Как мне сообщить Джерси, где находится мой MessageBodyWriter?

1

Я работаю с Джерси (jaxrs-ri-2.7), Tomcat 7.0.47 и Java 1.7.0_51. Из-за брандмауэров я не могу использовать Maven. Моя цель - сделать веб-сервис JSON RESTful. Я не могу заставить МОКСИ работать, хотя мне говорят, что он включен в версию Джерси. В какой-то момент я могу заставить Джерси вернуть XML. Когда я вызываю свой веб-сервис через браузер, это то, что я получаю:

org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: 

MessageBodyWriter not found for media type=application/json, type=class com.pracht.test.Calculation, genericType=class com.pracht.test.Calculation.

    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:247)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
    at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:103)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
    at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:88)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
    at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1154)
    at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:571)
    at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:378)
    ...

Это мой класс провайдера:

package com.pracht.test;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
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 com.owlike.genson.Genson;
import com.owlike.genson.TransformationException;

@Provider
@Produces("application/json")
public class JsonProvider implements MessageBodyWriter<Calculation> {

    public JsonProvider() throws IOException{
        try {
            PrintWriter pw=new PrintWriter(
                       new BufferedOutputStream(new  FileOutputStream("c:\\test.txt")));
            pw.println("Reached JsonProvider()");
            pw.close();
        } catch(IOException e){
            e.printStackTrace();
        }
    }

    @Override
    public long getSize(Calculation arg0, Class<?> arg1, Type arg2,
            Annotation[] arg3, MediaType arg4) {
        return 0;
    }

    @Override
    public void writeTo(Calculation calculation, 
            Class<?> type, 
            Type genericType,
            Annotation[] annotations, 
            MediaType mediaType,
            MultivaluedMap<String, Object> httpHeaders, 
            OutputStream entityStream)
            throws IOException, WebApplicationException {
        Genson genson = new Genson();
        try {
            String json=genson.serialize(calculation);
            entityStream.write(json.getBytes());
        } catch (TransformationException e) {
            e.printStackTrace();
            throw new WebApplicationException("Serialization error",e);
        }
    }

    @Override
    public boolean isWriteable(Class<?> classType, Type arg1, Annotation[] arg2,
            MediaType arg3) {
        return classType == Calculation.class;
    }


}

Я добавил PrintWriter в конструкторе, надеюсь, скажу, что, по крайней мере, объект был сконструирован и поместить результаты, где я могу его увидеть. Я просто хотел что-то быстро и не хотел, чтобы выяснить, какой API-интерфейс регистрации используется.

Это мой веб-ресурс:

package com.pracht.test;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/calc")
public class CalcRest {


public CalcRest(){
    System.out.println("Reached CalcRest()");

}

@GET
@Path("/add/{a}/{b}")
@Produces("application/json")
public Calculation addPlainText(@PathParam("a") double a,
        @PathParam("b") double b) {
    System.out.println("Reached addPlainText()");
    return new Calculation().withProblem(a+"+"+b).withAnswer(a+b);
}

}

Это вызов, который я использую с помощью Firefox:

http://localhost:8080/Contacts/rest/calc/add/1/2

В качестве побочного примечания разработчикам Java понравилось бы, если бы была только одна библиотека, которая фактически обрабатывала веб-службы JSON, используя аннотации, из коробки. Тот, который просто сработал?

  • 0
    Там нет необходимости писать пользовательские MessageBodyWriter. Вам нужно просто установить для свойства com.sun.jersey.api.json.POJOMappingFeature значение true в поставщике.
Теги:
rest
jersey

1 ответ

1

Почему вы пишете MessageBodyWriter для Genson? У Genson есть свои собственные, которые должны быть выбраны автоматически, когда у вас есть Genson в вашем классе.

Если это не так, я думаю, что Джерси найдет другого поставщика для JSON (возможно, мокси) и, таким образом, не выбрал Генсона. Если это так, вы можете попытаться создать папку META-INF/services в вашем пути к классам и определить там Genson в качестве вашего провайдера (это должно переопределить других поставщиков). Вы можете посмотреть на то, как это делается в Genson здесь.

Также вы должны взять последнюю версию Genson, 0.99, у нее есть несколько улучшений, таких как реализация JSR 353, которая пытается обеспечить "стандарт" для JSON Parsing (а не привязки данных) на Java.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню