Статьи

Создание простого JAX-RS MessageBodyWriter

JAX-RS действительно крут, и с помощью JAXB многие типы данных ответов могут быть преобразованы для вас, просто добавляя аннотации к объектам данных с аннотациями JAXB. Я довольно новичок в JAXB, но некоторые простые вставки аннотаций займут у вас долгий путь.

Возможно, есть некоторые типы данных, которые вы не можете или не хотите аннотировать для целей возврата этого типа данных из метода ресурсов JAX-RS. Одним простым примером является возврат либо логического (примитива), либо логического класса-оболочки. Я прочитал вопрос о StackOverflow, где кто-то спросил, могут ли они вернуть логическое значение из метода ресурса, и так как я не знал ответа, я решил попробовать! Моя версия возвращает только XML, а не JSON, но вы должны понять.

Я начал с примера HelloWorld из Руководства пользователя Джерси и начал с него изменять. Я использовал pom.xml, и единственное изменение состояло в том, чтобы раскомментировать блок, чтобы разрешить использование JSON.

Основной класс

Это основной класс из примера Hello World без каких-либо изменений.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package com.example;
 
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
 
import java.io.IOException;
import java.net.URI;
 
/**
 * Main class.
 *
 */
public class Main {
    // Base URI the Grizzly HTTP server will listen on
    public static final String BASE_URI = "http://localhost:8080/myapp/";
 
    /**
     * Starts Grizzly HTTP server exposing JAX-RS resources defined in this application.
     * @return Grizzly HTTP server.
     */
    public static HttpServer startServer() {
        // create a resource config that scans for JAX-RS resources and providers
        // in com.example package
        final ResourceConfig rc = new ResourceConfig().packages("com.example");
 
        // create and start a new instance of grizzly http server
        // exposing the Jersey application at BASE_URI
        return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
    }
 
    /**
     * Main method.
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        final HttpServer server = startServer();
        System.out.println(String.format("Jersey app started with WADL available at "
                + "%sapplication.wadl\nHit enter to stop it...", BASE_URI));
        System.in.read();
        server.stop();
    }
}

Ресурсный класс

Я создал класс ресурсов, который включал метод GET для возврата логического значения и другой метод GET для возврата логического класса оболочки. Обратите внимание, что методы getBool () и getBoolean () возвращают XML в качестве первой опции.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.example;
 
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
 
/**
 * Root resource (exposed at "myresource" path)
 */
@Path("myresource")
public class MyResource {
 
    /**
     * Method handling HTTP GET requests. The returned object will be sent
     * to the client as "text/plain" media type.
     *
     * @return String that will be returned as a text/plain response.
     */
    @GET
    @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN})
    public String getIt() {
        return "Got it!";
    }
 
    @GET
    @Path("/bool")
    @Produces({MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN})
    public boolean getBool() {
        return false;
    }
 
    @GET
    @Path("/Boolean")
    @Produces({MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN})
    public Boolean getBoolean() {
        return Boolean.TRUE;
    }
}

Класс BooleanMessageBodyWriter

Вот интересная часть, создание класса MessageBodyWriter, позволяющего методу ресурса возвращать XML для логического или логического значения.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package com.example;
  
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyWriter;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.WebApplicationException;
import java.io.IOException;
import java.io.InputStream;
import java.io.DataOutputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
  
@Provider
@Produces("application/xml")
public class BooleanMessageBodyWriter implements MessageBodyWriter<boolean> {
   
    @Override
    public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) {
        System.out.println("isWriteable called...");
        return type == Boolean.class;
    }
   
    @Override
    public long getSize(Boolean myBool, Class type, Type genericType,
                        Annotation[] annotations, MediaType mediaType) {
        // deprecated by JAX-RS 2.0 and ignored by Jersey runtime
        return 0;
    }
   
    @Override
    public void writeTo(Boolean myBool,
                        Class type,
                        Type genericType,
                        Annotation[] annotations,
                        MediaType mediaType,
                        MultivaluedMap<string object=""> httpHeaders,
                        OutputStream entityStream)
                        throws IOException, WebApplicationException {
   
        StringBuilder sb = new StringBuilder();
        sb.append("<boolean><boolean>").append(myBool.toString()).append("</boolean></boolean>");
        DataOutputStream dos = new DataOutputStream(entityStream);
        dos.writeUTF(sb.toString());
    }
}
</string></boolean>

Я не использовал Maven раньше, но следующие цели — это все, что вам нужно для компиляции и запуска проекта после установки maven (конечно!).

  • mvn compile — компилирует код
  • mvn exec: java — запускает Grizzly HttpServer и развертывает оставшийся сервис.

Надеюсь это поможет!

Ссылка: Создание простого JAX-RS MessageBodyWriter от нашего партнера по JCG Майка Миллера в блоге Scratching my itch .