簡體   English   中英

Spring REST API中自定義接受/標題和返回類型的406 HTTP狀態

[英]406 HTTP Status for custom accept/header and return type in Spring REST API

我有一個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不可接受狀態,但沒有收到/ end端點的狀態。 我從Postman發送的請求當然包含“ Accept:project / xml”標頭。

因此,如果我從Postman請求中刪除Controller中的“ produces”和“ Accept”標頭,則一切正常。 如果我將'produces'更改為'application / xml'並且將請求標頭更改為'application / xml'或不包含任何標頭,則它也可以工作。

但是使用自定義標頭僅適用於ResponseEntity類,不適用於我自己的Response類。

我也嘗試過使Response類擴展ResponseEntity,但沒有效果。

我已經瀏覽了許多解決方案和類似問題-沒有任何幫助。 而且沒有其他人使用自己的自定義“ Accept”標頭。

我最終設法以另一種方式解決了此問題。 首先,添加了自己的消息轉換器,該消息轉換器擴展了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”標頭響應請求。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM