【问题标题】:How to use POJO class for rest WS with CXF如何将 POJO 类用于带有 CXF 的 rest WS
【发布时间】:2015-11-05 14:44:51
【问题描述】:

我正在尝试在 rest WS(CXF 3.1.2) 中将 POJO 类引用返回给客户端,如下所示,

服务方法声明:

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes({"application/xml", MediaType.TEXT_PLAIN})
    @Path("/agentLogout")
    public ResponseEvent agentLogout(String ext) {
    ResponseEvent response= new ResponseEvent();
    response.setDn(ext);
    return response;
    }

客户代码:

    WebClient client = WebClient.create(REST_URI);    
    client.path("agentLogout").accept(MediaType.APPLICATION_JSON);
    Response agentLogoutResponse = client.post("3101");
    String responseStr=agentLogoutResponse.readEntity();

POJO:

    public class ResponseEvent {
    private String dn;
    public String getDn() {
    return dn;
    }
    public void setDn(String ext) {
    this.dn=ext;
    }
    }

问题:

  1. 如何在客户端代码中检索/访问返回的引用?

    String responseStr=agentLogoutResponse.readEntity(); // 我是否也需要在客户端代码中创建 pojo 类/接口..?

  2. 此 POJO 引用是否在 CXF 中呈现为 JSON?如果是这样,我们如何在客户端代码中使用它?

谢谢,

【问题讨论】:

    标签: java json web-services rest cxf


    【解决方案1】:

    1) 您可能希望在服务器端拥有MessageBodyWriter<ResponseEvent>。您可能需要register 这个@Provider。这将使您的 POJO 能够写入服务器的输出流。例如(未测试):

    @Provider
    class ResponseEventWriter implements MessageBodyWriter<ResponseEvent> {
        @Override
        public boolean isWriteable(Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType) {
            return true;
        }
        @Override
        public long getSize(ResponseEvent t, Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType) {
            return t.getDn().length();
        }
        @Override
        public void writeTo(ResponseEvent t, Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType,
            MultivaluedMap<String, Object> httpHeaders,
            OutputStream entityStream) throws IOException,
            WebApplicationException {
            entityStream.write(t.getDn().getBytes());
        }
    }
    

    2) 您需要在客户端拥有MessageBodyReader&lt;ResponseEvent&gt;。 例如:

    @Provider
    public class ResponseEventReader implements MessageBodyReader<ResponseEvent> {
        @Override
        public boolean isReadable(Class<?> type, Type genericType,
            Annotation[] annotations, MediaType mediaType) {
            return true;
        }
        @Override
        public ResponseEvent readFrom(Class<ResponseEvent> type, Type    genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
            throws IOException, WebApplicationException {
            StringBuilder sb = new StringBuilder();
            try(InputStreamReader isr = new InputStreamReader(entityStream)) {
                char[] c = new char[1];
                while (isr.read(c) != -1)
                   sb.append(c);
            } catch (IOException e) {
                //do something
            }
            ResponseEvent event = new ResponseEvent();
            event.setDn(sb.toString());
            return event;
        }
    }
    

    您需要在客户端注册此提供程序。例如,您可以使用JAXRS client,而不是 cxf 客户端(自 cxf 3 起可用)来执行此操作,例如:

        Client client = ClientBuilder.newClient();
        client = client.register(ResponseEventReader.class);
        Response agentLogoutResponse = client.target(/*whateveryourpath + */ "agentLogout")
                .request().accept(MediaType.APPLICATION_JSON)
                .buildPost(Entity.text("1301")).invoke();
    

    然后您可以将您的实体读取为

    ResponseEvent event = agentLogoutResponse.readEntity(ResponseEvent.class);
    

    【讨论】:

      【解决方案2】:

      假设您在客户端创建了接口(可以使用 WADL2Java 插件自动生成)。

      public interface MyService{
      
       @POST
          @Produces(MediaType.APPLICATION_JSON)
          @Consumes({"application/xml", MediaType.TEXT_PLAIN})
          @Path("/agentLogout")
          public ResponseEvent agentLogout(String ext);
      
      }
      

      创建单例类并创建服务实例

      public class CxfRestSingleton {
      
          public static GenService obj;
      
          public static GenService getInstance() {
      
              if (obj == null) {
                  obj = JAXRSClientFactory.create("http://localhost:8080/api/hello", MyService.class, Arrays.asList(new JacksonJaxbJsonProvider()));
              }
              return obj;
          }
      
      }
      

      **注意:**这里我使用的是 Jackson JAXB JSON 提供程序,它可以编组/解组 xml 和 JSON,您可以使用您选择的提供程序。 Jackson 提供程序不是 cxf 的一部分,因此您需要单独包含这些依赖项

      你可以访问你的 pojo 类,如下所示

      CxfRestSingleton.getInstance().agentLogout(12345).getDn();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多