Я работаю с Джерси (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, используя аннотации, из коробки. Тот, который просто сработал?
Почему вы пишете MessageBodyWriter для Genson? У Genson есть свои собственные, которые должны быть выбраны автоматически, когда у вас есть Genson в вашем классе.
Если это не так, я думаю, что Джерси найдет другого поставщика для JSON (возможно, мокси) и, таким образом, не выбрал Генсона. Если это так, вы можете попытаться создать папку META-INF/services в вашем пути к классам и определить там Genson в качестве вашего провайдера (это должно переопределить других поставщиков). Вы можете посмотреть на то, как это делается в Genson здесь.
Также вы должны взять последнюю версию Genson, 0.99, у нее есть несколько улучшений, таких как реализация JSR 353, которая пытается обеспечить "стандарт" для JSON Parsing (а не привязки данных) на Java.
com.sun.jersey.api.json.POJOMappingFeature
значениеtrue
в поставщике.