我有一个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>
此外,我已将必要的bean添加到Spring配置中,如下所示:
@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中删除'produce'并从Postman请求中删除'Accept'标题,则一切正常。 如果我将'produce'更改为'application / xml'并将请求标头更改为'application / xml'或没有任何标头,它也可以工作。
但是使用自定义标题只适用于 ResponseEntity 类,并且不适用于我自己的响应类。
我也试过让Response类扩展ResponseEntity,但没有效果。
我查看了许多解决方案和类似问题 - 没有任何帮助。没有其他人使用自己的自定义“接受”标题。
答案 0 :(得分:0)
我最终设法通过下一个方式解决了这个问题。首先,添加了自己的消息转换器,扩展了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会响应请求,并接受:project / xml&#39;报头中。