我已创建此REST映射,以便它可以接受URI末尾的文件名...
@RequestMapping(value="/effectrequest/{name}/{imagename:[a-zA-Z0-9%\\.]*}",
headers="Accept=*/*", method=RequestMethod.GET,
produces = "application/json")
public @ResponseBody EffectRequest effectRequest(
@PathVariable("name") String name,
@PathVariable("imagename") String imageName)
{
return new EffectRequest(2, "result");
}
使用MappingJackson2HttpMessageConverter返回JSON内容。我使用...
对这个映射进行了测试jQuery AJAX调用var effectName = 'Blur';
var imageName = 'Blah.jpg';
var requestUri = '/effectrequest/' + effectName + '/' + imageName;
alert(requestUri);
$(document).ready(function() {
$.ajax({
url: /*[+ [[${hostname}]] + requestUri +]*/
}).then(function(data) {
$('.effect').append(data.id);
$('.image').append(data.content);
});
});
这会生成一个http://localhost/effectrequest/Blur/Blah.jpg的URI,并且在调试会话中,在上面的effectRequest()方法中正确接收文件名。但是,即使在RequestMapping中使用produces = "application/json"
,客户端或jQuery AJAX调用也会从服务器收到HTTP 406错误(不可接受)。
经过多次调试后,我缩小了范围 - 当我修改测试javascript代码以生成http://localhost/effectrequest/Blur/Blah.json
的URI时,它可以工作。因此,Tomcat或MappingJackson2HttpMessageConverter
通过查看URI末尾的文件扩展名并确定我发回的JSON内容不是很好的匹配来导致HTTP 406错误。
无论如何都要重写此行为而不必编码。文件名中的(点)?
答案 0 :(得分:10)
默认情况下,Spring MVC在尝试找出对请求的响应的媒体类型时,更喜欢使用请求的路径。这在javadoc for ContentNegotiationConfigurer.favorPathExtension()
:
指示是否应使用请求路径的扩展名来确定具有最高优先级的请求媒体类型。
默认情况下,此值设置为true,在这种情况下,
/hotels.pdf
的请求将被解释为"application/pdf"
的请求,无论Accept标头如何。
在您的情况下,这意味着/effectrequest/Blur/Blah.jpg
的请求被解释为对image/jpeg
的请求,MappingJackson2HttpMessageConveter
尝试撰写image/jpeg
无法回复的请求要做。
您可以使用ContentNegotiationConfigurer
扩展WebMvcConfigurerAdapter
来轻松更改此配置。例如:
@SpringBootApplication
public class Application extends WebMvcConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
public void configureContentNegotiation(
ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false);
}
}