※. SpringMVC框架在项目中的搭建
第一步:构建Web项目(Dynamic Web Project)
第二步:导入所需jar包
第三步:配置前端控制器DispatcherServlet
第四步:编写Controller控制器(也称为Handler处理器)
第五步:配置处理器映射器(可省去,有默认配置)
第六步:配置处理器适配器(可省去,有默认配置)
第七步:配置视图解析器(可省去,有默认配置,但是前缀和后缀都为"")
第八步:配置处理器
1)构建Web项目
在自己Eclipse中创建一个动态web项目(DynamicWebProject),注意JDK版本和项目版本的选择
2)导入所需的jar包
在lib目录下放入如下jar包,这是初始jar包,根据后续需求会陆续加入jar包
commons-logging-1.2.jar
spring-beans-5.0.10.RELEASE.jar
spring-aop-5.0.10.RELEASE.jar
spring-context-5.0.10.RELEASE.jar
spring-core-5.0.10.RELEASE.jar
spring-expression-5.0.10.RELEASE.jar
spring-web-5.0.10.RELEASE.jar
spring-webmvc-5.0.10.RELEASE.jar
※ 3)配置前端控制器DispatcherServlet
SpringMVC的核心控制器就是一个Servlet对象,继承自HttpServlet,
所以需要在web.xml文件中配置。
SpringMVC是Spring提供的一个模块,Spring所有的模块都是基
于Spring IOC功能的。所以SpringMVC的DispatcherServlet对象在初始
化之前也会去实例化Spring的容器对象(ApplicationContext),那么就需要
读取Spring的配置文件。默认SpringMVC会在你web应用的WEB-INF目录下
查找一个名字为[servlet-name]-servlet.xml文件,并且创建在这个文件
中定义的bean对象。如果你提供的spring配置文件的名字或者位置和默认
的不同,那么需要在配置servlet时同时指定配置文件的位置。
例如:
<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>*.action</url-pattern>
</servlet-mapping>
如上配置,框架会自动去当前应用的WEB-INF目录下查找名字为SpringMVC-servlet.xml文件(默认前缀和<servlet-name>标签中的值一致)。
也可以自己指定配置文件的名字和位置:
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-web-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
注意:
配置文件在WEB-INF下:
<param-value>/WEB-INF/spring-web-mvc.xml</param-value>
配置文件在classpath下:
<param-value>classpath:spring-web-mvc.xml</param-value>
注意:
<url-pattern>*.action</url-pattern>
也可以配置成 注意这里是/ 不是/*
<url-pattern>/</url-pattern>
例:
<?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">
<display-name>jd1812_MVC</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>
<!-- 让tomcat中的default对静态的资源进行处理
(前端控制器不在拦截),有多少静态资源配置多
少个,还和tomcat的版本有关系 -->
<!-- <servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.png</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping> -->
<!-- 编码的设置,给request和response设置
编码 -->
<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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置前端控制器的时候,需要加载
spring的配置文件
1.默认的spring文件的名字 [servlet-name]-servlet.xml
SpringMVC-servlet.xml
位置在WEB-INF中
2. 配置文件路径初始化参数,指定spring配置文件的
位置,名子没有要求,路径自定义,可以指定
加载多个spring配置文件-->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 指定加载xml文件的路径
如果有多个路径中间空格隔开
eg:
<param-value>
classpath:spring.xml
classpath:service.xml
classpath:dao.xml
</param-value>
注意,指定了spring的路径,默认的spring配置文件
不在生效
-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<!-- /* 能处理浏览器的请求,但是会对返回的资源
(XX.jsp等)
进行再一次拦截(页面获取不到内容),
/表示对页面不处理 html jsp,但是像静态的资源
(xx.js,xxx.css,xxx.png,xxx.jpg)
也会被拦截 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--SpringMVC-servlet.xml
WEB-INF
-->
<!-- <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>*.do</url-pattern>
</servlet-mapping> -->
</web-app>
WEB-INF下的SpringMVC-servlet.xml(名字与web.xml文件name属性有关)
<?xml version="1.0" encoding="UTF-8"?>
<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">
<!-- 配置映射器 ,指明类url和处理请求
类的对象对应规则
<bean name="hello.do" class="com.briup.web.controller.FirstController">
-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!-- 适配器,默认,控制器实现了接口controller
里面有重写方法的时候配置SimpleControllerHandlerAdapter -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!-- 配置视图解析器
viewClass表示视图处理会用jstl标签库
prefix表示对逻辑视图拼接的前缀
suffix表示对逻辑视图拼接的后缀
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 处理器 -->
<bean name="/hello.do" class="com.briup.web.controller.FirstController"></bean>
</beans>
4)编写Controller控制器
Controller控制器,是MVC中的部分C,因为此处的控制器主要负责功能处理部分:
1、收集、验证请求参数并封装到对象上;
2、将对象交给业务层,由业务对象处理并返回模型数据;
3、返回ModelAndView(Model部分是业务层返回的模型数据,视图部分为逻辑视图名)。
前端控制器(DispatcherServlet)主要负责整体的控制流程的调度部分:
1、负责将请求委托给控制器进行处理;
2、根据控制器返回的逻辑视图名选择具体的视图进行渲染(并把模型数据传入)。
因此MVC中完整的C(包含控制逻辑+功能处理)由(DispatcherServlet + Controller)组成。
Controller接口中只有一个需要实现的方法就是handleRequest方法,方法中接收两个参数,
分别对应Servlet对象中的request,response对象。可以从request中获取客户端提交过来的请求参数。
返回值ModelAndView,既包含要返回给客户端浏览器的逻辑视图又包含要对视图进行渲染的数据模型。
例如:
public class HelloWorldController implements Controller{
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
String name = request.getParameter("name");
//ModelAndView对象中包括了要返回的逻辑视图,以及数据模型
ModelAndView mv = new ModelAndView();
//设置逻辑视图名称
mv.setViewName("hello");
//设置数据模型
mv.addObject("name", name);
return mv;
}
}
例:
控制器:同Servlet(src下com.briup.web.controller.FirstController.java)
package com.briup.web.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
/*
* 控制器:处理浏览器请求
* 回写ModelAndView对象
*/
public class FirstController
implements Controller{
@Override
public ModelAndView
handleRequest(HttpServletRequest req, HttpServletResponse res) throws Exception {
String name=req.getParameter("name");
System.out.println("name:"+name);
ModelAndView mv=
new ModelAndView();
//设置视图hello
mv.setViewName("hello");
//如果没有视图解析器,
//必须写物理视图(具体资源路径)的名字
//mv.setViewName("/WEB-INF/jsp/hello.jsp");
//设置内容
mv.addObject("name", name);
return mv;
}
}
构建页面(服务器内部可以访问WEB-INF下的jsp)(安全性:防止浏览器访问到)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<base href="<%=basePath %>">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
<script type="text/javascript" src="js/test.js">
</script>
<link type="text/css" rel="stylesheet" href="css/test.css">
</head>
<body>
<!--onclick 鼠标左键点击事件
test() 函数或方法
-->
<div onclick="test()"></div>
success:${name}
<br>
<img src="images/1.png">
</body>
</html>
css样式:test.css
div{
width: 100px;
height: 100px;
border: 1px solid red;
background-color: blue;
}
js:test.js
function test(){
alert("111");
}
5)配置映射器(可省去,有默认配置)
注意:如果xml文件不能自动提示,那么可以在Eclipse中把schame配置过来即可,
schame文件也在下载的spring的压缩包中
Spring容器需要根据映射器来将用户提交的请求url和后台Controller/Handler进行绑定,所以需要配置映射器。
例如:
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
BeanNameUrlHandlerMapping:表示将请求的URL和Bean名字映射,如URL为 "/hello",则Spring配置文件必须有一个名字为"/hello"的Bean.
注意:这里/代表的含义是url中项目名后面的/
例:src整个项目下
<?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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
">
<!-- 配置映射器 ,指明类url和处理请求
类的对象对应规则
http://localhost:8888/jd1812_MVC/hello.do
<bean name="/hello.do" class="com.briup.web.controller.FirstController">
-->
<bean name="myInterceptor"
class="com.briup.web.Interceptor.defineInterceptor"></bean>
<!-- 一旦自定义了拦截器,
映射器就不能省略 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
<!-- 配置拦截器
,在映射器中配置的拦截器,对
所有的controller处理器生效
interceptors List<Object>
-->
<property name="interceptors">
<array>
<ref bean="myInterceptor"/>
</array>
</property>
</bean>
<!-- 适配器,默认,控制器实现了接口controller
里面有重写方法的时候配置SimpleControllerHandlerAdapter -->
<bean class="com.briup.web.adapter.DefineAdapter"></bean>
<!-- <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
配置视图解析器
viewClass表示视图处理会用jstl标签库
prefix表示对逻辑视图拼接的前缀
suffix表示对逻辑视图拼接的后缀
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 处理忽略静态的资源
imgaes/* 对应的如 images/1.png 匹配不了
images/test/1.png
imgaes/** 匹配images下的所有资源 images/1.png
images/test/1.png
mapping指向拦截的资源名字匹配
location表示资源存储的位置
/images/ eg:WebContent下的images文件下的内容
-->
<!-- <mvc:resources mapping="/images/**" location="/images/"/>
<mvc:resources mapping="/js/**" location="/js/"/>
<mvc:resources mapping="/css/**" location="/css/"/> -->
<!-- 默认忽略静态资源 -->
<mvc:default-servlet-handler/>
<!-- 处理器 -->
<bean name="/hello.do" class="com.briup.web.controller.FirstController"></bean>
<bean name="/four"
class="com.briup.web.adapter.FourController"></bean>
<bean name="/third"
class="com.briup.web.controller.ThirdController">
<!-- <property name="synchronizeOnSession"
value="true"></property> -->
<!--本次请求支持提交的方式 -->
<!-- <property name="supportedMethods" value="POST,GET">
</property> -->
<!-- 本次请求,服务器必须给当前浏览器
构建过session 会话,没有session直接报错
-->
<!-- <property name="requireSession"
value="true"></property> -->
<!-- (-1)表示默认,缓存上次的内容
0 表示直接不缓存
正数,表示缓存,缓存时间的设置
-->
<property name="cacheSeconds" value="0"></property>
</bean>
<bean name="/second"
class="com.briup.web.controller.SecondController"></bean>
<bean name="/five"
class="com.briup.web.controller.FiveController"></bean>
</beans>
6)配置适配器(可省去,有默认配置)
想要正确运行自定义处理器,需要配置处理器适配器,在spring的配置文件中
(就是本例中的SpringMVC-servlet.xml),进行如下配置:
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
SimpleControllerHandlerAdapter:表示所有实现了org.springframework.web.servlet.mvc.Controller
接口的Bean可以作为SpringMVC中的处理器。如果需要其他类型的处理器可以通过实现HadlerAdapter来解决。
7)配置视图解析器(可省去,有默认配置,但是前缀和后缀都为"")
当处理器执行完成后,返回给spring容器一个ModelAndView对象,这个对象需要能够被解析成与之相对应的视图,并且使用返回的Model数据对视图进行渲染。
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
如果配置设置为如上操作,那么在自定义的Handler中返回的视图的名字不能有后缀.jsp,并且页面一定放在/WEB-INF目录下。
InternalResourceViewResolver:用于支持Servlet、JSP视图解析;
viewClass:JstlView表示JSP模板页面需要使用JSTL标签库,classpath中必须包含jstl的相关jar包;
prefix和suffix:视图页面的前缀和后缀(前缀+逻辑视图名+后缀),比如传进来的逻辑视图名为hello,则该该jsp视图页面应该存放在"WEB-INF/jsp/hello.jsp"
注意:放在WEB-INF下的页面,只能通过内部跳转的方式访问到,因为客户端访问不到WEB-INF目录,而且服务器端可以访问到WEB-INF目录
注意:需要引入jstl相关jar包
注意:页面中的路径问题
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<base href="<%=basePath%>" />
8)配置处理器
把编写好的handler/controller在spring中进配置,让其接受Spring IoC容器管理
<bean name="/hello.action" class="com.briup.web.controller.HelloWorldController"/>
注意: 对于Spring配置文件中的处理器适配器,处理器映射器,都可以省去不写,springMVC框架中会有默认配置的,视图解析器也可以不配置,因为在org.springframework.web.servlet.DispatcherServlet这个类的同包下,有一个DispatcherServlet.properties文件,里面就是SpringMVC默认的配置,是当用户的Spring配置文件中没有指定配置时使用的默认策略(你不配置那么用户默认的,你配置了,那么就使用你的配置)
从默认的配置中可以看出DispatcherServlet在启动时会自动注册这些特殊的Bean,无需我们注册,如果我们注册了,默认的将不会注册。
因此之前的BeanNameUrlHandlerMapping、SimpleControllerHandlerAdapter是不需要注册的,DispatcherServlet默认会注册这两个Bean。
整个访问的流程:
1、 首先用户发送请求,前端控制器DispatcherServlet收到请求后自己不进行处理,而是委托给其他的解析器进行处理,前端控制器作为统一访问点,进行全局的流程控制;
2、 DispatcherServlet把请求转交给HandlerMapping, HandlerMapping将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器对象、多个HandlerInterceptor拦截器)对象.(后面会学习到拦截器)
3、 DispatcherServlet再把请求转交给HandlerAdapter,HandlerAdapter将会把处理器包装为适配器,从而支持多种类型的处理器(适配器模式).简单点说就是让我们知道接下来应该调用Handler处理器里面的什么方法
4、 HandlerAdapter将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView对象(包含模型数据、逻辑视图名);
5、 ModelAndView的逻辑视图名交给ViewResolver解析器, ViewResolver解析器把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;
6、 View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构,因此很容易支持其他视图技术;
7、最后返回到DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。