2014-11-27 2 views
0

실체으로 POJO를 통과 잭슨을 사용하는 클라이언트 :저지/JAX-RS I가 <a href="https://jersey.java.net/" rel="nofollow">Jersey</a>/JAX-RS를 사용하여 RESTful 웹 서비스 클라이언트 구현하기 위해 노력하고

public class MyClient implements Closeable { 
    private Client client; 
    private FizzResource fizzResource; 
    // Several other resources omitted for brevity. 

    // Ctor, getters and setters, etc. 

    @Override 
    public void close() throws Exception { 
     client.destroy(); 
     client.getExecutorService().shutdown(); 
    } 
} 

public class FizzResource { 
    private Client client; 

    public Fizz saveFizz(Fizz fizz) { 
     WebResource webResource = client.resource("whatever"); 
     ClientResponse response = webResource.accept(???).post(???); 
     if(response.getStatus() != 200) { 
      // do something... 
     } else { 
      // do something else... 
     } 
    } 
} 

내 문제는 내가 싶지 않아입니다 JSON으로 작업하십시오. 대신 엔티티 (예 : Fizz)와 직접 작업하고 싶습니다. 난 Jackson 자동으로 JSON과 내 엔티티 (각 메서드 내에서 명시 적으로 변환 작업을 수행하지 않고도) 사이의 직렬화 작업을 수행하고 싶지만, 이것이 가능/실행 가능하다는 것을 알지 못한다.

public Fizz saveFizz(Fizz fizz) { 
    WebResource webResource = client.resource("whatever"); 

    ClientResponse response = webResource.accept("application/json").post(fizz); 
    if(response.getStatus() != 200) { 
     throw new RuntimeException("Errors are bad, mkay?"); 
    } 

    Fizz fizz = response.extractSomehow(); 

    return fizz; 
} 

Fizz 클래스가 이미 올바른 잭슨 주석 (JsonProperty 등)로 주석이 다음과 같다고 가정처럼 이상적으로 내 saveFizz 방법을 볼 수 있습니다.

아이디어가 있으십니까?

final ObjectMapper mapper = new ObjectMapper(); 
mapper.readValue(response.getEntity(String.class), Fizz.class); 

만큼 소다가 제대로 주석이,이 당신이 찾고있는 무엇을 수행해야합니다

답변

2

을, 그래서 the user guide for JSON/POJO support

우선 살펴있다 : 우리는 당신이 jersey-json 모듈이 있는지 확인해야합니다

<dependency> 
    <groupId>com.sun.jersey</groupId> 
    <artifactId>jersey-json</artifactId> 
    <version>${jersey-version}</version> 
</dependency> 

이 모듈이 필요한 것이다 MessageBodyReaderMessageBodyWriter 읽고 JSON

과에서 당신에게 POJO를 쓰기 것

두 번째 사항 : POJO 매핑 지원 기능을 사용하도록 설정해야합니다. 서버/응용 프로그램 및 클라이언트의 web.xml

<init-param> 
    <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name> 
    <param-value>true</param-value> 
</init-param> 

서버 프로그램

public class MyApplication extends PackagesResourceConfig { 
    public MyApplication() { 
     getFeatures()..put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE); 
    } 
} 

참조 다른 Deployment Options

클라이언트 구성

ClientConfig clientConfig = new DefaultClientConfig(); 
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, 
           Boolean.TRUE); 
Client client = Client.create(clientConfig); 

서버와 두3210

세 번째 사항 : 우리는 리소스 메소드에 주석이 제대로되어 있는지 확인하고 클라이언트가 올바르게 호출되도록해야합니다 (올바른 작성자/판독기가 발견되도록).

JSON을 허용하는 메소드의 경우 @Consumed("application/json") 주석을 달고 JSON에서 응답을 생성하는 경우 @Produces("application/json")으로 주석을 추가해야합니다. 따라서 메소드의 의미에 따라 달라지며 주석에는 주석이 포함되거나 둘 중 하나 일 수 있습니다.

클라이언트의 경우 구성을 수정하고 Java 객체를 추출해야하는 한 Java 유형의 getXxx을 호출해야합니다. 여기

public void testGetFizz() { 
    // Directly extact 
    Fizz fizz = r.path("fizz").accept("application/json").get(Fizz.class); 
    System.out.println(fizz); 

    // Extract from ClientResponse 
    ClientResponse response = r.path("fizz"). 
        accept("application/json").get(ClientResponse.class); 
    Fizz fizz1 = response.getEntity(Fizz.class); 
    System.out.println(fizz1); 
} 

내 테스트

@Path("/fizz") 
public class FizzResource { 

    @POST 
    @Consumes("application/json") 
    public Response postFizz(Fizz fizz) { 
     System.out.println("==== Created Fizz ==="); 
     System.out.println(fizz); 
     System.out.println("====================="); 
     return Response.created(null).build(); 
    } 

    @GET 
    @Produces("application/json") 
    public Response getFizz() { 
     Fizz fizz = new Fizz(1, "fizz"); 
     return Response.ok(fizz).build(); 
    } 
} 

서버 설정

ResourceConfig resourceConfig = new PackagesResourceConfig("test.json.pojo"); 
resourceConfig.getFeatures().put(
         JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE); 

클라이언트 설정

ClientConfig clientConfig = new DefaultClientConfig(); 
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, 
           Boolean.TRUE); 
Client client = Client.create(clientConfig); 
r = client.resource(Main.BASE_URI); 
// r = WebResource 
1

당신은 잭슨의 ObjectMapper를 사용할 수 있습니다.

일반적으로 사용자 지정 공급자를 구현하는 것과 관련된 다른 옵션도 있습니다. 당신이 포함 된 경우

+0

감사 @Calardan에 사용되는 코드의 다른 부분 (+1은) - 그러나 th at은 JSON 문자열을 'Fizz' 인스턴스로 역 직렬화하는 독립 실행 형 스 니펫입니다. 위의 실제 saveFizz 메소드 내에서 어떻게 작동합니까? 'webResource' 메쏘드에 무엇을 전달해야합니까? '응답 '에서'피즈'를 어떻게 추출 할 수 있을까요? 다시 한 번 감사드립니다! 당신이 대신의 InputStream에서 작업 할 경우 – IAmYourFaja

+0

당신은'response.getEntity (String.class) 를 호출하여 응답의 String 표현을 얻을 수' , 당신은 단지 게시 'response.getEntityInputStream()' 을 사용할 수 있습니다 Fizz의 인스턴스를 사용하면 다음과 같이 쓸 수 있습니다 : 'ObjectMapper mapper = new ObjectMapper(); JSON 문자열을 마샬링 및 언 마샬링하는 데 매우 기본적인 솔루션입니다. – Calardan

+0

@peeskillet이 보여 주듯이, Jersey의 클라이언트 API를 구성하거나 사용자 정의 공급자를 도입하는 고급 솔루션이있을 것입니다. 가장 적합한 것을 골라라. – Calardan

0

아무것도 설정하지 않고

<dependency> 
     <groupId>org.glassfish.jersey.media</groupId> 
     <artifactId>jersey-media-moxy</artifactId> 
     <version>${jersey.version}</version> 
    </dependency> 

은 다음 자동적으로 변환을해야합니다 (당신이 받는다는 사용 랬). 당신은 같은 기능을 쓸 수 있습니다 : 당신은 저지 1.x에서를 사용하는

@POST 
@Consumes(APPLICATION_JSON) 
@Produces(APPLICATION_JSON) 
public Activity createActivity(@Valid Activity activity) { 

    return activityDAO.createActivity(vuser,activity); 
} 
관련 문제