【问题标题】:"Could not find acceptable representation" using spring-boot-starter-web使用 spring-boot-starter-web “找不到可接受的表示”
【发布时间】:2015-04-12 12:34:24
【问题描述】:

我正在尝试使用 spring-boot-starter-web 创建一个提供 Java 对象的 JSON 表示形式的休息服务。据我了解,这个 boot-starter-web jar 应该通过 Jackson 自动处理到 JSON 的转换,但我却收到了这个错误。

{ 
  "timestamp": 1423693929568,
  "status": 406,
  "error": "Not Acceptable",
  "exception": "org.springframework.web.HttpMediaTypeNotAcceptableException",
  "message": "Could not find acceptable representation"
}

我的控制器是这个...

@RestController
@RequestMapping(value = "/media")
public class MediaController {
    @RequestMapping(value = "/test", method = RequestMethod.POST)
    public @ResponseBody UploadResult test(@RequestParam(value="data") final String data) {
      String value = "hello, test with data [" + data + "]"; 
      return new UploadResult(value);
    }

    @RequestMapping(value = "/test2", method = RequestMethod.POST)
    public int test2() {
        return 42;
    }

    @RequestMapping(value = "/test3", method = RequestMethod.POST)
    public String test3(@RequestParam(value="data") final String data) {
        String value = "hello, test with data [" + data + "]"; 
        UploadResult upload = new UploadResult(value);
        return upload.value;
    }


    public static class UploadResult {
        private String value;
        public UploadResult(final String value)
        {
            this.value = value;
        }
    }
}

我的pom.xml 有...

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>1.2.1.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <version>1.2.1.RELEASE</version>
    <scope>provided</scope>
</dependency>

mvn dependency:tree 表明 spring-boot-starter-web 确实依赖于 jackson2.4 数据绑定,因此应该在类路径中......

[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:1.2.1.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter:jar:1.2.1.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot:jar:1.2.1.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-autoconfigure:jar:1.2.1.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-logging:jar:1.2.1.RELEASE:compile
[INFO] |  |  |  +- org.slf4j:jul-to-slf4j:jar:1.7.8:compile
[INFO] |  |  |  \- org.slf4j:log4j-over-slf4j:jar:1.7.8:compile
[INFO] |  |  \- org.yaml:snakeyaml:jar:1.14:runtime
[INFO] |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.4.4:compile
[INFO] |  |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.4.0:compile
[INFO] |  |  \- com.fasterxml.jackson.core:jackson-core:jar:2.4.4:compile
[INFO] |  +- org.hibernate:hibernate-validator:jar:5.1.3.Final:compile
[INFO] |  |  +- javax.validation:validation-api:jar:1.1.0.Final:compile
[INFO] |  |  +- org.jboss.logging:jboss-logging:jar:3.1.3.GA:compile
[INFO] |  |  \- com.fasterxml:classmate:jar:1.0.0:compile
[INFO] |  +- org.springframework:spring-web:jar:4.1.4.RELEASE:compile
[INFO] |  |  +- org.springframework:spring-aop:jar:4.1.4.RELEASE:compile
[INFO] |  |  |  \- aopalliance:aopalliance:jar:1.0:compile
[INFO] |  |  +- org.springframework:spring-beans:jar:4.1.4.RELEASE:compile
[INFO] |  |  \- org.springframework:spring-context:jar:4.1.4.RELEASE:compile
[INFO] |  \- org.springframework:spring-webmvc:jar:4.1.4.RELEASE:compile
[INFO] |     \- org.springframework:spring-expression:jar:4.1.4.RELEASE:compile

...但调用test 服务会出现上述错误。 test2test3 工作正常,证明它一定只是尝试转换为 JSON 失败了吗?我是否缺少一些配置问题或注释?从我能找到的所有示例中,不再需要为基本的 Jackson JSON 转换注释类。

非常感谢任何帮助。

【问题讨论】:

  • 顺便说一句,最新的春天(不确定何时添加)做得更好。去年的某个时候,我不小心再次犯了这个错误,而不是上面的神秘错误,我得到了一个错误,它几乎准确地告诉了我我做错了什么(不记得文字但是......)。非常感谢团队改进这一点。

标签: java json spring maven spring-mvc


【解决方案1】:

您的 UpdateResult 没有公共 getter,例如:

public static class UploadResult {
    private String value;
    public UploadResult(final String value)
    {
        this.value = value;
    }

    public String getValue() {
       return this.value;
    }
}

我相信默认情况下自动发现是打开的,并且会尝试发现你的吸气剂。您可以使用@JsonAutoDetect(getterVisibility=Visibility.NONE) 禁用它,在您的示例中将导致[]

【讨论】:

  • 弹簧对 HttpMediaTypeNotAcceptableException 错误消息非常“有帮助”...
  • 我遇到了同样的问题,有一个空类(到目前为止)没有字段或吸气剂。我同意错误消息非常“有用”,非常感谢。
  • 我试图返回 List&lt;MyClass&gt; 但说 produces = MediaType.APPLICATION_XML_VALUE 所以 Spring 不知道如何将列表表示为 XML.. :D 显然......
  • Wonderfule,我在使用 lombok,添加了所有 arg 并且没有 arg 注释,并且完全忘记了 getter setter。谢谢!
  • 没错。我忘记了吸气剂和二传手。事实上,请求是传入的,所有字段都为空
【解决方案2】:

我在使用spring/jhipster RESTful 服务时遇到了类似的错误(通过Postman

端点类似于:

@RequestMapping(value = "/index-entries/{id}",
        method = RequestMethod.GET,
        produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
public ResponseEntity<IndexEntry> getIndexEntry(@PathVariable Long id) {

我试图通过带有标题Accept: text/plainPostman 调用restful 端点,但我需要使用Accept: application/json

【讨论】:

  • 是的,我认为“找不到可接受的表示”会以多种方式显示其丑陋的一面。 :(
  • 我有一个 JSON API,但在一条路线上我返回了produces = MediaType.TEXT_HTML_VALUE(原始 HTML ..)。但是当抛出异常时(我想要一个 JSON 错误模型),Spring 可能不知道如何将其转换为字符串......:/当我删除 produces 部分时它起作用了......:D
【解决方案3】:

我也遇到了类似的问题。在我的情况下,请求路径接受邮件 ID 作为路径变量,所以 uri 看起来像 /some/api/test@test.com

基于路径,Spring 确定 uri 是获取一些带有“.com”扩展名的文件,并尝试使用不同的媒体类型进行响应,然后是预期的。将路径变量转换为请求参数后,它对我有用。

【讨论】:

    【解决方案4】:

    如果使用@FeignClient,添加例如

    produces = "application/json"
    

    @RequestMapping 注解

    【讨论】:

      【解决方案5】:

      将以下依赖项添加到您的pom.xml

      <dependency>
          <groupId>com.fasterxml.jackson.dataformat</groupId>
          <artifactId>jackson-dataformat-xml</artifactId>
          <version>2.10.2</version>
      </dependency>
      

      【讨论】:

      • 我在上面显示了正确的杰克逊依赖(不是这个)已经存在。所以这不是解决问题的办法。 @ikumen 已经给出了解决方案
      • 当这个依赖缺失时我们会得到同样的错误。所以请不要对这个答案投反对票,因为这在某些情况下是正确的。
      • 好吧,我现在不能取消投票,因为它不允许我这样做。但它仍然不是我原来问题的答案。我希望它确实对其他人有所帮助。
      • 这不是针对上述问题,但如果你使用produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE } 并要求application/xml 是正确的解决方案
      【解决方案6】:

      我在访问执行器时遇到了这个问题。放置以下配置类解决了这个问题:

      @Configuration
      @EnableWebMvc
      public class MediaConverterConfiguration implements WebMvcConfigurer {
          @Bean
          public MappingJackson2HttpMessageConverter jacksonConverter() {
              MappingJackson2HttpMessageConverter mc =
                      new MappingJackson2HttpMessageConverter();
              List<MediaType> supportedMediaTypes =
                      new ArrayList<>(mc.getSupportedMediaTypes());
              supportedMediaTypes
                      .add(MediaType.valueOf(MediaType.APPLICATION_JSON_VALUE));
              supportedMediaTypes.add(
                  MediaType.valueOf("application/vnd.spring-boot.actuator.v2+json"));
              mc.setSupportedMediaTypes(supportedMediaTypes);
              return mc;
          }
      
          @Override
          public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
              converters.add(jacksonConverter());
          }
      }
      

      【讨论】:

      • 在没有启动的旧 Spring 应用程序上,我很难让我的 REST 服务返回 json 而不会出现此错误。这对我有用,非常有帮助!
      【解决方案7】:

      如果您使用的是 Lombok,请确保它具有像 @Data 或 @Getter 这样的注释 @Setter 在您的响应模型类中。

      【讨论】:

      • 这让我大开眼界。我使用过 Lombok,但忘记为 Eclipse 设置它。这就是为什么即使我使用了 @Data 注释,getter 和 setter 也没有为 bean 填充。谢谢
      【解决方案8】:

      我的返回对象在类上没有 @XmlRootElement 注释。添加注释解决了我的问题。

      @XmlRootElement(name = "ReturnObjectClass")
      public class ReturnObjectClass {
      
          @XmlElement(name = "Status", required = true)
          protected StatusType status;
          //...
      }
      

      【讨论】:

        【解决方案9】:

        我遇到了完全相同的问题。查看此参考后:http://zetcode.com/springboot/requestparam/

        我的问题通过改变解决了

        method = RequestMethod.GET, produces = "application/json;charset=UTF-8"

        method = RequestMethod.GET, produces = MediaType.TEXT_PLAIN_VALUE

        别忘了添加库:

        import org.springframework.http.MediaType;
        

        它适用于邮递员或普通浏览器。

        【讨论】:

          【解决方案10】:

          就我而言,我在 ResponseEntity() 中发送了正确的对象。

          正确:

          @PostMapping(value = "/get-customer-details", produces = { MediaType.APPLICATION_JSON_VALUE })
          public ResponseEntity<?> getCustomerDetails(@RequestBody String requestMessage) throws JSONException {
              JSONObject jsonObject = new JSONObject();
              jsonObject.put("customerId", "123");
              jsonObject.put("mobileNumber", "XXX-XXX-XXXX");
              return new ResponseEntity<>(jsonObject.toString(), HttpStatus.OK);
          }
          

          不正确:

          return new ResponseEntity<>(jsonObject, HttpStatus.OK);
          

          因为,jsonObject 的 toString() 方法“将 jsonObject 编码为紧凑的 JSON 字符串”。因此,Spring 直接返回 json 字符串,无需任何进一步的序列化。

          当我们改为发送 jsonObject 时,Spring 尝试根据 RequestMapping 中使用的 producer 方法对其进行序列化,但由于“找不到可接受的表示”而失败。

          【讨论】:

            【解决方案11】:

            即使您执行了上述所有操作,就像我的情况一样,我仍然收到错误 406 - 从邮递员处使用时不可接受。经过仔细研究,我注意到,在请求标头中,“接受”的默认标头是“/”。

            我通过向标题添加预设并关闭默认标题解决了我的问题。请看下面的截图。

            这解决了我的问题,无需任何其他设置甚至添加弹簧配置。

            【讨论】:

              【解决方案12】:

              我必须在我的 POM 中显式调用我的 json 库的依赖项。

              一旦我添加了以下依赖项,它就可以工作了。

              <dependency>
                  <groupId>com.google.code.gson</groupId>
                  <artifactId>gson</artifactId>
              </dependency>
              

              【讨论】:

                【解决方案13】:

                就我而言,我碰巧在使用 lombok,显然与 get 和 set 存在冲突

                【讨论】:

                  【解决方案14】:

                  我也有同样的例外。问题是,我使用了注释

                  @RepositoryRestController

                  而不是

                  @RestController

                  【讨论】:

                  • 谢谢!我试图做this,但出于同样的原因它没有工作。
                  【解决方案15】:

                  当我的一个控制器拦截所有带有空 @GetMapping 的请求时遇到类似问题

                  【讨论】:

                    【解决方案16】:

                    对我来说,问题是试图在 url 中传递带有点的文件名。例如

                    "http://localhost:8080/something/asdf.jpg" //causes error because of '.jpg'
                    

                    可以通过不传递 .jpg 扩展名来解决,或者将其全部发送到请求正文中。

                    【讨论】:

                      【解决方案17】:

                      我遇到了同样的问题,我在设置中缺少的是将它包含在我的 maven (pom.xml) 文件中。

                      <dependency>
                           <groupId>org.codehaus.jackson</groupId>
                           <artifactId>jackson-mapper-asl</artifactId>
                           <version>1.9.9</version>
                      </dependency> 
                      

                      【讨论】:

                        【解决方案18】:

                        我有同样的例外,但原因不同,我找不到任何信息,所以我会在这里发布。这只是一个容易忽略的错误。

                        不好:

                        @RestController(value = "/api/connection")
                        

                        好:

                        @RestController
                        @RequestMapping(value = "/api/connection")
                        

                        【讨论】:

                          【解决方案19】:

                          Spring 5 接受的答案不正确。尝试将 Web 服务的 URL 更改为 .json!这是正确的解决方法。这里有很多细节http://stick2code.blogspot.com/2014/03/solved-orgspringframeworkwebhttpmediaty.html

                          【讨论】:

                            猜你喜欢
                            • 2017-10-18
                            • 1970-01-01
                            • 2019-01-23
                            • 1970-01-01
                            • 1970-01-01
                            • 2019-10-28
                            • 2016-01-29
                            • 1970-01-01
                            • 2016-09-28
                            相关资源
                            最近更新 更多