springMvc 入门二
目的:请求参数接受,输出,常见的注解(在上一篇入门1基础上)
1:请求参数的绑定
1.1绑定的机制
表单中请求参数都是基于key=value的。 SpringMVC绑定请求参数的过程是通过把表单提交请求参数,作为控制器中方法参数进行绑定的。
1.2基本类型参数 请求参数:?userName=lsw&psw=123
<%--请求参数绑定--%> <a href="Param/testParam?userName=lsw&psw=123">请求参数绑定</a>
控制器:
/** * url 地址 Param/testParam?userName=lsw&psw=123 * @param userName * @param pwd * @return */ @RequestMapping(value = "testParam",method = {RequestMethod.GET}) public String testParam(String userName,String pwd){ System.out.println( "testParam" ); System.out.println( "用户名:"+userName ); return "sucess"; }
插曲:注解的一个参数不知道怎么写,选中ctrl+b 进去看源代码,比如RequestMapping
1.3 POJO类型参数: 包括实体类,以及关联的实体类,集合类型(list map)
user类:
1 package cn.lsw.domain; 2 3 4 import java.util.List; 5 import java.util.Map; 6 7 /** 8 * Create by on 2019-09-16 9 * 请求参数绑定 10 * @author lsw 11 */ 12 public class user { 13 14 private String userName; 15 private String pwd; 16 private int age; 17 18 /** 19 * 引用类型 20 */ 21 private Address address; 22 23 /** 24 * 集合 25 */ 26 private List<Address> addressList; 27 28 /** 29 * map 30 */ 31 private Map<String,Address> map; 32 33 public String getUserName() { 34 return userName; 35 } 36 37 public void setUserName(String userName) { 38 this.userName = userName; 39 } 40 41 public String getPwd() { 42 return pwd; 43 } 44 45 public void setPwd(String pwd) { 46 this.pwd = pwd; 47 } 48 49 public Address getAddress() { 50 return address; 51 } 52 53 public void setAddress(Address address) { 54 this.address = address; 55 } 56 57 public int getAge() { 58 return age; 59 } 60 61 public void setAge(int age) { 62 this.age = age; 63 } 64 65 public List<Address> getAddressList() { 66 return addressList; 67 } 68 69 public void setAddressList(List<Address> addressList) { 70 this.addressList = addressList; 71 } 72 73 public Map<String, Address> getMap() { 74 return map; 75 } 76 77 public void setMap(Map<String, Address> map) { 78 this.map = map; 79 } 80 81 @Override 82 public String toString() { 83 return "user{" + 84 "userName='" + userName + '\'' + 85 ", pwd='" + pwd + '\'' + 86 ", age=" + age + 87 ", address=" + address + 88 ", addressList=" + addressList + 89 ", addressMap=" + map + 90 '}'; 91 } 92 }
address:
package cn.lsw.domain; /** * Create by on 2019-09-16 * * @author lsw */ public class Address { private String address; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
控制器:
/** * 请求数据封装到javaBean的类中 * @param user * @return */ @RequestMapping("saveUse") public String saveUse(user user){ System.out.println( user.toString()); return "sucess"; }
<form action="Param/saveUse" method="post"> 用户名称:<input type="text" name="userName" ><br/> 用户密码:<input type="password" name="pwd" ><br/> 用户年龄:<input type="text" name="age" ><br/> 地址:<input type="text" name="address.address" ><br/> 张三地址:<input type="text" name="addressList[0].address" ><br/> 李四地址:<input type="text" name="addressList[1].address" ><br/> 张三map地址:<input type="text" name="map['one'].address" ><br/> 李四map地址:<input type="text" name="map['two'].address" ><br/> <input type="submit" value="保存"> </form>
运行结果:
问题:中文乱码解决: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>
1.4特殊情况 类型转换问题(比如Date)
html:
<%--date--%> <a href="Param/deleteUse?date=2019-01-01">date</a>
控制器:
/** * 删除账户 * @return */ @RequestMapping("/deleteUse") public String deleteUse(Date date) { System.out.println("删除了账户。。。。"+date); return "success"; }
运行结果:
控制台打印:大概意思字符串2019-01-01无法转换date
16-Sep-2019 11:13:01.434 警告 [http-apr-9999-exec-2] org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver.handleTypeMismatch Failed to bind request element: org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'java.util.Date'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.util.Date] for value '2019-01-01'; nested exception is java.lang.IllegalArgumentException
解决办法:自定义转换器
StringToDateConverter:
package cn.lsw.common; /** * Create by on 2019-09-16 * * @author lsw */ import org.springframework.core.convert.converter.Converter; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; /** * 把字符串转换日期 */ public class StringToDateConverter implements Converter<String,Date> { /** * String source 传入进来字符串 * @param source * @return */ @Override public Date convert(String source) { // 判断 if(source == null){ throw new RuntimeException("请您传入数据"); } DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); try { // 把字符串转换日期 return df.parse(source); } catch (Exception e) { throw new RuntimeException("数据类型转换出现错误"); } } }
springMvc.xml添加,修改
<!--配置自定义类型转换器--> <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="cn.lsw.common.StringToDateConverter"/> </set> </property> </bean> <!-- 开启SpringMVC框架注解的支持 --> <mvc:annotation-driven conversion-service="conversionService"/>
运行结果:
1.5 控制器获取原生的servlet API
控制器:
/** * 原生的API 自己在参数上面写上HttpServletRequest,HttpServletResponse * @return */ @RequestMapping("/testServlet") public String testServlet(HttpServletRequest request, HttpServletResponse response){ System.out.println("用户名:"+request.getParameter("name")); HttpSession session = request.getSession(); System.out.println(session); ServletContext servletContext = session.getServletContext(); System.out.println(servletContext); System.out.println(response); return "sucess"; }
html:
<%--原生的API--%> <a href="Param/testServlet?name=lsw">原生的API</a>
运行结果:
2:注解
2.1 RequestParam ,把请求中指定名称的参数给控制器中的形参赋值。
个人理解:给url地址的name起个别名(个人感觉实际运用不多)
新建一个控制器:AnnoController
package cn.lsw.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; /** * Create by on 2019-09-16 * 注解 * @author lsw */ @Controller @RequestMapping("/anno") public class AnnoController { @RequestMapping("/testRequestParam") public String testRequestParam(@RequestParam(name="name") String username){ System.out.println("执行了..."); System.out.println(username); return "sucess"; } }
html:
<a href="anno/testRequestParam?name=lsw">请求参数绑定</a> <br><br>
注意:url 参数的名称是userName 控制器的参数是@RequestParam(name="name") String username
运行结果:
2.2 RequestBody (总结:针对post请求 参数不用定义实体类 方便)
作用: 用于获取请求体内容。直接使用得到是key=value&key=value...结构的数据。 get请求方式不适用。
控制器:
/** * 获取到请求体的内容 * @return */ @RequestMapping("/testRequestBody") public String testRequestBody(@RequestBody String body){ System.out.println("执行了..."); System.out.println(body); return "sucess"; }
html:
<form action="anno/testRequestBody" method="post"> 用户姓名:<input type="text" name="username" /><br/> 用户年龄:<input type="text" name="age" /><br/> <input type="submit" value="提交" /> </form>
运行结果: