SpringMVC
1 了解MVC
MVC是英文Modle(具体业务处理) View(视图) Controller(控制器请求和响应,业务分发页面跳转)的简称,是一种软件设计典范,目的是将业务逻辑、数据、页面视图代码分离,降低耦合。
2 什么是SpringMVC
表示层的MVC框架,是Spring的子框架。
3 SpringMVC运行原理
(1)接收用户的http请求,前端控制器DispatcherServlet根据请求进行调度处理;
(2)DispatcherServlet根据请求找到对应的处理器映射器HandlerMapping;
(3)HandlerMapping把请求和Handler之间进行映射,返回一个Handler给DispatcherServlet;
(4)DispatcherServlet根据获得的Handler选择一个合适的处理器适配器HandlerAdapter;
(5)HandlerAdapter调用处理器Handler进行相应的数据处理;
(6)Handler处理完数据后将结果返回给HandlerAdapter;
(7)HandlerAdapter向DispatcherServlet返回一个ModerAndView对象;
(8)DispatcherServlet根据返回的ModelAndView对象,选择一个合适的视图解析器ViewResolver;
(9)ViewResolver结合Model和View来渲染视图,并返回给DispatcherServlet;
(10)DispatcherServlet响应用户的请求。
4 SpringMVC中几个重要的类
(1)ContextLoaderListener类:
这是一个监听类,在tomcat启动后创建一个IOC容器,并将创建的IOC容器存到servletContext中。
(2)DispatcherServlet类:
是SpringMVC的入口,DispatcherServlet类主要负责任务的调度,用于控制流程。DispatcherServlet类本身也是一个Servlet
(3)HandlerMapping接口:
根据前端控制器的请求找到一个处理器Handler。维持了一个url到Controller关系的Map结构。根据request来获得HandlerExecutionChain,获取真正要执行的Controller或者某个具体的方法。HandlerMapping接口提供唯一的方法getHandler(HttpServletRequest request)。
(4)ViewResolver接口:
把一个逻辑上的视图名称解析为一个真正的视图。
5 案例(基于xml)
web.xml配置:对前端控制器进行配置,并修改默认加载路径
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
<display-name>springmvc</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 前端控制器配置,处理所有*.do结尾的请求
默认加载配置文件路径:/WEB-INF/[servletname]-servlet.xml
修改加载配置文件的路径:DispatcherServlet类里面有一个key-value的键值对:contextConfigLocation:配置文件加载路径
-->
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:SpringMVC.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>*.do</url-pattern><!-- *.do结尾的请求才进行处理 -->
</servlet-mapping>
</web-app>
SpringMVC.xml配置文件:配置处理器映射器,处理器适配器,创建处理器,配置视图解析器
<?xml version="1.0" encoding="UTF-8"?>
<!-- schema约束 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 3. 创建处理器(后端映射器)handler的对象 -->
<bean id="handsomecontroller" name="/handSome.do"
class="controller.HandSomeController"></bean>
<!-- 1. 处理器映射器: url(请求)在handler对象之间建立映射关系 handSome.do请求和handsomecontroller对象建立映射关系
如果url和handler对象的name一致则映射成功 -->
<bean
class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
<!-- 2. 处理器适配器:调用handler的对象 -->
<bean
class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
<!-- 4. 视图解析器 视图名称找到物理视图 show /show.jsp
prefix+viewname+suffix
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="handSome.do">好帅</a>
</body>
</html>
后端控制器(处理器):需要实现Controller
package controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
/**
* @Description 后端控制器,处理handSome.do
* @author refuel
* @version v1.0
*/
public class HandSomeController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("接收到请求");
ModelAndView mv = new ModelAndView();
//数据
mv.addObject("msg","好漂亮");
//视图 show---> /show.jsp
mv.setViewName("show");
return mv;
}
}
6 案例(基于注解)
web.xml配置文件:对前端控制器进行配置,并修改默认加载路径
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
<display-name>springmvc02</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:SpringMVC.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
SpringMVC.xml配置文件:配置扫描Controller包,设置适配器和映射器的注解生效,配置视图解析器
<?xml version="1.0" encoding="UTF-8"?>
<!-- schema约束 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="controller"></context:component-scan>
<!-- 让requestMapping生效(适配器和映射器生效),支持json交互 -->
<mvc:annotation-driven></mvc:annotation-driven>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="hello.do">ni hao</a>
</body>
</html>
处理器类
package controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @Description 后端控制器 hello要和对象的方法进行关联要先有对象
* (1)@Controller @Controller创建需要context(2)方法上加@RequestMapping 需要mvc实现映射
* @author refuel
* @version v1.0
*/
@Controller
public class HelloController {
//处理hello.dao请求
//返回值:视图名称
@RequestMapping("/hello.do")
public String sayHi() {
System.out.println("接收到请求");
return "show";
}
}
7 SpringMVC参数封装相关
7.1 参数封装
(1)简单数值类型封装
请求参数名称和方法参数名称一致,则可直接封装。
(2)对象类型数据封装
请求参数名称和对象属性名称一致,则可封装。
(3)数组类型封装
请求参数名称和数组名称一致,则可封装。
(4)list或map集合
需要作为对象的属性存在,只要和请求参数的名称一致,则可封装·
7.2 数据回显
使用model对象,和request的使用方法一致。
7.3 转发和重定向
forward:请求: 转发; redirect:请求 : 重定向;在return返回视图名称的前面加上forward:或redirect:
7.4 编码处理
在web.xml中进行配置
7.5 封装、回显、转发、重定向、编码处理案例(注解方式)
web.xml配置文件:配置前端控制器和过滤器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
<display-name>springmvc03</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 前端控制器 -->
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:SpringMVC.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!-- 配置过滤器 -->
<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>
</web-app>
SpringMVC..xml配置文件:扫描controller包,使适配器和映射器生效,配置视图解析器
<?xml version="1.0" encoding="UTF-8"?>
<!-- schema约束 -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 扫描包 -->
<context:component-scan base-package="controller"></context:component-scan>
<!-- 让requestMapping生效(适配器和映射器生效),支持json交互 -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 解析视图 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="login.do" method="post">
用户名:<input type="text" name="user" id="user"><br />
密码:<input type="text" name="pwd" id="pwd"><br />
<!-- 爱好:
<input type="checkbox" name="hobby" value="book">跑步
<input type="checkbox" name="hobby" value="eat">吃饭
<input type="checkbox" name="hobby" value="sleep">学习<br />
备注1:
<input type="text" name="list[0]" >
<input type="text" name="list[1]" >
<input type="text" name="list[2]" ><br />
备注2:
<input type="text" name="map[name]" >
<input type="text" name="map[age]" ><br /> -->
<input type="submit" value="登录">
</form>
</body>
</html>
User实体类
package entity;
import java.util.List;
import java.util.Map;
public class User {
private String user;
private String pwd;
private List list;
private Map map;
public User() {
super();
}
public User(String user, String pwd) {
super();
this.user = user;
this.pwd = pwd;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
@Override
public String toString() {
return "User [user=" + user + ", pwd=" + pwd + ", list=" + list + ", map=" + map + "]";
}
}
处理器类
package controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class UserController {
// @RequestMapping("/login.do")
// //在请求的时候已经封装到了request,所以可以传参进来用
// public String login(HttpServletRequest request) {
// //.获取参数
// String user = request.getParameter("user");
// String pwd = request.getParameter("pwd");
// //根据返回值实现页面跳转
// return "show";
// }
// @RequestMapping("/login.do")
// //是通过getParameter进行了底层的封装
// public String login(String user,String pwd) {
// //获取参数
// System.out.println();
// //根据返回值实现页面跳转
// return "show";
// }
// @RequestMapping("/login.do")
// //直接封装到对象
// public String login(User user) {
// //.获取参数
// System.out.println();
// // 根据返回值实现页面跳转
// return "show";
// }
// @RequestMapping("/login.do")
// //直接封装到数组
// public String login(String[] hobby) {
// //获取参数
// System.out.println(Arrays.toString(hobby));
// //根据返回值实现页面跳转
// return "show";
// }
// @RequestMapping("/login.do")
// //封装集合到对象
// public String login(User user,Model model) {
// //获取参数
// System.out.println(user);
// //根据返回值实现页面跳转
// // model.addAttribute("msg",user);
// return "show";
// }
// @RequestMapping("/login.do")
//
// public String login(String user,String pwd,Model model) {
// System.out.println("a");
// if(user.equals("aa") && "123".equals(pwd)) {
// System.out.println("b");
// return "show";
// }
//
// model.addAttribute("msg",user+pwd);
// System.out.println("c");
// return "index";
// }
//表示层都是以请求的方式调用,不能创建对象调用,在service,dao层才能那么调用,因为是后台的
//这个controller只处理和用户相关的
@RequestMapping("/first.do")
public String first() {
System.out.println("first");
return "forward:second.do";
//forward:转发 redirect:重定向
}
//这个controller
@RequestMapping("/second.do")
public String second() {
System.out.println("second");
return "show";
}
}