【问题标题】:406 HTTP Status for custom accept/header and return type in Spring REST APISpring REST API 中自定义接受/标头和返回类型的 406 HTTP 状态
【发布时间】:2018-05-14 10:23:15
【问题描述】:

我有一个 Spring REST API,它必须响应自定义的 'accept: project/xml' 标头。此外,我从 REST 方法返回自己的 Response 对象,然后将其转换为 XML(以便所有响应都包含在标签内)。 所以,控制器看起来像:

@Controller("Project Controller")
@RequestMapping(value = "/wa", produces = "project/xml; charset=utf-8")
@ResponseBody
public class ProjectController {

    private final IProjectService projectService;

    @Autowired
    public ProjectController(IProjectService projectService) {
        this.projectService = projectService;
    }

    @RequestMapping(method = RequestMethod.GET)
    public Response projectInfo() {
        return new Response(projectService.listProjects());
    }

    @RequestMapping(value = "/start", method = RequestMethod.GET)
    public Response start() {
        return new Response(new JAXBElement<>(new QName("resource"), 
String.class, StaticConstants.STRING_START_TAG));
    }

    @RequestMapping(value = "/end", method = RequestMethod.GET)
    public ResponseEntity<String> end() {
        return ResponseEntity.ok(StaticConstants.STRING_END_TAG);
    }
}

这是 Response 类的样子:

@XmlRootElement(name = "response")
@XmlAccessorType(XmlAccessType.FIELD)
@Data
@NoArgsConstructor
public class Response {

   @XmlAnyElement(lax=true)
   private List<Object> body;

   public Response(Object single) {
      if (body == null) {
          body = new ArrayList<>(1);
      }
      body.add(single);
   }
}

所有封装在 Response 中的 Bean 类也到处都用@XmlRootElement 和@XmlElement 注解标记。

我还包含了所有 fastxml 依赖项(即使是那些不必要的):

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>${com.fasterxml.jackson.version}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${com.fasterxml.jackson.version}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.dataformat</groupId>
        <artifactId>jackson-dataformat-xml</artifactId>
        <version>${com.fasterxml.jackson.version}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>${com.fasterxml.jackson.version}</version>
    </dependency>

我还在 Spring 配置中添加了必要的 bean,如下所示:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.project")
public class BeanConfiguration {

    ...

    @Bean
    public HttpMessageConverter jsonMessageConverter() {
        return new MappingJackson2HttpMessageConverter();
    }
}

问题是我收到 /start 端点的 406 Not Acceptable 状态,但没有收到 /end 端点的状态。 我从 Postman 发送的请求当然包含“Accept: project/xml”标头。

因此,如果我从 Controller 中删除“produces”并从 Postman 请求中删除“Accept”标头,那么一切正常。 如果我将 'produces' 更改为 'application/xml' 并将请求标头更改为 'application/xml' 或没有任何标头,它也可以工作。

但使用自定义标头,它仅适用于 ResponseEntity 类,不适用于我自己的 Response 类。

我也尝试过让 Response 类扩展 ResponseEntity,但没有效果。

我查看了许多解决方案和类似问题 - 没有任何帮助。没有其他人使用自己的自定义“接受”标头。

【问题讨论】:

  • 您的project/xml 与任何通用application/xml 媒体类型有何不同?你为什么不坚持application/vnd.some-project+xml
  • 没有区别。我正在实现将由另一个应用程序使用的 API,该应用程序本身使用此“项目/xml”接受标头,并且无法更改。有另一个词代替了“项目”,但我不能分享它。

标签: java xml spring rest jaxb


【解决方案1】:

我最终设法通过下一种方式解决了这个问题。首先,添加自己的消息转换器,扩展Jaxb2RootElementHttpMessageConverter并调用setSupportedMediaTypes方法:

public class ProjectXmlMessageConverter extends Jaxb2RootElementHttpMessageConverter {

    public ProjectXmlMessageConverter() {
        super();
        setSupportedMediaTypes(Collections.singletonList(MediaType.valueOf("project/xml")));
}

}

其次,以这种方式将我的转换器添加到已定义的转换器列表中:

@EnableWebMvc
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new ProjectXmlMessageConverter());
    }
}

现在它可以工作了,我的 API 响应带有“Accept: project/xml”标头的请求。

【讨论】:

    猜你喜欢
    • 2018-07-22
    • 2012-06-17
    • 2019-04-30
    • 2023-03-17
    • 2019-05-05
    • 1970-01-01
    • 2016-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多