@RequestMapping(value = "/produces", produces = "application/json"):表示该功能处理方法将生产json格式的数据,此时根据http请求头中的Accept进行匹配,如请求头“Accept:application/json”时即可匹配;
@RequestMapping(value = "/produces", produces = "application/xml"):表示该功能处理方法将生产xml格式的数据,此时根据http请求头中的Accept进行匹配,如请求头“Accept:application/xml”时即可匹配。
此种方式相对使用@RequestMapping的“headers = "Accept=application/json"”更能表明你的目的。
服务器控制器代码详解cn.javass.chapter6.web.controller.consumesproduces.ProducesController;
客户端代码类似于之前的Content-Type中的客户端,详见ProducesController.java代码。
当你有如下Accept头:
①Accept:text/html,application/xml,application/json
将按照如下顺序进行produces的匹配 ①text/html ②application/xml ③application/json
②Accept:application/xml;q=0.5,application/json;q=0.9,text/html
将按照如下顺序进行produces的匹配 ①text/html ②application/json ③application/xml
q参数为媒体类型的质量因子,越大则优先权越高(从0到1)
③Accept:*/*,text/*,text/html
将按照如下顺序进行produces的匹配 ①text/html ②text/* ③*/*
即匹配规则为:最明确的优先匹配。
代码详见ProducesPrecedenceController1、ProducesPrecedenceController2、ProducesPrecedenceController3。
Accept详细信息,请参考http://tools.ietf.org/html/rfc2616#section-14.1。
方法级别的注解覆盖类级别上的注解
类级别上映射为 @RequestMapping(value="/narrow", produces="text/html"),
方法级别上映射为@RequestMapping(produces="application/xml"),
此时方法级别的映射将覆盖类级别,因此请求头是“Accept:application/xml”则能成功,请求头为“text/html”将不能匹配,匹配不成功(或转换失败,如json转换缺依赖包)会报406错误码,表示不支持的请求媒体类型。
详见cn.javass.chapter6.web.controller.consumesproduces.NarrowController。
只有生产者/消费者 模式 是 覆盖,其他的使用方法是继承,如headers、params等都是继承。
四、组合使用是“或”的关系
@RequestMapping(produces={"text/html", "application/json"}) :
将匹配“Accept:text/html”或“Accept:application/json”。
五、问题
消费的数据,如JSON数据、XML数据都是由我们读取请求的InputStream并根据需要自己转换为相应的模型数据,比较麻烦;
生产的数据,如JSON数据、XML数据都是由我们自己先把模型数据转换为json/xml等数据,然后输出响应流,也是比较麻烦的。
Spring提供了一组注解(@RequestBody、@ResponseBody
)和一组转换类(HttpMessageConverter
)来完成我们遇到的问题。
@ResponseBody,@RequestBody,@PathVariable
控制器:
@RequestMapping(value="fileupload", method=RequestMethod.POST,produces="text/html;charset=utf-8")
public @ResponseBody String addPic(HttpServletResponse response,HttpServletRequest request,
@RequestParam(value="file", required=false) MultipartFile file) throws IOException{
System.out.println(file.getOriginalFilename());
String path = request.getSession().getServletContext().getRealPath("upload");
if (path ==null){path="D:\\fileupload";}
File targetfile=new File(path,file.getOriginalFilename());
if (!targetfile.exists()){
targetfile.mkdirs();
}
try{
file.transferTo(targetfile);
return "success";
}catch(Exception e){
e.printStackTrace();
return "unkonw error";
}