Spring @RestController,spring-boot 出现意外错误(类型=不可接受,状态=406)

Posted

技术标签:

【中文标题】Spring @RestController,spring-boot 出现意外错误(类型=不可接受,状态=406)【英文标题】:There was an unexpected error (type=Not Acceptable, status=406) for Spring @RestController, spring-boot 【发布时间】:2016-08-11 04:12:08 【问题描述】:

我正在尝试从我的 @RestController 方法返回 xml -

@RestController
public class MCSController 
.
.
@RequestMapping(value = "/encoders", method =  RequestMethod.GET , produces =  MediaType.APPLICATION_JSON,
        MediaType.APPLICATION_XML )
public List<EncoderVO> getEncoders() 

    List<EncoderVO> encoders = null;
    try 
        encoders = infoService.listEncoders();
     catch (MCSException e) 
        logger.error("Error in listing encoders : " + e.getMessage());
    
    return encoders;

这是我的 EncoderVO.java -

@XmlRootElement
public class EncoderVO 

@XmlElement
private Long id;

@XmlElement
private String name;

@XmlElement
private Boolean flagActive;

public EncoderVO() 


public EncoderVO(Long id, String name, Boolean flagActive) 
    super();
    this.id = id;
    this.name = name;
    this.flagActive = flagActive;


public Long getId() 
    return id;


public void setId(Long id) 
    this.id = id;


public String getName() 
    return name;


public void setName(String name) 
    this.name = name;


public Boolean getFlagActive() 
    return flagActive;


public void setFlagActive(Boolean flagActive) 
    this.flagActive = flagActive;



这是我的 pom.xml 文件 -

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

<groupId>com.test</groupId>
<artifactId>mcs</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<!-- Inherit defaults from Spring Boot -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.0.RELEASE</version>
</parent>

<properties>
    <aws.sdk-version>1.9.1</aws.sdk-version>
    <liquibase.version>3.3.0</liquibase.version>
</properties>

<!-- Add typical dependencies for a web application -->
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <artifactId>jackson-annotations</artifactId>
                <groupId>com.fasterxml.jackson.core</groupId>
            </exclusion>
        </exclusions>
    </dependency>

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

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-rest</artifactId>
        <exclusions>
            <exclusion>
                <artifactId>jackson-annotations</artifactId>
                <groupId>com.fasterxml.jackson.core</groupId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jms</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.activemq</groupId>
        <artifactId>activemq-broker</artifactId>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <scope>test</scope>
    </dependency>

    <!-- Aws SDK Dependencies -->
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk-s3</artifactId>
        <version>$aws.sdk-version</version>
    </dependency>
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk-elastictranscoder</artifactId>
        <version>$aws.sdk-version</version>
    </dependency>
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk-sqs</artifactId>
        <version>$aws.sdk-version</version>
    </dependency>
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk-sns</artifactId>
        <version>$aws.sdk-version</version>
    </dependency>
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk-datapipeline</artifactId>
        <version>$aws.sdk-version</version>
    </dependency>
    <dependency>
        <groupId>com.amazonaws</groupId>


        <artifactId>aws-java-sdk-cloudfront</artifactId>
            <version>$aws.sdk-version</version>
        </dependency>

    </dependencies>

</project>

下面是我的应用程序类 -

@SpringBootApplication(exclude =  SpringBootWebSecurityConfiguration.class, LiquibaseAutoConfiguration.class )
@ComponentScan(basePackages =  "com.test.ott.mcs" )
@EnableAspectJAutoProxy
@EnableJms
@EntityScan("com.test.ott.mcs.entities")
@EnableJpaRepositories("com.test.ott.mcs.repository")
    public class MCSApplication 

    @Bean
    JmsListenerContainerFactory<?> jmsContainerFactory(ConnectionFactory connectionFactory) 
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        // A core poll size of 3 threads and a maximum pool size of 10 threads
        factory.setConcurrency("3-10");
        return factory;
    

    // Using factory pattern with spring annotation
    @Bean
    public FactoryBean serviceLocatorFactoryBean() 
        ServiceLocatorFactoryBean factoryBean = new ServiceLocatorFactoryBean();
        factoryBean.setServiceLocatorInterface(EncodingAPIFactory.class);
        return factoryBean;
    

    public static void main(String args[]) 
        SpringApplication.run(MCSApplication.class, args);
    


当我在浏览器中点击 url /encoders 时,我收到以下错误 -

出现意外错误(类型=不可接受,状态=406)。可以 找不到可接受的代表

我的 calsspath 中与 jackson 相关的 jar 是 -

jackson-core-asl : 1.9.13 杰克逊-jaxrs:1.9.13 jackson-mapper-asl:1.9.13 杰克逊注解:2.6.3 杰克逊核心:2.6.3 jackson-module-jaxb-annotations : 2.2.3 jackson-jaxrs-json-provider : 2.2.3 jackson-jaxrs-base : 2.5.4 杰克逊数据绑定:2.6.3

所以,我的类路径中有 MappingJackson2HttpMessageConverter

请提出建议。提前致谢。

【问题讨论】:

您可以添加更多信息吗?您发送到此端点的请求 (curl)。 这是一个简单的 get 请求,我在我的 localhost (tomcat) 服务器上运行的应用程序上遇到它。 - 'http:/localhost:8080/encoders' Jackson1 不受支持,并且您确定 jackson 2 版本存在,因为您已排除它们(为什么?)。此外,List&lt;EncoderVo&gt; 对 XML 无效,因为它不是 XML 类型,所以会失败。 @M.Deinum 我的依赖项中有 jackson2 ,这是我从另一个本地模块中获取的,我在发布此问题时已从 pom 中删除了该模块。这就是排除的原因。是的,该列表不是 xml 类型,可能这就是它失败的原因。我怎样才能使它与List&lt;EncoderVo&gt; 一起工作?谢谢。 AFAIK 你不能。您必须将其包装在 EnvoderVos 对象中,该对象又具有列表。您需要返回一个 XML 对象,否则编组器无法理解它。 【参考方案1】:

有一种开箱即用的解决方案,类似于 JAX-RS,但输出稍差。该解决方案使用jackson-dataformat-xml。为您的项目添加依赖项:

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

响应将如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<List>
   <item>
      <id>1</id>
      <name>testEncoder1</name>
      <flagActive>true</flagActive>
   </item>
   <item>
      <id>2</id>
      <name>testEncoder2</name>
      <flagActive>true</flagActive>
   </item>
   <item>
      <id>3</id>
      <name>testEncoder3</name>
      <flagActive>true</flagActive>
   </item>
</List>

更多详情请关注Spring MVC Way (jackson-dataformat-xml)

【讨论】:

【参考方案2】:

试试

http://localhost:8080/mcs-0.0.1-SNAPSHOT/encoders.

mcs 是应用程序的名称,并且 0.0.1-SNAPSHOT 版本。

如果它不起作用,您必须在 RequestController 中添加一个全局路径。类似的东西:

@RestController
@RequestMapping(value = "/mcs")
public class MCSController 
.
.
@RequestMapping(value = "/encoders", method =  RequestMethod.GET , produces =  MediaType.APPLICATION_JSON,
        MediaType.APPLICATION_XML )
public List<EncoderVO> getEncoders() 

这个请求:

http://localhost:8080/mcs-0.0.1-SNAPSHOT/mcs/encoders

希望对你有帮助。

干杯

【讨论】:

问题是我能够在我的控制器方法中获取日志并且它正在访问后端并获取列表,但是在将列表转换为 XML 时,这给出了 406。【参考方案3】:

在你的 POM.xml 中添加这个依赖

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.8</version>

问题出在这个 jar 的版本上。所以请尝试这个解决方案

【讨论】:

以上是关于Spring @RestController,spring-boot 出现意外错误(类型=不可接受,状态=406)的主要内容,如果未能解决你的问题,请参考以下文章

Spring @RestController 用于匿名和授权用户的单一方法

Spring 注解中@RestController与@Controller的区别

Spring 注解中@RestController与@Controller的区别

Spring 注解中@RestController与@Controller的区别

Spring中@Controller和@RestController之间的区别

Spring @RestController 生成没有命名空间的 XML