SpringMVC和Struts2最大区别可能就是注解的使用。因为SpringMVC中可以实现在类这个层面上面配置信息,也可以在方法层面上面配置信息,既灵活又方便,不需要写大量的配置文件,也不需要写大量的action控制类,因为SpringMVC仅仅通过注解就可以实现了Action控制器的跳转和一些常用的功能。
通过注解来实现Action控制器中的execute方法和页面跳转的功能,而且SpringMVC中拦截器的实现也比Struts2方便的多,所以在开发效率方面SpringMVC比Struts2强,正因为如此所以SpringMVC的使用率这几年正在逐渐上升。
下面就来介绍一下RequestMapping中常用注解的用法。
RequestMapping中有六个属性分别是:
value: 指定请求的实际地址,指定的地址可以是URI Template 模式;
method: 指定请求的method类型, GET、POST、PUT、DELETE等;
consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
params: 指定request中必须包含某些参数值是,才让该方法处理。
headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。
其中比较常用的是value,method,params;具体的案例我就不多介绍了,有兴趣了解的可以看这篇博客:点击打开链接
1.RequestMapping最基础的用法就是实现类或者方法的访问控制:例如下面案例就是方法上面的控制:
- @RequestMapping(value = “testlogin.do”,method = RequestMethod.POST)
- public String testLogin(){
- return “redirect:login”;
- }
@RequestMapping(value = "testlogin.do",method = RequestMethod.POST)
public String testLogin(){
return "redirect:login";
}
- <form id=“loginTestForm” action=“testlogin.do” method=“post”>
- <input type=“submit” value=“submit”>
- </form>
<form id="loginTestForm" action="testlogin.do" method="post">
<input type="submit" value="submit">
</form>
从代码上面就可以很明显的看出来,在表单中提交action地址,通过SpringMVC框架会自动找到value值等于action地址的方法然后就会执行这个方法。
这里需要注意的是form表单中提交的方式要和方法里面的method一直,否则就会报错。上面的例子中两个都是post方法提交的。
2.RequestMapping带参数的情况:
- @RequestMapping(value = “testlogin.do”,method = RequestMethod.POST)
- public String testLogin(@RequestParam(“departmentId”) String departmentId){
- System.out.println(“输入的参数为:”+departmentId);
- return “redirect:login”;
- }
@RequestMapping(value = "testlogin.do",method = RequestMethod.POST)
public String testLogin(@RequestParam("departmentId") String departmentId){
System.out.println("输入的参数为:"+departmentId);
return "redirect:login";
}
第一种表单形式:- <form id=“loginTestForm” action=“testlogin.do” method=“post”>
- <input type=“text” name=“departmentId” id=“departmentId”></br>
- <input type=“submit” value=“submit”>
- </form>
<form id="loginTestForm" action="testlogin.do" method="post">
<input type="text" name="departmentId" id="departmentId"></br>
<input type="submit" value="submit">
</form>
第二中表单形式:- <form id=“loginTestForm” action=“testlogin.do?departmentId=123” method=“post”>
- <input type=“submit” value=“submit”>
- </form>
<form id="loginTestForm" action="testlogin.do?departmentId=123" method="post">
<input type="submit" value="submit">
</form>
以上两种的结果是一样的,都可以执行方法中内容。其中@RequestParam还有其他的写法,我这里就不多介绍了,有兴趣的可以自己去了解一下。
3.RequestMapping中获取URL中的参数信息:
- <form id=“loginTestForm” action=“testlogin.do/adc” method=“post”>
- <input type=“submit” value=“submit”>
- </form>
<form id="loginTestForm" action="testlogin.do/adc" method="post">
<input type="submit" value="submit">
</form>
- @RequestMapping(value = “testlogin.do/{departmentId}”,method = RequestMethod.POST)
- public String testLogin(@PathVariable(“departmentId”) String departmentId){
- System.out.println(“输入的URL参数为:”+departmentId);
- return “redirect:login”;
- }
@RequestMapping(value = "testlogin.do/{departmentId}",method = RequestMethod.POST)
public String testLogin(@PathVariable("departmentId") String departmentId){
System.out.println("输入的URL参数为:"+departmentId);
return "redirect:login";
}
通过{变量名称}这样的写法,就可以在@PathVariable(“变量名”) 实现参数的调用了。
当然也可以绑定多个参数,例如:
- @RequestMapping(value = “testlogin.do/departmentId/{departmentId}/departmentName/{departmentName}”,method = RequestMethod.POST)
- public String testLogin(@PathVariable(“departmentId”) String departmentId,@PathVariable(“departmentName”) String departmentName){
- System.out.println(“输入的URL参数为1:”+departmentId);
- tem.out.println(“输入的URL参数为2:”+departmentName);
- return “redirect:login”;
- }
@RequestMapping(value = "testlogin.do/departmentId/{departmentId}/departmentName/{departmentName}",method = RequestMethod.POST)
public String testLogin(@PathVariable("departmentId") String departmentId,@PathVariable("departmentName") String departmentName){
System.out.println("输入的URL参数为1:"+departmentId);
System.out.println("输入的URL参数为2:"+departmentName);
return "redirect:login";
}
还有就是可以实现正则表达式,我这里就不多介绍了,有兴趣的可以看一下这篇博客:点击打开链接到这里RequestMapping一些常用的方法就介绍完了,当然还有很多其他的用法。例如:在类中中实现action控制,方法之间相互访问跳转之类的,不过这些方法的实现基本都是基于RequestMapping这些常用方法实现的。
如博客内容有问题或有疑义,请及时提出,不甚感谢。本人QQ:208017534
@RequestMapping(value = ”/produces”, produces = “application/json”):表示将功能处理方法将生产json格式的数据,此时根据请求头中的Accept进行匹配,如请求头“Accept:application/json”时即可匹配;
@RequestMapping(value = ”/produces”, produces = “application/xml”):表示将功能处理方法将生产xml格式的数据,此时根据请求头中的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”将报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
)来完成我们遇到的问题,详见6.6.8节。