封装为Map集合
同样,SpringMVC要封装Map集合,需要封装到有Map属性的对象中。
1、pojo
public class User { private String username; private int age; private Map<String,Address> addressMap; //get/set/构造省略 }
2、控制器
/*对象中包含Map属性*/ @RequestMapping("/pojoMap") public void pojoMap(User user){ System.out.println(user); }
3、访问
http://localhost:8080/pojoMap?username=zhangsan&age=13&addressMap[%27one%27].addressName=beijing&addressMap[%27one%27].postCode=030000&addressMap[%27two%27].addressName=shanghai&addressMap[%27two%27].postCode=123123
4、结果
2.5 使用Servlet原生对象获取参数
SpringMVC也支持使用Servlet原生对象,在方法参数中定义HttpServletRequest
、HttpServletResponse
、HttpSession
等类型的参数即可直接在方法中使用。
1、控制器
/*通过servlet原生对象获取参数*/ @RequestMapping("/servlet") public void getByServlet(HttpServletRequest request, HttpServletResponse response, HttpSession session){ System.out.println(request.getParameter("username")); System.out.println(request.getParameter("age")); }
2、访问
http://localhost:8080/servlet?username=zhangsan&age=23
一般情况下,在SpringMVC中都有对Servlet原生对象的方法的替代,推荐使用SpringMVC的方式代替Servlet原生对象。
2.6 自定义参数类型转换器
前端传来的参数全部为字符串类型,SpringMVC使用自带的转换器将字符串参数转为需要的类型。如:
我们访问:http://localhost:8080/getUser?username=zhangsan&age=23
@RequestMapping("/getSimpleParam") public void simpleParam(String userName,int age){ System.out.println(userName); System.out.println(age); }
此时,springMVC会自动将字符串类型的age转为int类型。这是因为mvc使用自己的转换器将字符串类型的数据转换为了int类型的数据。
但在某些情况下,无法将字符串转为需要的类型,如:
@RequestMapping("/date") public void dateParam(Date birthday){ System.out.println(birthday); }
由于日期数据有很多种格式,SpringMVC没办法把所有格式的字符串转换成日期类型。比如参数格式为birthday=2025-01-01
时,SpringMVC就无法解析参数。此时需要自定义参数类型转换器。
1、定义类型转换器类,实现Converter接口
// 类型转换器必须实现Converter接口,两个泛型代表转换前的类型,转换后的类型 public class DateConverter implements Converter<String, Date> { @Override public Date convert(String source) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Date date = null; try { date = sdf.parse(source); //抓换后的结果 } catch (ParseException e) { e.printStackTrace(); } return date; } }
2、配置文件中注册类型转换器对象
<!--注册自定义类型转换器--> <!--配置转换器工厂--> <bean id="converterFactory" class="org.springframework.context.support.ConversionServiceFactoryBean"> <!--转换器集合--> <property name="converters"> <set> <!--自定义的转换器--> <bean class="com.zj.converter.DateConverter"/> </set> </property> </bean>
3、配置通过注解使用转换器工厂
<!-- 开启SpringMVC注解的支持 --> <mvc:annotation-driven conversion-service="converterFactory"/>
3、访问
http://localhost:8080/date?birthday=2025-01-01
2.7 编码过滤器
在传递参数时,tomcat8以上能处理get请求的中文乱码,但不能处理post请求的中文乱码。tomcat7版本有tomcat8之后版本的功能,也能处理get请求中文乱码。
1、编写jsp表单
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>编码过滤器</title> </head> <body> <form action="/post" method="post"> 姓名:<input name="username"> <input type="submit"> </form> </body> </html>
2、控制器
@Controller public class MyController { //获取表单数据(post请求) @RequestMapping("/post") public void post(String username){ System.out.println(username); } }
3、访问
4、SpringMVC提供了处理中文乱码的过滤器,在web.xml中配置该过滤器即可解决中文乱码问题:
<!--SpringMVC中提供的字符编码过滤器,放在所有过滤器的最上方--> <filter> <filter-name>encFilter</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>encFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
三、SpringMVC处理响应
3.1 配置视图解析器
SpringMVC默认情况下会在控制器执行完成后跳转到视图页面,视图解析器能找到相应的视图,之前的404异常就是由于没有配置视图解析器导致找不到视图。
在SpringMVC中提供了13个视图解析器,用于支持不同的视图技术。InternalResourceViewResolver是SpringMVC的默认视图解析器,用来解析JSP视图。
<!-- 视图解析器 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 视图前缀 --> <property name="prefix" value="/" /> <!-- 视图后缀 --> <property name="suffix" value=".jsp" /> </bean>
3.2 控制器方法的返回值
返回值为void
此时会跳转到名字是 前缀+方法路径名+后缀 的jsp页面。
1、编写控制器方法
// 路径是helloMVC,方法执行完后会跳转到/helloMVC.jsp @RequestMapping("/helloMVC") public void helloMVC(){ System.out.println("hello SpringMVC!"); }
2、编写helloMVC.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>MVC</title> </head> <body> <h1>欢迎来到SpringMVC</h1> </body> </html>
3、访问
返回值为String
此时会跳转到名字是 前缀+返回值+后缀 的jsp页面。
1、控制器
// 返回值为String @RequestMapping("/hello") public String helloMVC1(){ System.out.println("hello SpringMVC!"); // 方法执行完后会跳转到/helloMVC.jsp return "helloMVC"; }
2、访问
返回值为ModelAndView
这是SpringMVC提供的对象,该对象可以向request域设置数据并指定跳转的页面。该对象中包含Model对象和View对象。
- Model:向request域中设置数据。
- View:指定跳转的页面。
1、控制器
// 返回值为ModelAndView @RequestMapping("/hello2") public ModelAndView useMAV(){ System.out.println("返回值类型为ModelAndView"); // 1.创建ModelAndView对象 ModelAndView modelAndView = new ModelAndView(); // 2.获取Model对象,本质是一个Map Map<String, Object> model = modelAndView.getModel(); // 3.使用Model对象向request域设置数据 model.put("name","张三"); // 4.使用View对象设置跳转的路径为/helloMVC.jsp modelAndView.setViewName("helloMVC"); return modelAndView; }
2、修改web.xml命名空间,让jsp页面默认支持el表达式
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> </web-app>
3、编写jsp页面
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <html> <head> <title>MVC</title> </head> <body> <h1>你好,${requestScope.name}</h1> </body> </html>
4、访问
3.3 request域设置数据
当控制器返回值为ModelAndView时我们可以向request域设置数据,我们还有以下方法可以向request域设置数据:
使用原生的HttpServletRequest
@RequestMapping("/hello3") public String setRequestModel(HttpServletRequest request){ request.setAttribute("name","张三"); return "helloMVC"; }
使用Model、ModelMap
SpringMVC提供了Model接口和ModelMap类,控制器方法添加这两个类型的参数,使用该参数设置数据,该数据就会存到request域中。
@RequestMapping("/hello4") public String setRequestModel2(Model model, ModelMap modelMap){ // 使用Model将数据存入request域 //model.addAttribute("name","张三"); // 使用ModelMap将数据存入request域 modelMap.addAttribute("name","张三"); return "helloMVC"; }
使用Map集合
Model接口底层就是一个Map集合,我们可以给控制器方法设置Map类型的参数,向Map中添加键值对,数据也会存到request域中。
@RequestMapping("/hello5") public String setRequestModel3(Map map){ map.put("name","张三"); return "helloMVC"; }
3.4 session域设置数据
Session作用域表示在当前会话中有效。在SpringMVC中对于Session作用域传值,只能使用HttpSession对象来实现。
@RequestMapping("/hello6") public String setSessionModel(HttpSession session){ session.setAttribute("address","北京"); return "helloMVC"; }
3.5 context域设置数据
context作用域表示在整个应用范围都有效。在SpringMVC中对context作用域传值,只能使用ServletContext对象来实现。但是该对象不能直接注入到方法参数中,需要通过HttpSession对象获取。
1、控制器
@RequestMapping("/hello7") public String setContextModel(HttpSession session){ ServletContext servletContext = session.getServletContext(); servletContext.setAttribute("name","张三"); return "helloMVC"; }
2、jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <html> <head> <title>MVC</title> </head> <body> <h1>你好,${applicationScope.name}</h1> </body> </html>