SpringMVC笔记

SpringMVC 原理图:

  1. 用户访问 /index
  2. 根据web.xml中的配置 所有的访问都会经过DispatcherServlet
  3. 根据 根据配置文件springmvc-servlet.xml ,访问路径/index
    会进入IndexController类
  4. 在IndexController中指定跳转到页面index.jsp,并传递message数据
  5. 在index.jsp中显示message信息

原理图

DispatcherServlet:前端控制器设计模式的实现,提供Spring Web MVC的集中访问点,而且负责职责的分派,而且与Spring IoC容器无缝集成,从而可以获得Spring的所有好处。
DispatcherServlet主要用作职责调度工作,本身主要用于控制流程,主要职责如下:
1、文件上传解析,如果请求类型是multipart将通过MultipartResolver进行文件上传解析;
2、
通过HandlerMapping,将请求映射到处理器(返回一个HandlerExecutionChain,它包括一个处理器、多个HandlerInterceptor拦截器)

3、通过HandlerAdapter支持多种类型的处理器(HandlerExecutionChain中的处理器);
4、通过ViewResolver解析逻辑视图名到具体视图实现;
5、本地化解析;
6、渲染具体的视图等;
7、如果执行过程中遇到异常将交给HandlerExceptionResolver来解析。工作流程

1.在WEB-INF目录下创建 web.xml
—配置Spring MVC的入口 DispatcherServlet,把所有的请求都提交到该Servlet。

<?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"
	id="WebApp_ID" version="3.1">
	<servlet>
		<servlet-name>SpringMVC</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>SpringMVC</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>
<!--load-on-startup:表示启动容器时初始化该Servlet;-->
<!--url-pattern:表示哪些请求交给Spring Web MVC处理, “/” 是用来定义默认servlet映射的。也可以如“*.html”表示拦截所有以html为扩展名的请求。-->

2.WEB-INF目录下创建springmvc-servlet.xml
文件名与web.xml中的<servlet-name>对应,因为这是Spring MVC的 映射配置文件;表示访问路径/index会交给id=indexController的bean处理,id=indexController的bean配置为类:IndexController;

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
	<bean id="simpleUrlHandlerMapping"
	class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="mappings">
			<props>
				<prop key="/index">indexController</prop>
			</props>
		</property>
	</bean>
	<bean id="indexController" class="controller.IndexController" />
</beans>

3.控制类 IndexController实现接口Controller
提供方法handleRequest处理请求,
SpringMVC通过 ModelAndView 对象把模型和视图结合在一起;

public class IndexController implements Controller {
	@Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {

		ModelAndView mav = new ModelAndView("index.jsp");
		mav.addObject("message", "hello Spring MVC");
		// 模型数据是 message,内容是 “Hello Spring MVC”
		return mav;
	}
}

4.在WebContent目录下创建index.jsp
index.jsp,通过EL表达式显示message的内容

<h1>${message}</h1>

5.部署在Tomcat中,重启tomcat,然后访问地址。
这里写图片描述

视图定位:
如果代码写成这样,就表示跳转到页面 index.jsp
new ModelAndView(“index.jsp”);
所谓的视图定位,指的是代码还是写成这样,但是会跳转到
/WEB-INF/page/index.jsp
new ModelAndView(“index”);
作用:不是所有的视图都会使用jsp来做,还可以是JSF,html 等其他的方式。使用视图定位,如果要把视图从index.jsp改为index.html,就不需要修改代码,而只需要修改配置文件即可。
另一个便利之处在于,如果要批量修改视图文件所处于的位置,按照以前的办法,也需要对每个类逐一修改,工作量大,容易出错。 而使用这种方式,维护成本就小多了。

1.修改springmvc-servlet.xml

<bean id="viewResolver"	class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/page/" />
		<property name="suffix" value=".jsp" />
	</bean>
<!--作用:把视图约定在 /WEB-INF/page/*.jsp 这个位置-->

2.修改IndexController
改这行代码

ModelAndView mav = new ModelAndView("index");

3.移动index.jsp
在WEB-INF下新建目录page
把index.jsp移动到 WEB-INF/page 目录下

4.测试,完成

注解的方式:
1.修改IndexController

//2.注解方式:表示该类是一个控制器
@Controller
public class IndexController /* implements Controller 第一种方式 */ {
	// 表示路径/index会映射到该方法上
	@RequestMapping("/index")
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {

		ModelAndView mav = new ModelAndView("index");
		mav.addObject("message", "hello Spring MVC");
		// 模型数据是 message,内容是 “Hello Spring MVC”
		return mav;
	}
}

2.修改springmvc-servlet.xml
去掉映射相关的配置;

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context        
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <context:component-scan base-package="controller"/>
	<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/page/" />
		<property name="suffix" value=".jsp" />
	</bean>
</beans>

3.测试,结果一样。

1. 接收表单数据

  1. 准备实体类
public class Student {
	private int id;
	private String name;
	private String address;
	}
  1. 新建addStudent.jsp(webContext目录下)
<form action="addStudent">
	姓名:<input type="text" name="name" value="">
	住址:<input type="text" name="address" value="">

	<input type="submit" value="增加学生信息">
</form>
  1. 新建控制器StudentController
    控制器StudentController,准备一个add方法映射/addStudent路径
    为add方法准备一个Student参数,用于接收注入
    最后跳转到showStudent页面显示用户提交的数据
@Controller
public class StudentController {
	
	@RequestMapping("/addStudent")
	public ModelAndView add(Student student) throws Exception {
		ModelAndView mav = new ModelAndView("showStudent");
		return mav;
	}
}
  1. 创建 showProduct.jsp(WEB-INF/page)
	姓名: ${student.name}<br>
	住址: ${student.address}
  1. 测试,完成。

2. 客户端跳转
修改IndexController
映射/jump到jump()方法

@RequestMapping("/jump")
	public ModelAndView jump() {
		ModelAndView mav=new ModelAndView("redirect:/index");
		//表示客户端跳转
		return mav;
	}

Session
在用户登录,一些特殊场合在页面间传递数据的时候会经常用到
修改IndexController
映射 /check 到方法check()

@RequestMapping("/check")
	public ModelAndView check(HttpSession session) {
		Integer i = (Integer) session.getAttribute("count");
		if (i == null)
			i = 0;
		i++;
		session.setAttribute("count", i);
		ModelAndView mav = new ModelAndView("check");
		return mav;

	}

check.jsp文件

session中记录的访问次数:${count}

中文处理:

修改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>

修改addStudent.jsp为form 设置method=“post”

SPRING MVC 拦截器
1.拦截器类:IndexInterceptor

public class IndexInterceptor extends HandlerInterceptorAdapter {
	
	/** 
     * 在业务处理器处理请求之前被调用 
     * 如果返回false 
     *     从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链
     * 如果返回true 
     *    执行下一个拦截器,直到所有的拦截器都执行完毕 
     *    再执行被拦截的Controller 
     *    然后进入拦截器链, 
     *    从最后一个拦截器往回执行所有的postHandle() 
     *    接着再从最后一个拦截器往回执行所有的afterCompletion() 
     */ 
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("preHandle(), 在访问Controller之前被调用");
		return true;
	}
	
	 /**
     * 在业务处理器处理请求执行完成后,生成视图之前执行的动作   
     * 可在modelAndView中加入数据,比如当前时间
     */ 
	

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("postHandle(), 在访问Controller之后,访问视图之前被调用,这里可以注入一个时间到modelAndView中,用于后续视图显示");
		modelAndView.addObject("date", "由拦截器生成的时间:" + new Date());
	}

	/** 
     * 在DispatcherServlet完全处理完请求后被调用,可用于清理资源等  
     *  
     * 当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion() 
     */
	
	
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("afterCompletion(), 在访问视图之后被调用");
	}
}

2.配置拦截器
springmvc-servlet.xml以对/index路径进行拦截

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
     http://www.springframework.org/schema/context 
     http://www.springframework.org/schema/context/spring-context-3.0.xsd 
     http://www.springframework.org/schema/mvc
     http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
	<bean id="viewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/page/" />
		<property name="suffix" value=".jsp" />
	</bean>

	<bean id="multipartResolver"
		class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
	<!-- 开放对上传功能的支持代码比较 复制代码 -->

	<bean id="simpleUrlHandlerMapping"
		class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="mappings">
			<props>
				<prop key="/index">indexController</prop>
			</props>
		</property>
	</bean>
	<bean id="indexController" class="controller.IndexController" />

	<mvc:interceptors>
		<mvc:interceptor>
			<mvc:mapping path="/index" />
			<!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 -->
			<bean class="interceptor.IndexInterceptor" />
		</mvc:interceptor>
		<!-- 当设置多个拦截器时,先按顺序调用preHandle方法, 然后逆序调用每个拦截器的postHandle和afterCompletion方法 -->
	</mvc:interceptors>

</beans>

3.修改 index.jsp

<p>${date }</p><!--打印时间方便观察-->
posted @ 2018-02-25 23:22  小沐酱  阅读(1)  评论(0编辑  收藏  举报  来源