二、SpringMVC 入门
2.1 搭建SpringMVC的项目
2.1.1 创建一个WEB项目
2.1.2 导入Spring的jar包
其中spring-webmvc-4.3.18.RELEASE.jar为SpringMVC的核心jar包。
方式一:引入jar包
方式二:maven依赖配置
<dependencies>
<!-- spring核心包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springbean包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springcontext包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- spring表达式包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springAOP包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springAspects包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- spring对web的支持 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- springwebMVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- 配置javaweb环境 -->
<!-- servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<!-- jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
2.1.3 配置前端控制器
Spring MVC 是基于 Servlet 的,DispatcherServlet 是整个 Spring MVC 框架的核心,主要负责截获请求并将其分派给相应的处理器处理。所以配置 Spring MVC,首先要定义 DispatcherServlet。跟所有 Servlet 一样,用户必须在 web.xml 中进行配置。
Spring MVC 初始化时将在应用程序的 WEB-INF 目录下查找配置文件,该配置文件的命名规则是“servletName-servlet.xml”,例如 springmvc-servlet.xml。
也可以将 Spring MVC 的配置文件存放在应用程序目录中的任何地方,但需要使用 servlet 的 init-param 元素加载配置文件,通过 contextConfigLocation 参数来指定 Spring MVC 配置文件的位置,示例代码如下。
在web.xml中配置前端控制器:
<?xml version="1.0" encoding="UTF-8"?>
<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_4_0.xsd"
version="4.0">
<!-- 1、配置前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--
springmvc的核心配置文件,格式与spring的applicationContext.xml一致
默认路径:/WEB-INF/[前端控制器Servlet的名称]-servlet.xml
4、自定义springmvc配置文件的名称和位置:
通过Servlet的初始化参数,修改springmvc的配置文件的路径和名称
-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!-- 3、配置服务器启动时初始化前端控制器-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--
2、配置进入Spring MVC的请求
第一种:*.后缀名,表示由DispatcherServlet进行解析以某种扩展名结尾的请求路径。
例如:*.do,*.action,*.abc..但是不能配置*.jsp,*.css,*.js等视图类型的后缀或静态资源后缀
优点:不会导致静态资源的拦截(静态资源的访问不会进入springmvc的流程),无需单独排除静态资源
缺点:不支持RESTful风格的开发
第二种:/,表示所有的访问服务器的路径都进入Spring MVC的流程中(.jsp文件除外)。
优点:支持RESTful风格的开发
缺点:当访问静态资源时,因没有相应的处理类,会报出404的错误,需要单独排除静态资源
注意:/*,此种在Spring MVC中是错误的配置,因为它会拦截所有的静态资源,以及jsp文件。
-->
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
配置解析:
contextConfigLocation:指定springmvc配置的加载位置,如果不指定,默认加载的是/WEB-INF/[servlet名称]-serlvet.xml。例如:springmvc-servlet.xml。
url-pattern:请交给DispatcherServlet处理的请求路径。
第一种:\*.do,由DispatcherServlet进行解析以某种扩展名结尾的路径,不会导致静态资源(jpg,js,css)被拦截。
第二种:/,所以访问的地址都由DispatcherServlet进行解析,对于静态文件的解析需要配置不让DispatcherServlet进行解析。使用此种方式可以实现RESTful风格的url。
第三种:/*,这样配置不对,使用这种配置,最终要转发到一个jsp页面时,仍然会由DispatcherServlet解析jsp地址,不能根据jsp页面找到handler,会报错。
2.1.4 配置处理器映射器
在springmvc配置文件中配置处理器映射器:
<?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:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置处理器映射器 -->
<!--
所有的处理器映射器都实现HandlerMapping接口
BeanNameUrlHandlerMapping:根据处理器bean标签中name属性值来与请求路径匹配查找相应的处理器对象
-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
</beans>
2.1.5 配置处理器适配器
<!-- 配置处理器适配器 -->
<!--
所有的处理器适配器都实现HandlerAdapter接口
SimpleControllerHandlerAdapter:要求在编写处理器时,必须实现org.springframework.web.servlet.mvc.Controller接口
-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
通过查看原代码:
public class SimpleControllerHandlerAdapter implements HandlerAdapter {
public SimpleControllerHandlerAdapter() {
}
public boolean supports(Object handler) {
return handler instanceof Controller;
}
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return ((Controller)handler).handleRequest(request, response);
}
public long getLastModified(HttpServletRequest request, Object handler) {
return handler instanceof LastModified ? ((LastModified)handler).getLastModified(request) : -1L;
}
}
此适配器能执行实现org.springframework.web.servlet.mvc.Controller接口的Handler。
2.1.6 开发Handler
需要实现Controller接口,才能由SimpleControllerHandlerAdapter适配器执行:
/**
* 处理器:用于请求处理
*
* 问题:
* 1.依赖Spring API的处理器
* 2.每个处理器仅能处理一个请求
*/
public class HelloWorldController implements Controller {
/**
* 处理请求的方法
* @param request 原生的请求对象
* @param response 原生的响应对象
* @return 模型与视图对象
* @throws Exception
*/
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("Hello Springmvc.....");
//创建ModelAndView对象
ModelAndView modelAndView = new ModelAndView();
//设置数据(相当于将数据存放到域对象中,request域)
modelAndView.addObject("message", "Hello Springmvc");
//设置视图(相当于进行请求转发的页面路径)
modelAndView.setViewName("/success.jsp");
return modelAndView;
}
}
ModelAndView:包含了模型数据及视图名。
2.1.7 配置Handler
将Handler对象交给SpringIOC容器管理:
<!-- 配置处理器-->
<bean name="/helloworld.do" class="com.newcapec.controller.HelloWorldController"/>
其中bean的name属性值作为请求url,路径以斜杠开头;
2.1.8 配置视图解析器
<!-- 视图解析器 -->
<!--
所有的视图解析器都实现ViewResolver接口
InternalResourceViewResolver:JSP视图的解析器
-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"/>
2.1.9 视图编写
index.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Title</title>
</head>
<body>
<div style="text-align: center;">
<h1>首页</h1>
<p><a href="helloworld.do">测试helloworld</a></p>
</div>
</body>
</html>
success.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Title</title>
</head>
<body>
<div style="text-align: center;">
<h1>跳转成功页面</h1>
<div style="color:red;">${message}</div>
</div>
</body>
</html>
2.2 非注解的处理器映射器和适配器
2.2.1 非注解的处理器映射器
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,在配置handler时,bean标签的name属性上配置该处理器在被访问时对应的url。
org.springframework.web.servlet.handler.SimpleUrlHandlerMapping,根据处理器bean标签中id属性值与请求路径匹配查找相应的处理器对象,一个处理器对象可对应多个请求路径。
<!--
SimpleUrlHandlerMapping:
根据处理器bean标签中id属性值与请求路径匹配查找相应的处理器对象,一个处理器对象可对应多个请求路径
-->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<!-- 请求路径的url为key,处理器bean的id为value-->
<prop key="/hello.do">helloController</prop>
<prop key="/hello.action">helloController</prop>
</props>
</property>
</bean>
注意:在同一个项目中,多个映射器可以并存,前端控制器判断url能让哪些映射器映射,就让正确的映射器处理。
2.2.2 非注解的处理器适配器
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,要求编写的Handler实现Controller接口。
org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,要求编写的handler必须实现org.springframework.web.HttpRequestHandler接口。
<!--
HttpRequestHandlerAdapter:
要求在编写处理器时,必须实现HttpRequestHandler接口
-->
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
2.2.3 处理器
代码:
public class HelloController implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
System.out.println("HelloController执行了....");
httpServletRequest.setAttribute("message", "hello");
//重定向
// httpServletResponse.sendRedirect("/success.jsp");
//请求转发
httpServletRequest.getRequestDispatcher("/success.jsp").forward(httpServletRequest, httpServletResponse);
}
}
配置:
<bean id="helloController" class="com.newcapec.controller.HelloController"/>
2.2.4 视图编写
index.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Title</title>
</head>
<body>
<div style="text-align: center;">
<h1>首页</h1>
<p><a href="helloworld.do">测试helloworld</a></p>
<p><a href="hello.do">测试hello.do</a></p>
<p><a href="hello.action">测试hello.action</a></p>
</div>
</body>
</html>
2.3 SpringMVC的默认配置
在org.springframework.web.servlet包下存在一个DispatcherServlet.properties资源文件。
前端控制器从此属性文件中加载处理器映射器、处理器适配器、视图解析器等组件,如果不在springmvc.xml中配置,使用默认加载的。
2.4 注解的处理器映射器和适配器
2.4.1 与默认配置中不同的处理器映射器和适配器
在spring3.1之前使用:
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping注解处理器映射器。
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter注解处理器适配器。
在spring3.1之后使用:
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping注解处理器映射器。
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter注解处理器适配器。
2.4.2 组件扫描
<!-- springmvc的注解式开发 -->
<!-- 开启组件扫描 -->
<context:component-scan base-package="com.newcapec.controller"/>
2.4.3 RequestMappingHandlerMapping
注解式处理器映射器,对类中标记@ResquestMapping的方法进行映射,根据ResquestMapping定义的url匹配ResquestMapping标记的方法,匹配成功返回HandlerMethod对象给前端控制器,HandlerMethod对象中封装url对应的方法Method。
<!--配置处理器映射器-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
2.4.4 RequestMappingHandlerAdapter
注解式处理器适配器配置如下:
<!--配置处理器适配器-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
2.4.5 Handler处理器
@Controller 注解用于声明某类的实例是一个控制器。
Spring MVC 使用扫描机制找到应用中所有基于注解的控制器类,所以,为了让控制器类被 Spring MVC 框架扫描到,需要在配置文件中声明 spring-context,并使用 <context:component-scan/> 元素指定控制器类的基本包(请确保所有控制器类都在基本包及其子包下)。
/**
* 注解式处理器
*
* 好处:
* 1.零侵入:无需继承或实现任何的接口或类
* 2.一个处理器中可以处理多个请求,每个请求对应一个方法
*
* @Controller
* 作用:配置bean和标识当前类为spirngmvc中的处理器
*/
@Controller
public class DemoController {
/**
* 处理请求的方法
*
* @RequestMapping
* 作用:将请求的路径与处理请求的方法进行绑定...
*/
@RequestMapping("/find.do")
public ModelAndView find(){
System.out.println("查询请求...");
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("message", "find");
modelAndView.setViewName("/success.jsp");
return modelAndView;
}
@RequestMapping("/add.do")
public ModelAndView add(){
System.out.println("新增请求...");
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("message", "add");
modelAndView.setViewName("/success.jsp");
return modelAndView;
}
}
注意:注解的映射器和注解的适配器必须配对使用。
2.4.6 视图编写
index.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Title</title>
</head>
<body>
<div style="text-align: center;">
<h1>首页</h1>
<p><a href="find.do">测试find</a></p>
<p><a href="add.do">测试add</a></p>
</div>
</body>
</html>
success.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<base href="${pageContext.request.contextPath}/">
<title>Title</title>
</head>
<body>
<div style="text-align: center;">
<h1>跳转成功页面</h1>
<div style="color:red;">${message}</div>
</div>
</body>
</html>
2.5 入门程序小结
-
通过入门程序理解SpringMVC前端控制器、处理器映射器、处理器适配器、视图解析器用法。非注解式了解即可,注解式必须熟练掌握。