@produces

注解@Produces用于定义方法的响应实体的数据类型,可以定义一个或多个,然后与请求头中Accept匹配,匹配成功则将响应数据进行对应转换。


@RequestMapping(value = "/produces", produces = "application/json"):表示该功能处理方法将生产json格式的数据,此时根据http请求头中的Accept进行匹配,如请求头“Accept:application/json”时即可匹配;

该功能处理方法将生产xml格式的数据,此时根据http请求头中的Accept进行匹配,如请求头“Accept:application/xml”时即可匹配。

   

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等数据,然后输出响应流,也是比较麻烦的。

 

@RequestBody、@ResponseBody)和一组转换类(HttpMessageConverter)来完成我们遇到的问题。

@ResponseBody,@RequestBody,@PathVariable 
控制器: 

1. @Controller
2. public class
3.   
4. /**
5.      * 查询个人信息
6.      * 
7.      * @param id
8.      * @return
9.      */
10. @RequestMapping(value = "/person/profile/{id}/{name}/{status}", method = RequestMethod.GET)  
11. public @ResponseBody
12. @PathVariable int id, @PathVariable
13. @PathVariable boolean
14. return new
15.     }  
16.   
17. /**
18.      * 登录
19.      * 
20.      * @param person
21.      * @return
22.      */
23. @RequestMapping(value = "/person/login", method = RequestMethod.POST)  
24. public @ResponseBody
25. @RequestBody
26. return
27.     }  
28. }



备注:

@RequestMapping(value = "/person/profile/{id}/{name}/{status}", method = RequestMethod.GET) 中的 {id}/{name}/{status} 与 @PathVariable int id, @PathVariable String name,@PathVariable boolean status 一一对应,按名匹配。

java中product类型 java @produces_html

 这是restful式风格。 


如果映射名称有所不一,可以参考如下方式: 

1. @RequestMapping(value = "/person/profile/{id}", method = RequestMethod.GET)  
2. public @ResponseBody
3. Person porfile(@PathVariable("id") int
4. return new
5. }



  • GET模式下,这里使用了@PathVariable绑定输入参数,非常适合Restful风格。因为隐藏了参数与路径的关系,可以提升网站的安全性,静态化页面,降低恶意攻击风险。
  • POST模式下,使用@RequestBody绑定请求对象,Spring会帮你进行协议转换,将Json、Xml协议转换成你需要的对象。
  • @ResponseBody可以标注任何对象,由Srping完成对象——协议的转换。

@

RequestParam用法与@

PathVariable

类似,功能类似request.getparameter("xx"),xx名称应与请求参数匹配。

@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";
      }