2014-04-23 3 views
1

Jersey (jaxrs-ri-2.7), Tomcat 7.0.47 및 Java 1.7.0_51에서 작업하고 있습니다. 방화벽 때문에 Maven을 사용할 수 없습니다. 내 목표는 JSON RESTful 웹 서비스를 만드는 것이다. Jersey 버전에 포함되어 있다고 들었지만 MOXy를 사용할 수는 없습니다. 어느 시점에서 Jersey가 XML을 반환하도록 할 수있었습니다. 내 MessageBodyWriter가있는 곳을 Jersey에게 어떻게 알릴 수 있습니까?

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를 추가 :

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) 
    ... 

이 내 바이더 클래스입니다 : 나는 브라우저를 통해 내 웹 서비스를 호출 할 때, 이것은 내가 무엇을 얻을 적어도 객체가 생성되고 결과를 볼 수있는 위치에 놓습니다. 방금 뭔가 빠른 것을 원했고 사용중인 로깅 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); 
} 

} 

이 나는 ​​파이어 폭스를 사용하여 만든다 호출입니다 :

내 웹 자원 보조 노트로

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

, 것 자바 개발자 맘이 있다면 그냥 실제로 JSON 웹 서비스를 어노테이션을 사용하여 처리 한 라이브러리. 방금 작동 한 하나?

+0

맞춤 MessageBodyWriter를 작성할 필요가 없습니다. 당신이해야 할 일은 프로 바이더에서'com.sun.jersey.api.json.POJOMappingFeature' 속성을'true'로 설정하는 것입니다. – Opal

답변

1

왜 Genson 용 MessageBodyWriter를 작성 했습니까? Genson에는 클래스 패스에 Genson이있을 때 자동으로 선택되어야하는 자체가 있습니다.

저지가 JSON (아마도 Moxy)에 대한 다른 공급자를 찾고 Genson을 선택하지 않는다고 생각하는 경우입니다. 이 경우 classpath에 META-INF/services 폴더를 만들고 해당 Genson을 공급자로 정의 할 수 있습니다 (다른 공급자를 무시해야 함). Genson here에서 어떻게 진행되는지 살펴볼 수 있습니다.

또한 당신이 Genson, 0.99의 최신 버전을해야, 그것은 자바에서 JSON 구문 분석 (하지 바인딩)에 대한 "표준"을 제공하려고 JSR 353의 구현으로 improvments의 몇 가지가 있습니다.

관련 문제