Java Spring更改URI上的媒体类型,结尾为.au
当前实现了一个REST端点,如下所示:Java Spring更改URI上的媒体类型,结尾为.au,java,spring,rest,content-type,Java,Spring,Rest,Content Type,当前实现了一个REST端点,如下所示: @RequestMapping(path = "/login/user/{username:.+}", method = POST, produces = "application/json; charset=utf-8") @ResponseStatus(code = HttpStatus.OK) public User userLogin(@PathVariable("username") String username, @RequestBody P
@RequestMapping(path = "/login/user/{username:.+}", method = POST, produces = "application/json; charset=utf-8")
@ResponseStatus(code = HttpStatus.OK)
public User userLogin(@PathVariable("username") String username, @RequestBody Password password) {
//do stuff
return new User(UUID.randomUUID());
}
我目前使用电子邮件地址作为用户名,当我使用以.au结尾的电子邮件地址时,端点返回406内容,这是不可接受的
我试着到处玩,把上面的内容改成这个
@RequestMapping(path = "/login/user/{username:.+}", method = POST, produces = "application/json; charset=utf-8")
@ResponseStatus(code = HttpStatus.OK)
public String userLogin(@PathVariable("username") String username, @RequestBody Password password) {
//do stuff
return "blah";
}
当我访问它时,它会提示我下载一个.au文件(Sun microsystems制作的音频格式…),其中包含“blah”。
如果我在方法中随时检查用户名的值,我会得到正确的电子邮件地址,包括.au
我猜Spring堆栈中的某些东西正在解析.au并试图强制执行不同的媒体类型,因此现在它忽略了application/json,我认为这是在序列化程序和反序列化程序时从数据传输对象(DTO)引起的。所以用户应该实现可序列化的界面。我最近遇到了同样的问题,并发现了这个问题。想在这里分享它,因为它会帮助其他人。@Patrick解释说,这种行为似乎是由于Spring MVC中基于URL(URL后缀)的内容协商而发生的 什么是内容协商? 在某些情况下,我们必须处理控制器返回的相同数据的多个表示(或视图)。确定返回哪种数据格式称为内容协商 内容协商是如何进行的? 通过HTTP发出请求时,可以通过设置
Accept
头属性来指定所需的响应类型。然而,浏览器实际上发送非常混乱的Accept
标题,这使得依赖它们变得不切实际。因此,Spring为内容协商提供了一些替代约定
Spring内容协商备选方案-URL后缀和/或URL参数
它们与使用Accept
标题一起工作。因此
可以通过三种方式中的任意一种请求内容类型。默认情况下,他们
按以下顺序进行检查:
- 在URL中添加路径扩展名(后缀)。因此,如果传入的URL类似于HTML
是必需的。对于电子表格,URL应为
. 媒体类型的后缀
映射是通过JavaBeans激活自动定义的
框架或JAF(因此
必须在类路径上)activation.jar
- 类似以下内容的URL参数:。名称
默认情况下,参数为format,但这可能会更改。使用
默认情况下,参数处于禁用状态,但启用后,将选中该参数
第二
- 最后,检查
HTTP头属性。HTTP实际上就是这样定义的,但正如前面提到的,它可以 使用起来可能有问题Accept
- 最后,检查
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false).
favorParameter(true).
parameterName("mediaType").
ignoreAcceptHeader(true).
useJaf(false).
defaultContentType(MediaType.APPLICATION_JSON).
mediaType("xml", MediaType.APPLICATION_XML).
mediaType("json", MediaType.APPLICATION_JSON);
}
}
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false" />
<property name="favorParameter" value="true" />
<property name="parameterName" value="mediaType" />
<property name="ignoreAcceptHeader" value="true"/>
<property name="useJaf" value="false"/>
<property name="defaultContentType" value="application/json" />
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
</map>
</property>
</bean>
我面临着类似的问题。我的资源映射到/upload/(需要文件路径)。因此,资源URI将类似于/upload/a/b/c/test1.jpg、upload/xy/test2.xml等 正如@Rajind所提到的,它将媒体类型视为URL中的扩展(在点(.)之后) HTTP状态406–不可接受 我通过添加下面的配置解决了这个问题
@Configuration
@EnableWebMvc
public class **** implements WebMvcConfigurer {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false);
}
....
....
}
{
"timestamp": 1538992653298,
"status": 406,
"error": "Not Acceptable",
"message": "Could not find acceptable representation",
"path": "/file-manager-services/api-6.0/234833/upload/Mohan/tst.jpg"
}
@Configuration
@EnableWebMvc
public class **** implements WebMvcConfigurer {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false);
}
....
....
}