目录
3、编写一个Java控制类(HelloController.java)
前言
Spring框架提供了构建Web应用程序的全功能MVC模块,而且它分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离使其更容易被定制。Spring的MVC框架主要由下面几部分组成:DispatcherServlet、处理器映射、处理器(控制器)、视图解析器、视图。本文主要是对学习过程中的知识进行归纳总结,由于框架中很多代码是可以复用的,方便以后的学习。
一、SpringMVC的执行过程
1、当用户通过浏览器输入url 时,会发送一个http请求给web服务器,web服务器收到http请求后,会对该请求进行解析,如果匹配到了DispatcherServlet 的请求映射路径(在web.xml中指定,代码见步骤二),web容器会将该请求转交给DispatcherServlet。
2、 DispatcherServlet 收到请求之后,会调用处理器映射器HandlerMapping。
3、处理器映射器根据请求url 找到具体的处理器Handler,生成处理器对象及处理器拦截器(如有则生成)一并返回给DispatcherServlet。
4、DispatcherServlet 调用HandlerAdapter处理器适配器,执行HandlerAdapter的一系列操作,包括:数据验证等。
5、 HandlerAdapter 经过适配后调用具体的处理器(Controller,也叫后端控制器或者页面控制器)。
6、 Controller 执行完成后返回ModelAndView结果。
7、HandlerAdapter 再将 Controller 执行结果ModelAndView返回给DispatcherServlet。
8、DispatcherServlet 将执行结果ModelAndView传给ViewReslover视图解析器。
9、ViewReslover 解析后返回具体View。
10、DispatcherServlet 根据View进行视图渲染(即将模型数据model填充至视图中)。
11、DispatcherServlet 响应用户。
二、导入SpringMVC的相关pom依赖
1、导入pom依赖,建议建立一个父模块,然后在其下面绑定许多子模块,就无需每次都导入依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.15</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
2、在build中配置resources,来防止我们资源导出失败的问题
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
三、第一个SpringMVC项目
1、配置web.xml文件
1)在web.xml文件中注册DispatcherServlet,DispatcherServlet是SpringMVC的核心,又被称为请求分发器或者前端控制器。使用DispatcherServlet时,需要绑定springmvc配置文件。启动级别越小,启动得越早。
<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:springmvc-servlet.xml</param-value>
</init-param>
<!--启动级别为1,和服务器一起启动-->
<load-on-startup>1</load-on-startup>
</servlet>
2)配置好了servlet,一定不要忘记配置它的映射,即servlet-mapping。映射方式通常有两种,“/” 和“/*”。“/”匹配除jsp页面的所有请求(代表本级),不会匹配到.jsp,“/*”匹配所有的请求(代表下一级),包括jsp页面请求(会匹配到*.jsp,而且可能会出现404错误)。
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
2、 配置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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
1)添加处理器映射器,BeanNameUrlHandlerMapping实际用的少
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
2)添加处理器适配器
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
3)添加视图解析器,有许多模板引擎,包括Thymeleaf、Freemarker.....
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
4)编写好业务代码后(步骤3),记得注册bean,name对应请求路径,class对应处理请求的类
<bean name="/hello" class="com.controller.HelloController"/>
3、基本配置完成后,进行业务操作
在SpringMVC中,对于Controller的实现有很多种,通常有实现Controller接口和注解定义两种方式,推荐使用注解定义的方法。通过SpringMVC的执行过程,我们知道Controller控制器负责解析用户的请求并将其转换为一个模型,最后将结果返回给视图解析器(将mv返回至2.3进行解析)。该方法的缺点很明显,一个控制器中只能有一个方法,如果需要使用到多个方法就需要定义多个Controller,定义的方式比较繁琐。
package com.controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//只要实现了Controller接口的类,就说明这是一个控制器了
public class HelloController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mv = new ModelAndView();
//业务代码
String result = "Hello,SpringMVC!";
mv.addObject("msg", result);//添加数据
//进行视图跳转
mv.setViewName("hello");//设置视图的名字为:hello
return mv;
}
}
4、要跳转的jsp页面
该页面放于/WEB-INF/jsp包下,用以显示ModelandView存放的数据以及我们正常的页面。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
5、部署项目,查看运行结果
四、使用注解方式实现SpringMVC
1、配置web.xml文件
该配置和不用注解的方式一样
2、配置SpringMVC配置文件
1)配置头文件
<?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.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
2)自动扫描包的功能,让指定包下(这里是com.controller包)的注解生效,由Spring的IOC容器统一管理
<context:component-scan base-package="com.controller"/>
3)过滤掉HTML,JS ,CSS , 图片 , 视频等静态资源
<mvc:default-servlet-handler/>
4)annotation-driven配置可以帮助我们自动完成处理映射器和处理器适配器的注入
<mvc:annotation-driven/>
5)视图解析器跟无注解的一样,以后开展项目时,无需改动它。从下面代码中可以看出我们把所有的视图文件都放置于/WEB-INF/x/中,这是出于安全性的考虑,因为用户不能够直接访问到该文件夹下的配置资源。
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!-- 后缀 -->
<property name="suffix" value=".jsp"/>
</bean>
3、编写一个Java控制类(HelloController.java)
@Controller是为了让Spring IOC容器初始化时自动扫描到指定包;@RequestMapping是为了映射请求路径;方法中声明Model类型的参数是为了把Action中的数据带到视图中;方法返回的结果是视图的名称hello,加上配置文件中的前后缀变成WEB-INF/jsp/hello.jsp。
package com.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
/*
代表这个类会被Spring接管,被注解的类中的所有方法,如果返回值是String,
并且有具体页面可以跳转时,那么就可能被视图解析器解析.
*/
public class HelloController {
@RequestMapping("/hello")
public String hello(Model model){
//封装数据
model.addAttribute("msg","hello,SpringMVCAnnotation");
return "hello";
}
}
4、要跳转的jsp页面
解析“msg”,显示目标界面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
5、部署项目,查看运行结果
五、乱码过滤器
从Tomcat8.0开始,get请求中的中文参数不需要特殊处理,而使用post的提交方式,有时候还是会出现乱码问题。解决乱码问题有多种方法,第一种是自定义过滤器,第二种是修改Tomcat的配置文件,第三种是采用SpringMVC自带的过滤器。
1、自定义过滤器
创建一个EncodingFilter类,实现Filter接口并重写其中的方法,设置编码方式为UTF-8
package com.filter;
import javax.servlet.*;
import java.io.IOException;
public class EncodingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
在web.xml文件中配置过滤便签及过滤映射标签
<filter>
<filter-name>encoding</filter-name>
<filter-class>com.filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2、 修改Tomcat配置文件
<Connector URIEncoding="utf-8" port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
3、使用SpringMVC自带的乱码过滤器(建议使用)
在web.xml中配置,添加之后,重启Tomcat服务器
<filter>
<filter-name>encoding</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>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
注:最后附上Maven Repository地址,方便导入相关依赖jar包:https://mvnrepository.com/