【问题标题】:Null content-type when migrating from Jersey to RESTEasy.从 Jersey 迁移到 RESTEasy 时为 Null 内容类型。
【发布时间】:2011-03-06 14:48:38
【问题描述】:

所以我编写了一个示例 REST 资源,它在 Jersey/Tomcat 中就像一个魅力,但是当我把它带到 RestEASY/Tomcat 时它会爆炸。我是说真的吗?开箱即用发生了什么。总之有点沮丧。尝试访问资源时出现此错误(http://localhost:7070/mg/mytest)

“content-type 为 null 并希望提取正文”

7842 [http-7070-2] 错误 com.loyalty.mg.rest.exception.MGExceptionMapper - 在异常映射器中捕获错误 - org.jboss.resteasy.spi.BadRequestException:内容类型为 null 并期望提取正文 在 org.jboss.resteasy.core.MessageBodyParameterInjector.inject(MessageBodyParameterInjector.java:131) 在 org.jboss.resteasy.core.MethodInjectorImpl.injectArguments(MethodInjectorImpl.java:98) 在 org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:121) 在 org.jboss.resteasy.core.ResourceMethod.invokeOnTarget(ResourceMethod.java:247) 在 org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:212) 在 org.jboss.resteasy.core.ResourceMethod.invoke(ResourceMethod.java:202)

@Path("/mytest")
public class TestResource  {

    @GET
    public Response getData()

我想问题也是 - RestEASY 是否比泽西更好,这只是开始,我遇到了错误。我应该坚持泽西岛吗?

也已经试过了:)

<context-param>
  <param-name>resteasy.media.type.mappings</param-name>
  <param-value>json : application/json, xml : application/xml</param-value> 
</context-param>

【问题讨论】:

  • 我认为 Jersey 和 RestEASY 都可以很好地工作......所以我想人们也可以问“为什么首先要切换”。

标签: java tomcat rest resteasy


【解决方案1】:

嗯,我知道这个请求已经过时了,互联网上的很多东西都是旧的......在两年的时间里,一切通常都会改变并且效果更好。因此,与其他非专有 RESTLET 框架相比,RestEasy 不应该得到一个坏名声。

实际上,我认为 JBoss RestEasy 占用空间最轻,它不会因不必要的 *.jars 而臃肿,灵活、完全认证的 JAX-RS 实现、完整且易用性无与伦比。

有些人认为,GET 请求不应该期望请求中有 Content_Type,(我同意),但是对于每个 GET 请求,都必须表明您打算将什么发送回请求者?正确的! (它将是 JSON、XML、纯文本、XML 和工作表、多部分等)。好吧,RestEasy,JBoss 的框架通过如下所示的注释解决了这个问题,并且可以根据 URL REST 请求进行配置。 因此,这就是你的答案

 @GET 
 @Path("/echo/{message}")  
 @Produces("text/plain")  
 public String echo(@PathParam("message")String message){  
     return message;      
 }  

 @GET 
 @Path("/employees")  
 @Produces("application/xml")  
 @Stylesheet(type="text/css", href="${basepath}foo.xsl")
 public List<Employee> listEmployees(){  
    return new ArrayList<Employee>(employees.values());  
 }  

 @GET 
 @Path("/employee/{employeeid}")  
 @Produces("application/xml")  
 public Employee getEmployee(@PathParam("employeeid")String employeeId){  
     return employees.get(employeeId);          
 }  

 @GET 
 @Path("/json/employees/")  
 **@Produces("application/json")**  
 public List<Employee> listEmployeesJSON(){  
     return new ArrayList<Employee>(employees.values());  
}   

【讨论】:

    【解决方案2】:

    GET 请求不得有正文,应用程序不得扩展 Content-Type 标头。

    如果这是 RestEASY 的一个错误,那就让人想知道有多少人真正在使用该软件。

    编辑

    RFC2616 $4.3

    消息正文不得包含在 一个请求,如果该规范 请求方法(第 5.1.1 节)确实 不允许发送实体主体 请求。

    服务器应该读取并转发 任何请求的消息正文;如果 请求方法不包括 为实体主体定义语义, 那么消息体应该是 处理请求时忽略。

    GET 方法没有“不允许在请求中发送实体主体”,因此 GET 请求可能有主体。但是 GET “不包括实体主体的定义语义” 因此无论如何都应该忽略主体。

    无论如何,RestEASY 不应该要求在 GET 请求中存在 Content-Type。

    【讨论】:

    • 其实不是禁止的,只是不寻常。
    • @binary_runner 你是对的。 HTTP RFC 总是让我感到惊讶
    【解决方案3】:

    一个典型的原因是,如果你有这样的代码:

    @GET
    @Path("/foo/{bar}")
    @Produces(MediaType.TEXT_HTML)
    public Response foo(@PathParam("bar") String bar) {
    

    ...您忘记使用@PathParam 注释 bar 参数。然后 RestEasy 认为它应该从请求的正文中读取 bar,而不是从 URL 路径中读取,并将丢弃此异常。

    这似乎不是你的情况,但我遇到了同样的例外,这就是原因。

    【讨论】:

    • +1 表示 @PathParam 提示 - 刚刚让我发现,这有助于为我解决问题。
    【解决方案4】:

    RestEASY vs Jersey 很难说: http://www.infoq.com/news/2008/10/jaxrs-comparison

    关于你的错误,你可以通过注解来控制内容类型,如果你放置@Produces annotation会发生什么,例如:

    @Produces("application/json")
    @GET
    public Response getData() {
      ...
    }
    

    【讨论】:

      【解决方案5】:

      引发该异常的代码如下所示:

           final MediaType mediaType = request.getHttpHeaders().getMediaType();
           if (mediaType == null) {
              throw new BadRequestException(
                   "content-type was null and expecting to extract a body");
           }
      

      问题似乎是 RestEASY 无法从它收到的请求的标头中找出内容类型。这表明请求中的内容类型是虚假的,或者您配置 RestEASY 的方式存在问题。

      我想问题也是 - RestEASY 是否比泽西更好,这只是开始,我遇到了错误。我应该坚持泽西岛吗?

      我无法回答。但是,我认为您太快将可能是您的代码错误的事情归咎于 RestEASY。

      【讨论】:

      • 我通过在 REST 请求标头中显式传递“Content-Type”来解决此问题。所以我猜这个标题对于 RestEASY 来说是“强制性的”??这就是我的观点——这对 Jersey/JAXRS 来说不是强制性的,这就是我对 RestEASY 感到沮丧的原因。
      • @Kapil - 我会说在不设置显式内容类型的情况下尝试使用 RESTful API 是非常愚蠢的。如果有的话,我会说是 Jersey/JAXRS 让你侥幸逃脱。
      • @Kapil - 实际上,@irreputable 有一个很好的观点。问题可能是您的客户端正在发送“POST”请求,而它应该发送“GET”?
      • 如果没有注释为 @POST 的方法,则 POST 将返回状态 405,方法不允许。 (我已经在 RESTEasy 中尝试过。)
      猜你喜欢
      • 2017-02-04
      • 2021-09-08
      • 2013-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-10
      • 1970-01-01
      • 2013-03-19
      相关资源
      最近更新 更多