@Consumes 不适用于 JSON

Posted

技术标签:

【中文标题】@Consumes 不适用于 JSON【英文标题】:@Consumes doesn't work with JSON 【发布时间】:2015-02-09 05:54:23 【问题描述】:

我有以下休息服务:

@Path("/add")
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response add(SomeEntity entity) 
    entity = someService.addEntity(entity);
    return Response.ok("Entity added with id=" + entity.getId()).build();

将我的应用程序部署到 Wildfly 后,我使用 json:"id":0,"param1":value1,"param2":value2 发送 HTTP 请求并收到以下错误消息:

Bad arguments passed to org.jboss.resteasy.spi.metadata.ResourceMethod@4ab32ab7 ( java.util.LinkedHashMap id=0, param1=value1, param2=value2 ) 带有 500 状态码。

我会做错什么?如何让我的应用使用 json 而不是 LinkedHashMap 的实体?

更新:实体类代码不包含任何有趣的内容,只有 long id 和两个带有一些 jpa 注释的 String 字段。

UPDATE2:完整的堆栈跟踪:

WARN [org.jboss.resteasy.core.ExceptionHandler](默认任务 2)执行 POST /rest/add 失败:org.jboss.resteasy.spi.InternalServerErrorException:传递给 org.jboss.resteasy.spi 的参数错误.metadata.ResourceMethod@4ab32ab7 (java.util.LinkedHashMap id=0, param1=value1, param2=value2) 在 org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:177) [resteasy-jaxrs-3.0.8.Final.jar:] 在 org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:296) [resteasy-jaxrs-3.0.8.Final.jar:] 在 org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:250) [resteasy-jaxrs-3.0.8.Final.jar:] 在 org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:237) [resteasy-jaxrs-3.0.8.Final.jar:] 在 org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:356) [resteasy-jaxrs-3.0.8.Final.jar:] 在 org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:179) [resteasy-jaxrs-3.0.8.Final.jar:] 在 org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:220) [resteasy-jaxrs-3.0.8.Final.jar:] 在 org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56) [resteasy-jaxrs-3.0.8.Final.jar:] 在 org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51) [resteasy-jaxrs-3.0.8.Final.jar:] 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [jboss-servlet-api_3.1_spec-1.0.0.Final.jar:1.0.0.Final] 在 io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final] 在 io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final] 在 io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final] 在 org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78) 在 io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.15.Final.jar:1.0.15.Final] 在 io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:113) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final] 在 io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:56) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final] 在 io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.15.Final.jar:1.0.15.Final] 在 io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45) [undertow-core-1.0.15.Final.jar:1.0.15.Final] 在 io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:61) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final] 在 io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58) [undertow-core-1.0.15.Final.jar:1.0.15.Final] 在 io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final] 在 io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76) [undertow-core-1.0.15.Final.jar:1.0.15.Final] 在 io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.15.Final.jar:1.0.15.Final] 在 org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61) 在 io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.15.Final.jar:1.0.15.Final] 在 io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:25) [undertow-core-1.0.15.Final.jar:1.0.15.Final] 在 io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:240) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final] 在 io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:227) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final] 在 io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:73) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final] 在 io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:146) [undertow-servlet-1.0.15.Final.jar:1.0.15.Final] 在 io.undertow.server.Connectors.executeRootHandler(Connectors.java:177) [undertow-core-1.0.15.Final.jar:1.0.15.Final] 在 io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:727) [undertow-core-1.0.15.Final.jar:1.0.15.Final] 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_45] 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_45] 在 java.lang.Thread.run(Thread.java:744) [rt.jar:1.7.0_45] 引起:java.lang.IllegalArgumentException:参数类型不匹配 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_45] 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_45] 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_45] 在 java.lang.reflect.Method.invoke(Method.java:606) [rt.jar:1.7.0_45] 在 org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:137) [resteasy-jaxrs-3.0.8.Final.jar:] ... 35 更多

UPDATE3:我没有找到任何解决方案,所以我用@FormParams 代替了json 替换了方法参数和@Consumes。但无论如何都需要解决方案。

【问题讨论】:

您需要确保您的 SomeEntity 确实是 JSON 可序列化的(例如,通过 JAXB impl) 能否具体说明您的意见?我需要向我的实体 bean 添加一些注释吗? 我知道你使用 resteasy,但jersey.java.net/documentation/1.18/json.html 的想法也适用,你需要从请求体中获取 json 并将其序列化到你的实体对象,大多数 JAX-RS impl 使用 JAXB魔术这样做 发布您的 SomeEntity 类并列出您在此处用于 JSON 转换的 jar。 @Jimmy 实体类代码没有任何有趣的内容,只有long id 和两个String 字段以及一些jpa 注释、getter 和setter,仅此而已。另外,我不使用库进行 JSON 转换,实际上我认为我的 Wildfly 应用程序服务器会自动完成。 【参考方案1】:

我在使用 IDEA IDE 的 REST 客户端时遇到了完全相同的错误,我错过了将正确的 Content-Type: application/json 放入请求中,然后 RESTeasy 可以将 java.util.LinkedHashMap 转换为我在 POST 方法中的对象。

希望这会有所帮助,或者它可以为您的调查提供一些提示。

【讨论】:

感谢您的回复!我也使用了 IDEA REST 插件,但我在请求参数中设置了Accept:application/json,所以我认为这不是问题。希望我正确理解了您的回复。 Accept 参数用于响应,但如果您发送 POST,我认为您还应该使用 Content-Type 来帮助识别正文。无论如何,希望它能给你一些提示。 谢谢,现在很清楚了。我认为AcceptContent-Type 相同。如果这些是不同的东西,那可以解释问题。【参考方案2】:

您发送的 JSON 无效。您不能使用=(改用:)并且必须引用字符串值。

尝试使用JSONLint 等工具来验证您的请求正文。

【讨论】:

抱歉,解决了我的问题。我使用:,而不是=,也使用引号。 您仍然需要引用您的字符串值,例如"param1": "value1"(在您的示例中,您使用的是"param1": value1)。

以上是关于@Consumes 不适用于 JSON的主要内容,如果未能解决你的问题,请参考以下文章

springmvc中@RequestMapping的参数consumes无效

json串技术

Tensorflow - 多 GPU 不适用于模型(输入),也不适用于计算梯度

为啥 UITableViewAutomaticDimension 不适用于 sectionFooterHeight?

为啥排序不适用于矢量?

验证不适用于 saveMany