1.使用@RequestMapping 映射请求
1.1在类和方法上添加@RequestMapping
SpringMVC 使用@RequestMapping 为控制器指定可以处理哪些 URL 请求。可以在类上和方法上都添加@RequestMapping 注解。如在 IndexController 中添加注解:
1 @Controller 2 //加上这个注解,本类方法访问路径前都要加上/mvc 3 @RequestMapping("/mvc") 4 public class IndexController { 5 //RequestMapping 设置访问路径是 index.html 6 //因为类名上面已经加了/mvc,所以进入这个方法的 url 是/mvc/index.html 7 @RequestMapping("/index.html") 8 public String showIndex() { 9 //因为添加了父路径,而 index.jsp 在根路径,所以前面加/代表相对于根路径 10 return "/index.jsp"; 11 } 12 }
IndexController 类 上 添 加 了 @RequestMapping(“/mvc”) , 相 当 于 一 个 父 路 径 , 即IndexController 类中所有@ResuestMapping 注解的方法访问路径前都要添加上这个路径。想进入 showIndex()方法,路径是/mvc/index.html。@RequestMapping(“/mvc”)相当于@RequestMapping(value=“/mvc”)DispatcherServlet 截获请求后,就通过RequestMapping 提供的信息,将请求进行分发。
应用场景示例:
DeptController 用于处理部门相关的业务。EmployeeController 用于处理员工相关的业务。部门列表叫 list.html,员工列表也叫 list.html。可以通过父路径来区分请求。不需要程序员给每个请求单独起名字,也能让项目中的 url 更规范。
1.2 通过 method 指定 POST 或 或 GET
@RequestMapping 中有一个 method 属性,用于指定当前的方法是用 POST 还是 GET 访问:
1 //此方法只支持 POST 访问方式 2 @RequestMapping(value = "/post.html", method = RequestMethod. POST ) 3 public String showPost() { 4 return "/index.jsp"; 5 }
如果在浏览器中通过 GET 访问,会出现如下错误:
1.3其他参数
其它参数需要对应到 http 请求头:
1. comsume:
1 @RequestMapping(value = "xx.html", consumes = "application/json")
方法仅处理 request Content-Type 为“application/json”类型的请求。
2. produces:
1 @RequestMapping(value = "xx.html", produces = "application/json")
方法仅处理 request 请求中 Accept 头中包含了"application/json"的请求,同时返回的内容类型为 application/json;
3. params:
1 @RequestMapping(value = "xx.html", params = "act=list")
只处理请求中包含 act 参数并且值为 list 的请求。
params=”param1”请求中必须包含参数名为 param1 的参数。
params=”!param1”请求中不能包含参数名为 param1 的参数。
params=”param1!=value1”请求中包含名为 param1 的参数,但参数值不能为 value1。
params={“p1=v1”,p2}请求中必须包含名称为 p1 和 p2 两个参数,且 p1 的值为 v1。
4. headers:
1 @RequestMapping(value = "xx.html", headers = "Referer=http://www.xx.com/")
仅处理 request 的 header 中包含了指定“Refer”请求头和对应值为“ http://www.xx.com/ ”的请求;
1.4 REST 风格 URL
如/delete/123 和/delete/456 这两个 url,其中/delete/是公用的,后面的 123 和 456 是动态的参数。使用@PathVariable 获取参数:
1 //url 中包含参数 2 @RequestMapping(value = "/rest1/{id}") 3 public String testRest1(@PathVariable Integer id) { 4 System. out .println(id); 5 return "/index.jsp"; 6 } 7 //占位的参数和方法中参数名不同的时候 8 @RequestMapping(value = "/rest2/{id} ") 9 public String testRest2(@PathVariable("id") Integer someId) { 10 System. out .println(someId); 11 return "/index.jsp"; 12 }
1.5 支持正则表达式
1 //支持正则表达式匹配 2 @RequestMapping("/reg/{param:[\\d]+.html") 3 public String testRest3(@PathVariable Integer param) { 4 System. out .println(param); 5 return "/index.jsp"; 6 }
{参数名:正则表达式}
应用场景示例:
比如有一些静态页面展示,如果每一个页面都写一个访问的方法,会增加代码量。可以使用动态参数,在路径中提取出页面名称,合并到一个方法。(ps:在项目开发中,有时需要对权限进行限制,比如有些页面必须登录后才能访问。这时就需要限制用户不能直接通过.jsp 直接访问 jsp 页面文件,而是通过.html 经过 Spring 过滤器进行处理。)
上面的代码返回的页面路径前没有加/,所以是相对于当前访问路径的,页面需要放在webapp 的 page 文件夹下才能显示。
1.6 ANT 风格 URL
Ant 风格支持三种匹配符:
1. ?:匹配一个字符
1 @RequestMapping("/ant/test??.html")
可以匹配/ant/testaa.html 或/ant/testbb.html
2. *:匹配任意字符
1 @RequestMapping("/ant/*/test.html")
3. **:匹配多层路径
1 @RequestMapping("/ant/**/test.html")
可以匹配/ant/test.html 或/ant/aa/test.html 或/ant/aa/bb/test.html 等ANT 风格的 url 通常用在资源路径的加载中。
2. 参数绑定
2.1 @RequestParam
使用@RequestParam 可以实现把请求中的参数传递给被请求的方法。在这里我们新建一个 ParamController.java。
2.1.1 value
1 @Controller 2 public class ParamController { 3 @RequestMapping("param1.html") 4 public String testParam1(@RequestParam(value = "name") String name, 5 @RequestParam(value = "id") Integer id) { 6 System. out .println(name); 7 System. out .println(id); 8 return "index.jsp"; 9 } 10 }
在浏览器中访问如下地址:http://localhost:8080/param1.html?name=abc&id=1
可以看到控制台上输出:
abc
1
1 @RequestParam(value = "name") String name
相当于 servlet 中的:
1 String name=request.getParameter("name");
代码:
1 @RequestParam(value = "id") Integer id
相当于 servlet 中的:
1 String idStr= request.getParameter("id"); 2 Integer id=null; 3 if(idStr!=null&& idStr.trim()!=""){ 4 id=Integer.parseInt(idStr) 5 }
2.1.2 required
默 认 的 使 用 @RequestParam 注 解 的 参 数 都 是 必 传 的 。 上 面 的 例 子 中 , 使 用@RequestParam 注解了 name 和 id 两个参数。如果在访问的时候少传一个参数,会出现如下异常:
如果某个参数不是必须的,可以使用 required 属性设置:
1 @RequestParam(value = "id",required = false) Integer id
required 默认是 true,代表参数必传;设置为 false,则代表参数可以为 null。需要注意的是如果注入的是基本类型的数据,如 int 型,参数为空就会抛出异常,因为null 不能赋值给基本数据类型,只能是对象类型。
2.1.3 defaultValue
如果没传某个参数时,想给参数一个默认值,可以使用 defaultValue 属性设置:
1 @RequestParam(value = "name",defaultValue = "123") String name
如果访问时没传 name 参数,将会默认给 name 赋值为 123。相当于 servlet 中的:
1 String name = request.getParameter("name"); 2 if (name = null) { 3 name ="123"; 4 }
2.1.4 简化写法
1 //当 url 中的参数名与方法接收时参数名一致,且参数都是必传的,可以省略@RequestParam 2 @RequestMapping("param3.html") 3 public String testParam3(String name, Integer id) { 4 System. out .println(name); 5 System. out .println(id); 6 return "index.jsp"; 7 }
2.1.5 映射 POJO 类型参数
SpringMVC 支持 POJO 类型参数映射,即将多个参数直接封装成实体类。如我们要将参数封装到 Employee 和 Dept 对象中,先创建实体类:
public class Dept { private Integer id; private String name; private List<Employee> employees; //getter/setter 方法略 } ------------------------------------- public class Employee { private Integer id; private String name; private Float salary; private Dept dept; //getter/setter 方法略 }
controller 中的方法:
1 //映射 pojo 类 2 @RequestMapping("param5.html") 3 public String testParam5(Employee employee) { 4 System. out .println("员工名:" + employee.getName()); 5 System. out .println("员工 id:" + employee.getId()); 6 //支持级联形式的映射 7 System. out .println("员工部门名:" + employee.getDept().getName()); 8 System. out .println("员工部 id:" + employee.getDept().getId()); 9 return "index.jsp"; 10 }
为方便测试,jsp 页面中以表单形式提交请求:
1 <form action="/param5.html" method="post"> 2 员工 id:<input name="id" type="text"/><br/> 3 员工名:<input name="name" type="text"/><br/> 4 <!--级联形式的映射--> 5 员工部门 id:<input name="dept.id" type="text"/><br/> 6 员工部门名:<input name="dept.name" type="text"/><br/> 7 <input type="submit" value="提交"/> 8 </form>
运行结果:
提交后控制台输出:
2.1.6 基本类型的数组
基本数据类型的数组如 Integer[],String[]等比如批量删除数据的时候,需要传递多个数据的 id,这时用一个数组去接收:
1 //映射数组 2 @RequestMapping("param6.html") 3 public String testParam6(Integer[] ids) { 4 for (Integer id : ids) { 5 System. out .println(id); 6 } 7 return "index.jsp"; 8 }
页面:
1 <form action="/param6.html" method="post"> 2 <input name="ids" value="1" type="checkbox"/>1<br/> 3 <input name="ids" value="2" type="checkbox"/>2<br/> 4 <input name="ids" value="3" type="checkbox"/>3<br/> 5 <input name="ids" value="4" type="checkbox"/>4<br/> 6 <input type="submit" value="提交"/> 7 </form>
运行结果:控制台输出:
2.2 @RequestBody
对于复杂的数据类型,如 Dept[]、List<Integer>、List<Dept>、List<Map<String,Object>>以及 Dept 里包含 List<Employee>的映射,不能再使用简单的 form 表单提交请求了,需要使用 ajax 模拟提交 json 数据,并指定请求的 contentType 是 application/json。在 Controller 中用@RequestBody 接收参数。SpringMVC 解析 json 需要一个 json 适配器,json 转化使用的是 jackson,需要在 pom.xml中添加 jackson 的 jar 包:
1 <!-- Jackson Json 处理工具包 --> 2 <dependency> 3 <groupId>com.fasterxml.jackson.core</groupId> 4 <artifactId>jackson-databind</artifactId> 5 <version>2.7.4</version> 6 </dependency>
在 springMVC-servlet.xml 中配置 json 适配器:
1 <bean 2 class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerA 3 dapter"> 4 <property name="messageConverters"> 5 <list> 6 <bean 7 class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> 8 <property name="supportedMediaTypes"> 9 <list> 10 <value>application/json;charset=utf-8</value> 11 </list> 12 </property> 13 </bean> 14 </list> 15 </property> 16 </bean>
在工程中加入 jQuery 类库,如 jquery-1.10.1.min.js:
param.jsp 是我们写页面代码的文件。在页面中引入 jQuery:
1 <script type="text/javascript" src="jquery-1.10.1.min.js"></script>
3.2.1 List<Object> 类型的映射
List 是基本数据类型的集合,如 List<String>类型的映射:
1 //List 集合中包含基本数据类型 2 @RequestMapping("param7.html") 3 public String testParam7(@RequestBody List<String> names) { 4 for (String name : names) { 5 System. out .println(name); 6 } 7 return "index.jsp"; 8 }
页面中发送请求的方法:
1 <input type="button" onclick=" testParam7 ()" value="测试 List<Object>"/> 2 <script type="text/javascript"> 3 function testParam7 (){ 4 var nameList = ["张三","李四 "];//String 类型的数组 5 $.ajax({ 6 type: "POST", 7 url: "/param7.html", 8 data: JSON .stringify(nameList),//将对象序列化成 JSON 字符串 9 contentType : "application/json;charset=utf-8", 10 success: function(data){ 11 alert(data); 12 } 13 }); 14 } 15 </script>
3.2.2 List<POJO> 和 和 POJO[] 类型的映射
如将请求数据封装成 List<Dept>:
1 //List 集合中包含对象类型 2 @RequestMapping("param8.html") 3 //如果是数组,就写(@RequestBody Dept[] depts) 4 public String testParam8(@RequestBody List<Dept> depts) { 5 //public String testParam8(@RequestBody Dept[] depts) { 6 for (Dept dept : depts) { 7 System. out .println(dept.getId() + dept.getName()); 8 } 9 return "index.jsp"; 10 }
如果要封装成数组,就写页面提交请求方法
1 <input type="button" onclick=" testParam8 ()" value="测试 List<POJO>"/> 2 <script type="text/javascript"> 3 function testParam8 (){ 4 var deptList = new Array();//集合中存放的是实体类 5 deptList.push({"id":1,"name":"技术部"}); 6 deptList.push({"id":2,"name":"测试部"}); 7 $.ajax({ 8 type: "POST", 9 url: "/param8.html", 10 data: JSON .stringify(deptList),//将对象序列化成 JSON 字符串 11 contentType : "application/json;charset=utf-8", 12 success: function(data){ 13 alert(data); 14 } 15 }); 16 } 17 </script>
3.2.3 POJO 中包含 List 的映射
1 //POJO 中包含 List。Dept 中包含 List<Employee> 2 @RequestMapping("param9.html") 3 public String testParam9(@RequestBody Dept dept) { 4 System. out .println(dept.getName()); 5 for (Employee employee : dept.getEmployees()) { 6 System. out .println(employee.getName()); 7 } 8 return "index.jsp"; 9 }
页面提交请求的代码:
1 <input type="button" onclick=" testParam9 ()" value="POJO 中包含 List"/> 2 <script type="text/javascript"> 3 function testParam9 (){ 4 var empList = new Array();//集合中存放的是实体类 5 empList.push({"id":1,"name":"张三"}); 6 empList.push({"id":2,"name":"李四"}); 7 var dept={"id":1,"name":"技术部","employees":empList}; 8 $.ajax({ 9 type: "POST", 10 url: "/param9.html", 11 data: JSON .stringify(dept),//将对象序列化成 JSON 字符串 12 contentType : "application/json;charset=utf-8", 13 success: function(data){ 14 alert(data); 15 } 16 }); 17 } 18 </script>
3.2.4 List<Map<String,Object>> 的映射
List 中封装 Map 的操作和封装 POJO 类似:
1 //List<Map<String,Object>>的映射 2 @RequestMapping("param10.html") 3 public String testParam10(@RequestBody List<Map<String, Object>> map) { 4 for (Map<String, Object> stringObjectMap : map) {//遍历集合 5 for (String key : stringObjectMap.keySet()) {//遍历当前 Map 中的 key 6 //根据 key 拿到对应的值 7 System. out .println(key + "=" + stringObjectMap.get(key)); 8 } 9 System. out .println("--------------------"); 10 } 11 return "index.jsp"; 12 }
页面发送请求的代码:
1 <input type="button" onclick=" testParam10 ()" value="测试 List<Map<String,Object>>"/> 2 <script type="text/javascript"> 3 function testParam10 (){ 4 var data = new Array();// 5 data.push({"id":1,"name":"技术部"}); 6 data.push({"id":3,"addr":"三楼"}); 7 $.ajax({ 8 type: "POST", 9 url: "/param10.html", 10 data: JSON .stringify(data),//将对象序列化成 JSON 字符串 11 contentType : "application/json;charset=utf-8", 12 success: function(data){ 13 alert(data); 14 } 15 }); 16 } 17 </script>
3.3 使用 Servlet API
如果我们在方法中还想用 Servlet 的 request 和 response,可以在方法上添加参数:
1 /得到 HttpServletRequest 和 HttpServletResponse 2 @RequestMapping("param4.html") 3 public String testParam4(HttpServletRequest request, HttpServletResponse response) { 4 System. out .println(request.getParameter("name")); 5 return "index.jsp"; 6 }
需要在 pom.xml 中添加 servlet 的 jar 包:
1 <dependency> 2 <groupId>javax.servlet</groupId> 3 <artifactId>javax.servlet-api</artifactId> 4 <version>3.1.0</version> 5 </dependency>
原文地址:https://www.cnblogs.com/sueyyyy/p/9595620.html