目录
SpringMVC的请求参数绑定
(一)绑定说明
1、绑定的机制
表单中的请求参数都是基于key:value键值对的形式,SpringMVC绑定请求参数的过程是通过把表单提交请求参数,作为控制器中方法参数进行绑定的。
2、支持的数据类型
基本类型参数:包括基本类型和String类型 POJO类型参数:包括实体类,以及关联的实体类 数组和集合类型参数:包括List结构和Map结构的集合(包括数组) 这三个当中重点掌握基本类型参数和POJO类型参数
3、使用要求
基本类型和String类型:要求我们的参数名称必须和控制器Controller中的方法的参数名称保持一致(严格区分大小写)
POJO类型,或者他的关联对象:要求表单中的参数名称和POJO类的属性名称保持一致,并且控制器方法的参数类型是POJO类型
(二)参数绑定实例
1、基本类型和String类型作为参数
1.页面定义表单请求 <form action="test2" method="post"> 用户名:<input name="userName" type="text"> 年龄:<input type="text" name="age"> <input type="submit" value="提交"> </form> 2.执行器方法绑定参数: //传入的参数名字必须和表单中的name相同 @RequestMapping("/test2") public String test2(String userName,int age){ System.out.println("用户名"+userName); System.out.println("年龄"+age); //成功后跳转的View图层 return "success"; }
2、POJO类型作为参数
1.写一个实体类Car package com.ujiuye.pojo; public class Car { private String carName; private Double carPrice; public Car() { } public Car(String carName, Double carPrice) { this.carName = carName; this.carPrice = carPrice; } @Override public String toString() { return "Car{" + "carName='" + carName + '\'' + ", carPrice=" + carPrice + '}'; } public String getCarName() { return carName; } public void setCarName(String carName) { this.carName = carName; } public Double getCarPrice() { return carPrice; } public void setCarPrice(Double carPrice) { this.carPrice = carPrice; } } 2.将Car加入到People实体类中作为属性 package com.ujiuye.pojo; import java.io.Serializable; public class People implements Serializable { private Integer id; private String name; private Double money; private Car car; @Override public String toString() { return "People{" + "id=" + id + ", name='" + name + '\'' + ", money=" + money + ", car=" + car + '}'; } public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } public People() { } public People(Integer id, String name, Double money) { this.id = id; this.name = name; this.money = money; } } 2.定义表单发送请求 <form action="test3" method="post"> 用户id:<input name="id" type="text"> 用户名:<input name="name" type="text"> 余额:<input type="text" name="money"> 车名:<input name="car.carName" type="text"> 车价:<input type="text" name="car.carPrice"> <input type="submit" value="提交"> </form> 3.执行器方法绑定参数 //测试pojo类型的作为参数 @RequestMapping("test3") public String test3(People people){ System.out.println(people); return "success"; }
3、POJO类型中包含集合类型参数
(1)页面定义请求: <form action="test4" > 用户名:<input name="name" type="text"> 余额:<input name="money" type="text"> 车名称:<input name="car.carName" type="text"> 车价格:<input name="car.carPrice" type="text"> list集合车1:车名称<input name="carList[0].carName" type="text"> list集合车1:车价格<input name="carList[0].carPrice" type="text"> list集合车2:车名称<input name="carList[1].carName" type="text"> list集合车2:车价格<input name="carList[1].carPrice" type="text"> set集合车1:车名称<input name="carSet[0].carName" type="text"> set集合车1:车价格<input name="carSet[0].carPrice" type="text"> set集合车2:车名称<input name="carSet[1].carName" type="text"> set集合车2:车价格<input name="carSet[1].carPrice" type="text"> map集合车1:车名称<input name="map['x'].carName" type="text"> map集合车1:车价格<input name="map['x'].carPrice" type="text"> map集合车2:车名称<input name="map['y'].carName" type="text"> map集合车2:车价格<input name="map['y'].carPrice" type="text"> <input type="submit" value="提交"> </form> (2)执行器方法绑定参数: @RequestMapping("test4") public String test4(Person person){ System.out.println(person); return "main"; }
(三)参数绑定示例
4、使用 ServletAPI 对象作为方法参数
(1)引入servletAPI的依赖jar包:(注意jar包作用范围provided:不参与项目部署) <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> (2)执行器方法绑定参数: @RequestMapping("test6") public void test6(HttpServletRequest request, HttpServletResponse response,HttpSession session) throws ServletException, IOException { System.out.println("我在请求转发"); request.getRequestDispatcher("/test1").forward(request,response); } 注意: SrpingMVC是对servlet技术的扩展
5、请求参数乱码的问题
Tomcat对GET和POST的请求处理方式是不同的: (1)GET 请求的编码问题,要改 tomcat 的 server.xml配置文件: <Connector connectionTimeout="20000" port="8080"protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8"/> (2)POST 请求的编码问题,要在web.xml文件中配置编码过滤器: <filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
6、静态资源的访问
(1)将静态资源html、css等交给默认的DefaultServlet处理,在SpringMVC.xml文件中配置这些 <mvc:default-servlet-handler></mvc:default-servlet-handler> (2)指定静态资源的访问路径:在springMVC.xml配置文件中加如下配置: <mvc:resources location="/css/" mapping="/css/**"/> <mvc:resources location="/images/" mapping="/images/**"/> <mvc:resources location="/js/" mapping="/js/**"/> 以上两种都可以实现静态资源的访问,所以掌握第一种方式比较简单
(四)自定义参数处理
1、使用场景
SpringMVC不能自动识别参数,转换为我们需要的类型,浏览器报400错误,类型转换异常
2、使用步骤
1.定义类型转换工具类 //Converter这个工具类有俩个泛型参数,第一个参数是当前的数据类型,第二个参数是要转换成的类型 public class MyDateConverter implements Converter<String, Date> { public Date convert(String source) { //生成一个自定义格式的时间 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); Date date = null; //将传入的String类型转化为Date类型 try { date = simpleDateFormat.parse(source); } catch (ParseException e) { e.printStackTrace(); } return date; } } 2.在SpringMVC.xml配置文件中引入自定义工具类 <!-- 配置自定义类型转换器--> <bean id="formattingConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <!-- 将我们自己写的工具类引入--> <bean class="com.ujiuye.utils.MyDateConverter"></bean> </property> </bean> 3.在简化书写处理器映射器、处理器适配器配置中加入工具类 <mvc:annotation-driven conversion-service="formattingConversionService"></mvc:annotation-driven> 4.定义表单请求 <%--测试自定义工具转换类--%> <form action="test4" method="post"> 入职时间:<input type="date" name="hireDate"> <input type="submit" value="提交"> </form> 5.在执行器中绑定参数 //测试自定义转换器 @RequestMapping("test4") public String test4(Date hireDate){ System.out.println(hireDate); return "success"; }
二、SpringMVC的注解详解
前面接触到的注解:
@RequestMapping(value={”/url1“,”/url2“} method) : 当前的注解就是完成我们方法请求的设定
(一)RequestParam
1、RequestParam注解介绍
用于方法的参数位置,用于指定请求参数名称,将该请求参数绑定到注解参数位置。
属性:name:指定要绑定的请求参数名称;
required:指定请求参数是否必传,默认值是true
defaultValue:指定当没有传入请求参数时的默认值;
当没有传入值并且默认值也为空的时候会报错。
2、RequestParam注解使用案例
//测试@RequestParam @RequestMapping("test5") public String test5(@RequestParam(name="pname",required = true,defaultValue = "王嘉诚")String name){ System.out.println(name); return "success"; }
(二)RequestHeader
1、RequestHeader注解介绍
注解在方法入参位置,用户获取请求头信息
2、RequeHeader注解使用案例
@RequestMapping("test2") public String test2(@RequestHeader("Upgrade-Insecure-Requests")String data){ System.out.println(data); return "main"; } //将根据请求头查处的数据存放到参数data中
(三)RequestBody(掌握)
1、RequestBody注解介绍
用于方法入参位置,获取请求体,直接使用得到是key=value&key=value··结构的数据,get请求方式不使用,通常用于将json格式字符串绑定到bean对象中;
2、RequestBody注解使用案例
(1)将客户端json格式请求参数绑定到指定对象bean中 <script type="text/javascript" src="js/jquery.min.js"></script> <button οnclick="sendCar()">发起ajax请求</button> <script type="text/javascript"> function sendCar() { $.ajax({ type: "POST", url: "/test7", data: '{"carName":"宝马","carPrice":"20"}', contentType:"application/json", success: function(msg){ alert( "Data Saved: " + msg ); } }); } 2.执行器绑定对象 @RequestMapping("test7") //@RequestBody这个注解可以获取客户端传到服务器的json数据 public String test7(@RequestBody Car car){ System.out.println("车名"+car.getCarName()+"车价"+car.getCarPrice()); return "success"; }
注意: 1: 因为我们使用springmvc整合json,使用json操作数据之前需要引入json第三方的包
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.11.4</version> </dependency>
2:服务对jackson的支持需要使用tomcat8及以上服务器版本
(四)CookieValue
1、CookieValue注解介绍
用于方法入参位置,把指定cookie名称的值传入控制器方法参数
2、CookieValue注解使用案例
@RequestMapping("test5") public String test5(@CookieValue("JSESSIONID") String data){ System.out.println(data); return "main"; }
(五)ModelAttribute
1、ModelAttribute注解介绍
该注解是SpringMVC4.3版本之后新加入的,它可以用于修饰方法和参数。
出现在方法上,表示当前方法会在控制器的方法执行之前,先执行,它可以修饰没有返回值的方法,也可以修饰有具体返回值的方法。
出现参数上,获取指定的数据给参数赋值。
(1)注解在方法上: @ModelAttribute("shareParam") public String test6(){ System.out.println("我是公共方法"); return "公共参数"; } (2)注解在参数位置: @RequestMapping("test7") public String test7(@ModelAttribute("shareParam")String data){ System.out.println(data); return "main"; }
(六)SessionAttributes
1、SessionAttributes注解介绍
注解在类上,作用将请求域中的参数存放到Session域中,用于参数共享。
2、SessionAttributes注解使用案例
//将参数存放到请求域 @RequestMapping("test8") public ModelAndView test8(ModelAndView modelAndView){ modelAndView.addObject("aa","aa1"); modelAndView.addObject("bb","bb1"); modelAndView.addObject("cc","cc1"); modelAndView.setViewName("main"); return modelAndView; } //将请求域参数存放到session域中 @Controller @RequestMapping("annotation") @SessionAttributes(value = {"aa","bb"}) public class AnnotationController { ... }
三、响应数据和结果视图
(一)返回值分类
1、返回值为字符串(常用掌握)
用于指定返回的逻辑视图名称 控制器: @RequestMapping("test1") public String test1(String pname){ System.out.println(pname); System.out.println("返回Stirng类型测试"); return "success"; }
2、void类型(servlet的api操作)
通常使用原生的Servlet处理请求时,返回该类型; 控制器: @RequestMapping("test2") public void test2(HttpServeltRequest request , HttpServletResponse response){ System.out.println("返回void类型测试"); request.getRequestDispatcher("/response/test1").forwar(request,response); }
3.ModelAndView
用于绑定参数和指定返回视图名称: 控制器代码: @RequestMapping("test3") public ModelAndView test3(ModelAndView modelAndView){ modelAndView.addObject("aa","aa1"); modelAndView.setViewName("main"); return modelAndView; }
(二)转发和重定向
1、forward请求转发
控制器: //测试请求转发 @RequestMapping("test8") public String test8(){ System.out.println("请求转发"); return "forward:/test9"; } //重定向 @RequestMapping("test9") public String test9(){ System.out.println("重定向"); return "success"; } 表单发送请求: <form action="test8" method="post"> <input type="submit" value="请求转发"> </form>
2、redirect重定向
控制器: //重定向测试 @RequestMapping("test11") public String test11(){ System.out.println("重定向开始执行"); return "redirect:/test9"; } 表单发送请求: <form action="test11" method="post"> <input type="submit" value="重定向"> </form>
(三)响应json数据
从服务器端往客户端传送json数据 以前servlet的做法是response.getWriter().write("{key:value,key:value....}"); 现在使用springMVC注解的形式 (1)导入依赖 <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.11.4</version> </dependency> (2)controller代码编写 @RequestMapping("test10") /* * ResponseBody这个注解的作用是将Controller方法返回的对象通过适当的转换器转换为指定的格式后 * 写入到response对象的body区,通常用来返回JSON数据或者XML数据 * 注意:使用了此注解之后就不需要通过ModelAndView视图处理器,直接将数据写入到输出流中 * 他等同于 response.getWriter().write(); * * */ @ResponseBody public List<People> test10(){ List<People> list = new ArrayList<People>(); for (int i = 0;i<10;i++){ People people = new People(); people.setName("王嘉诚"+i); people.setMoney(1000.0+i); list.add(people); } System.out.println(list.size()); return list; }
四、Rest风格编程
(一)Rest风格URL规范介绍
1.什么是restful?
RESTful架构,就是目前最流行的一种互联网软件架构风格。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。REST这个词,是Roy Thomas Fielding在他2000年的博士论文中提出的. Fielding将他对互联网软件的架构原则,定名为REST,即Representational State Transfer的缩写。即"表现层状态转化"。如果一个架构符合REST原则,就称它为RESTful架构。值得注意的是 REST 并没有一个明确的标准,而更像是一种设计的格。 它本身并没有什么实用性,其核心价值在于如何设计出符合 REST 风格的网络接口。
2.restful的优点:
它结构清晰、符合标准、易于理解、扩展方便。
3.restful的特性
(1)资源(Resources):网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的存在。可以用一个 URI(统一资源定位符)指向它,每种资源对应一个特定的 URI 。要获取这个资源,访问它的 URI 就可以,因此 URI 即为每一个资源的独一无二的识别符。 (2)表现层(Representation):把资源具体呈现出来的形式,叫做它的表现层 (Representation)。比如,文本可以用 txt 格式表现,也可以用 HTML 格式、XML 格式、JSON 格式表现,甚至可以采用二进制格式。 (3)状态转化(State Transfer):每发出一个请求,就代表了客户端和服务器的一次交互过程。HTTP 协议,是一个无状态协议,即所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生“状态转化”(State Transfer)。而这种转化是建立在表现层之上的,所以就是“表现层状态转化”。具体说,就是 HTTP 协议里面,四个表示操作方式的动词:GET 、POST 、PUT、DELETE。它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。 (4)传统请求url: 新增:http://localhost:8888/annotation/addPerson POST 修改:http://localhost:8888/annotation/updatePerson POST 删除:http://localhost:8888/annotation/deletePerson?id=1 GET 查询:http://localhost:8888/annotation/findPerson?id=1 GET (4)REST风格请求: 新增:http://localhost:8888/annotation/person POST 修改:http://localhost:8888/annotation/person PUT 删除:http://localhost:8888/annotation/person/1 DELETE 查询:http://localhost:8888/annotation/person/1 GET
(二)PathVariable注解详解
该注解用于绑定url中的占位符。例如:请求url中/annotation/test9/{id},这个{id}就是占位符,url支持占位符是Spring3.0之后加入的,是SpringMVC支持rest风格URL的一个重要标志,因此在Dispatcher的拦截路径必须为"/" 他的属性: value:用于指定url中占位符的名称 required:是否必须提供占位符
(三)PathVariable案例
1、构建页面发起请求
REST风格编程: 新增: <form action="/annotation/person" method="post"> 用户名:<input name="userName" type="text"> 年龄:<input name="age" type="text"> <input type="submit" value="提交"> </form> 修改: <form action="/annotation/person" method="post"> <input type="hidden" name="_method" value="PUT"> 用户名:<input name="userName" type="text"> 年龄:<input name="age" type="text"> <input type="submit" value="提交"> </form> 删除: <form action="/annotation/person/1" method="post"> <input type="hidden" name="_method" value="DELETE"> <input type="submit" value="提交"> </form> 查询: <a href="/annotation/person/1">查询用户</a>
2、定义控制层执行器处理请求
@RequestMapping(value = "person",method = RequestMethod.POST) public String addPerson(String userName,int age){ System.out.println("新增用户:"+userName); return "main"; } @RequestMapping(value = "person",method = RequestMethod.PUT) public String updatePerson(String userName,int age){ System.out.println("修改用户:"+userName); return "main"; } @RequestMapping(value = "person/{id}",method = RequestMethod.DELETE) public String deletePerson(@PathVariable(value = "id")int id){ System.out.println("删除用户:id"+id); return "main"; } @RequestMapping(value = "person/{id}",method = RequestMethod.GET) public String findPerson(@PathVariable(value = "id")int id){ System.out.println("查询用户信息:id"+id); return "main"; }
3、引入请求方式转换过滤器
<filter> <filter-name>hiddenMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>hiddenMethodFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>