【问题标题】:Jersey 2.x post call with json input paramater throws MessageBodyProviderNotFoundException带有 json 输入参数的 Jersey 2.x 后调用抛出 MessageBodyProviderNotFoundException
【发布时间】:2016-07-05 11:10:25
【问题描述】:

我尝试直接从 json 映射到 json。对于 GET 请求,这工作顺利。对于 POST 请求,会发生异常。

资源方法:

@GET
@Path("testget")
@Produces(MediaType.APPLICATION_JSON)
public Response test(@Context HttpServletRequest request) {
    Password password = new Password();
    password.setPassword("testpassword");
    return Response.status(Response.Status.OK).entity(password).build();
}

@POST
@Path("testpost")
@Consumes(MediaType.APPLICATION_JSON)
public Response test(Password password) {
    return Response.status(Response.Status.OK).entity(password.getPassword()).build();
}

客户:

    Response reponse = target.request(MediaType.APPLICATION_JSON).get();

    Password password = new Password();
    password.setPassword("newTestPasswort");
    reponse = target.request(MediaType.APPLICATION_JSON).post(Entity.json(password));

例外:

    SEVERE: MessageBodyWriter not found for media type=application/json,        type=class com.entities.Password, genericType=class      com.entities.Password.
Exception in thread "main" org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter not found for media type=application/json, type=class com.entities.Password, genericType=class com.entities.Password.
    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.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1130)
    at org.glassfish.jersey.client.ClientRequest.writeEntity(ClientRequest.java:502)
    at org.glassfish.jersey.client.internal.HttpUrlConnector._apply(HttpUrlConnector.java:388)
    at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:285)
    at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:255)
    at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:684)
    at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:681)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
    at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:681)
    at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:437)
    at org.glassfish.jersey.client.JerseyInvocation$Builder.post(JerseyInvocation.java:343)
    at com.clientsql.RegistrationTest.setNewPassword(RegistrationTest.java:61)
    at com.clientsql.RegistrationTest.main(RegistrationTest.java:44)

依赖:

<dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
        <version>2.23.1</version>
    </dependency>

对于映射,我尝试了各种依赖项。对于每个只有 get 函数有效:

 <dependency>
        <groupId>com.owlike</groupId>
        <artifactId>genson</artifactId>
        <version>1.4</version>
 </dependency>

<!--        <dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
    <version>2.23.1</version>
</dependency>-->
<!--        <dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-moxy</artifactId>
    <version>2.23.1</version>
</dependency>-->

【问题讨论】:

  • 你需要为客户端注册一个provider来做json的映射,有一个使用Gensonhere的例子。

标签: java json jersey jersey-2.0


【解决方案1】:

您需要告诉 jersey 如何将对象转换为 JSON。

有多种方法可以在球衣中支持 JSON。

查看 Jersey 官方文档,了解支持 JSON 的不同方法:https://jersey.java.net/documentation/latest/media.html#d0e7963

以下两种是常见的方法:

  1. 基于 JAXB 的 JSON 绑定支持

    为 POJO 添加 @XmlRootElement 注解。

    @XmlRootElement
    class EntityX {
        // data
    }
    
  2. 基于 POJO 的 JSON 绑定支持

    您需要注册一个实现 ContextResolver 的提供程序。使用 Jackson,您可以做到这一点。

    @Provider
    @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    public class JacksonContextResolver implements ContextResolver<ObjectMapper> {
    
        private ObjectMapper objectMapper;
    
        public JacksonContextResolver() throws Exception {
            this.objectMapper = buildMapper(false);
        }
    
        public static ObjectMapper buildMapper(boolean indent) {
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.ENGLISH));
            AnnotationIntrospector primary = new JacksonAnnotationIntrospector();
            AnnotationIntrospector secondary = new JaxbAnnotationIntrospector();
            AnnotationIntrospector pair = new AnnotationIntrospector.Pair(primary, secondary);
    
            SerializationConfig sc = objectMapper.getSerializationConfig()
                .withAnnotationIntrospector(pair)
                .withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
            objectMapper.setSerializationConfig(sc);
    
            if (indent) {
                objectMapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
            }
    
            return objectMapper;
        }
    
        /**
         * @see javax.ws.rs.ext.ContextResolver#getContext(java.lang.Class)
         */
        public ObjectMapper getContext(Class<?> objectType) {
            return objectMapper;
        }
    }
    

    查看此链接了解更多信息:https://jersey.java.net/documentation/latest/media.html#json.jackson

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-17
    • 1970-01-01
    • 2016-03-16
    • 2017-07-18
    • 2015-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多