2013-08-02 50 views
8

Dưới đây là một dịch vụ Jersey:Jersey. Làm thế nào để tạo ra json và đầu ra xml tùy thuộc vào url param

@GET 
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) 
public Response service(@QueryParam("format") String format) { 

    if (format.equals("json")) {...} 

    return response; 

} 

Tôi muốn tạo XML hoặc JSON phản ứng lại tùy thuộc vào url param "định dạng".

My phản ứng dụ đang hình thành bởi jaxb2

Tôi biết tôi có thể nhận được xml hoặc json phản ứng trở lại nếu trên Java client/thử nghiệm chức năng của tôi bằng cách sử dụng mã này:

String content = service.path("").queryParam("myparam", "myvalue").accept(MediaType.APPLICATION_XML).get(String.class); 

hoặc

String content = service.path("").queryParam("myparam", "myvalue").accept(MediaType.APPLICATION_JSON).get(String.class); 

Nhưng tôi cần làm điều đó tùy thuộc vào thông số url.

+0

Nếu bạn có thể gửi một 'ContentType' tham số thích hợp, 'application/json' thay vì' json', sau đó bạn có thể sử dụng 'MediaType.valueOf (định dạng)' để có được những' dụ MediaType' và sử dụng nó với phương thức chấp nhận. –

+2

Vấn đề của bạn là bạn không biết cách đặt kiểu nội dung của phản hồi, hay ...? – DannyMo

Trả lời

4

Bạn có thể thiết lập các loại phương tiện truyền thông của tổ chức phản ứng trực tiếp qua Response#ok (giả sử bạn muốn quay trở lại HTTP 200 status) phương pháp

@GET 
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) 
public Response service(@QueryParam("format") String format) { 
    return Response 
      // Set the status, entity and media type of the response. 
      .ok(entity, "json".equals(format) ? MediaType.APPLICATION_JSON : MediaType.APPLICATION_XML) 
      .build(); 
} 

hoặc bằng cách sử dụng phương pháp Response.ResponseBuilder#header

@GET 
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) 
public Response service(@QueryParam("format") String format) { 
    return Response 
      // Set the status and Put your entity here. 
      .ok(entity) 
      // Add the Content-Type header to tell Jersey which format it should marshall the entity into. 
      .header(HttpHeaders.CONTENT_TYPE, "json".equals(format) ? MediaType.APPLICATION_JSON : MediaType.APPLICATION_XML) 
      .build(); 
} 
0

Ok. Vì chúng ta đang nói về những thứ bên ngoài khuôn mẫu ở đây, hãy để tôi thử một số thứ:

Cách bạn sử dụng bộ lọc (tìm com.sun.jersey.spi.container.ResourceFilterFactory) trên dịch vụ của bạn và thay đổi (hoặc thêm hoặc ghi đè lên) tiêu đề chấp nhận dựa trên thông số truy vấn của bạn?

Không phải là cách tiếp cận trung thực nhất, tôi thừa nhận điều đó, nhưng tôi nghĩ rằng bạn nên cung cấp cho nó một thử

10

Đây không phải là cách thích hợp để làm những gì bạn wan t. Bạn không nên sử dụng tham số truy vấn để xác định định dạng đầu ra. Bạn đã khai báo rằng phương thức tài nguyên của bạn tạo cả XML và JSON, cách tuân thủ tiêu chuẩn là để cho khách hàng gửi một tiêu đề HTTP "Chấp nhận" thích hợp khai báo loại phương tiện nào họ có thể tiêu thụ. Nếu họ gửi "Accept: application/json", việc triển khai JAX-RS của bạn nên chọn định dạng phản hồi của phương thức là JSON, nếu khách hàng gửi "Accept: application/xml", nó sẽ tự động định dạng phản hồi của bạn dưới dạng XML. Nếu khách hàng cho biết họ có thể chấp nhận hoặc, việc triển khai JAX-RS của bạn là miễn phí để chọn một trong hai và bạn không nên quan tâm. Nếu khách hàng cho biết họ không thể chấp nhận, JAX-RS của bạn phải gửi lại mã lỗi HTTP thích hợp cho biết họ không có cách nào để gửi trả lời thích hợp.

+0

Tôi có thể bỏ lỡ smth/nhưng "đây không phải là cách thích hợp" không hoàn toàn chính xác. Điều gì sẽ xảy ra nếu anh ta muốn tạo một Dịch vụ OData? Nó thậm chí trong tiêu chuẩn mà nó phải có một tham số truy vấn $ định dạng để chọn định dạng đầu ra. –

+0

Tôi không biết gì về OData cho đến khi tôi thấy câu trả lời của bạn, chưa bao giờ sử dụng nó. Tôi dựa trên câu trả lời của tôi về những gì tôi biết về nguyên tắc REST vào thời điểm đó. Tôi sẽ nói rằng OData làm điều này nhưng vẫn không có vẻ đúng như REST được cho là dựa trên việc tận dụng các tiêu chuẩn HTTP, và xác định định dạng đầu ra từ tham số truy vấn không phải là bất kỳ loại chuẩn HTTP nào mà tôi biết. – user2456600

1

Đây là ví dụ hoàn chỉnh, câu trả lời ở trên là đúng. Tôi cũng sử dụng cách tiếp cận trên nhưng phải đối mặt với vấn đề khi làm việc với Danh sách. Tôi thiết lập các thực thể như thế này:

public Response getCoursesJSONOrXML(@QueryParam("type") String type){ 
    //Here we get list 
    List<Course> entity= courseService.getAllCourses(); 
    Response response = Response 
      .ok(entity, "xml".equals(type) ? MediaType.APPLICATION_XML : MediaType.APPLICATION_JSON) 
      .build(); 
    return response; 
} 

Sau đó tôi đang phải đối mặt với ngoại lệ này:

MessageBodyWriter not found for media type=application/json, type=class java.util.Arrays$ArrayList, genericType=class java.util.Arrays$ArrayList 

Sau khi đọc tài liệu jersey, tôi thấy các giải pháp mà chúng ta cần phải sử dụng GenericEntity cho khóa học của chúng tôi danh sách.Đây là ví dụ

@GET 
@Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML}) 
public Response getCoursesJSONOrXML(@QueryParam("type") String type){ 
    //Here we get list 
    List<Course> list = courseService.getAllCourses(); 
    GenericEntity<List<Course>> entity = new GenericEntity<List<Course>>(list) {}; 
    Response response = Response 
      .ok(entity, "xml".equals(type) ? MediaType.APPLICATION_XML : MediaType.APPLICATION_JSON) 
      .build(); 
    return response; 
}