0、环境配置
0.0引入坐标依赖
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring.version>5.0.2.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--提供在IOC基础上的扩展功能-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!--包括Web应用开发时,用到的Spring框架所需核心类-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!--包含SpringMVC应用开发需要的核心类-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<!--解析JSON-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.18.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.18.1</version>
</dependency>
0.1、配置核心Servlet前段控制器
<!-- springMVC的核心控制器-->
<servlet>
<servlet-name>dispatchServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置Servlet的初始化参数,读取SpringMvc的配置文件,创建Spring容器-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!-- 配置Servlet启动时加载对象-->
<!-- 当启动TOMCAT服务器时,因为配置了load-on-startup标签
所以会创建 DispatcherServlet对象,就会加载springmvc.xml配置文件
-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatchServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
0.2、创建配置Springmvc.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvn="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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 配置Spring创建容器时要扫描的包-->
<context:component-scan base-package="com.monkey"></context:component-scan>
<!-- 配置视图解析器-->
<bean id="viewResolve" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 配置文件解析器,要求id名称必须是multipartResolver-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760"/>
</bean>
<!--配置异常处理器-->
<bean id="SystemExceptionResolver" class="com.monkey.Exception.SystemExceptionResolver"></bean>
<!--配置拦截器-->
<mvc:interceptors>
<!-- 配置拦截器-->
<mvc:interceptor>
<!-- 要拦截具体非方法-->
<mvc:mapping path="/user2/*"/>
<bean class="com.monkey.interceptor.MyInterepter1"/>
</mvc:interceptor>
</mvc:interceptors>
<!-- 前段控制器,哪些静态资源不拦截-->
<mvc:resources mapping="/js/" location="/js/**"/>
<mvc:resources mapping="/css/" location="/css/**"/>
<mvc:resources mapping="/images/" location="/imgaes/**"/>
<!--开启SpringMVC框架注解的支持-->
<mvc:annotation-driven></mvc:eq-driven>
在SpringMVC的各个组件中,处理映射器、处理器适配器、视图解析器称为SpringMVC的三大组件。使用mvc:annotation-driven自动加载RequestMappingHandlerMapping(处理映射器)和RequestMappingHandlerAdapter(处理器适配器)。
0.3、执行过程分析
1、组件
- DispatcherServlet:前端控制器
- HandlerMapping处理映射器
- Handler:处理器
- HandlerAdapter:处理器适配器
- View Resolver:视图解析器
- View:视图
以前端控制器为控制中心,前端空值器会去调用 视图解析器,处理器,处理适配器,文件上传组件,异常处理组件,过滤组件,注意这些组件都需要进行注册。。。都需要在配置文件中进行配置;配置比较繁琐。
1.1DispatcherServlet:前端控制器
用户请求到达前端控制器,它就相当于mvc模式中的c,dispatcherServlet是整个流程控制中心,由它调用其他组件处理用户的请求,dispatcherServlet降低了组件之间的耦合性
1.2 HandlerMapping处理映射器
HandlerMapping负责根据用户请求找到Handler即处理器,springMVC提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式
1.3、Handler:处理器
它就是我们开发中要编写的具体业务控制器,由DispatcherServlet把用户请求转发到Handler,由Hander对具体的用户请求进行处理
1.4、HandlerAdapter:处理器适配器
通过HandlerAdapter对处理器进行操作,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行 执行
1.5、View Resolver:视图解析器
View Resolver负责将处理结果生成View视图,View Resolver首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成view视图对象,最后对View进行渲染将处理结果通过页面展示给用户
1.6、View视图
Spring MVC框架提供了很多View视图类型的支持,包括:jstlview、freemarkerView、pdfView等。我们最常用的视图就是jsp。一般情况下需要通过页面标签或页面模板技术奖模型
2、请求参数的绑定:前端向后台传递数据
在实际的开发中,客户端请求后台处理方法时可以传递参数,且参数包含多种类型。SpringMVC框架是如何绑定并获取请求参数呢???
在执行过程中,Spring MVC根据客户端请求参数的不同将请求消息中的信息以一定的方式转发并绑定到控制器类的方法参数中。这种将请求消息数据与后台控制参数建立连接的过程就是SpringMVC中的数据绑定
SpringMVC绑定请求参数的过程是通过表单提交请求参数,作为控制器中方法参数进行绑定的
(1)基本类型参数:包括基本类型和String类型
(2)POJO类型参数:包括实体类,以及关联的实体类;在使用POJO类型数据绑定时,前端请求的参数名必须与要绑定的POJO类型中的属性名一致,这样才会自动将请求数据绑定到POJO对象中,否则后台接受的参数值为NULL
(3)数组和集合类型参数:包含List结构和Map结构的集合。
SpringMVC绑定请求参数是自动实现的,但是想要使用,必须遵循使用要求
2.2使用要求
(1)如果是基本类型或者String类型:要求我们的参数名称必须和控制器方法中的形参名称保持一致
(2)如果是POJO类型,或者他们的关联对象:要求表单中参数名称和POJO类的属性名称一致,并且控制方法的参数类型是POJO类型
在使用包装POJO类型数据绑定时,前端请求的参数名编写必须符合以下两种情况:
①如果查询条件参数是包装类的基本属性,参数名就直接用对应的属性名。
②如果查询条件是包装类中POJO的子属性,参数名就必须为[对象.属性],其中[对象]要和包装POJO中华的对象属性名称一致,[属性]要和包装POJO中的对象子属性一致。
(3)如果是集合类型,有两种方式:第一种:要求集合类型的请求参数必须在POJO。在表单中请求参数名称要和POJO中集合属性名称相同。给List集合中的元素赋值,使用下标。给Map集合中的元素赋值,使用键值对。
SpringMVC绑定请求参数是自动实现的,但是想要使用,必须遵循使用要求
2.3使用示例
2.4、使用ServletAPI对象作为方法参数
SpringMVC还支持使用原始ServletAPI对象作为控制器方法的参数,支持原始ServletAPI对象有:
- HttpServletRequest
- HttpServletResponse
- HttpSession
- Reader
- Writer
- InputStream
- OutputStream
我们可以吧上述对象,直接写在控制方法参数中使用
小结:在网页传递参数时,我们可以获取参数,可以根据参数的类型进行如下总结:(1)如果是基本数据类型那么把基本数据类型对应的参数名直接传入对应的方法参数名中乐意自动进行封装;(2)如果是POJO数据类型,那么传入参数的名称为POJO对应的属性名称;(3)如果传入LIst或MAP那么根据List或Map传入;(4)可以直接使用Servlet API。
2.5解决中文乱码的问题
在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>
3、注解
3.1、RequestMapping注解:用于建立请求URL和处理请求方法之间的对应关系。
作用:用于建立请求URL和处理请求方法之间的对应关系。
属性:(1)value:用于指定请求的URL。它和Path属性的作用是一样的。**
(2)method:用于指定请求的方式
(2)params:用于指定限制参数的条件
3.2 常用注解
RequestParam:注解解决前端请求中参数名和后台控制器类方法中的形参名不一样。
3.3存对象在request和session域
Model和@SessionAttribute
在会话中存储属性以及获取及删除属性用到的注解@SessionAttributes以及Model、ModelMap、Status等
@Controller
@SessionAttributes(value={"username","password"}) //必须声明,在SessionAttribute中存储的特征
public class TestSessionAttribute {
/**
* 将数据存储
* @param model
* @return
*/
@RequestMapping("/testPut")
public String testPut(Model model){
model.addAttribute("username","zhoujian");
model.addAttribute("password","123456");
return "success";
}
/**
* 获取存储在会话中的数据
* @param model
* @return
*/
@RequestMapping("/testGet")
public String testget(ModelMap model){
System.out.println(model.get("username"));
System.out.println(model.get("password"));
return "success";
}
/**
* 删除会话中的数据,需要使用到SessionStatus接口
* @param sessionStatus
* @return
*/
@RequestMapping("/testDelte")
public String testDelete(SessionStatus sessionStatus){
sessionStatus.setComplete();
return "success";
}
4、响应数据和结果视图
4.1、返回值类型
常见的返回类型有ModelAndView、String和Void。其中,ModelAndView类型可以添加Model数据,并指定视图;String类型的返回值可以跳转视图但不能携带数据;而VOID数据类型主要在异步请求时使用,它只返回数据而不会跳转视图
4.1.1、字符串
由于ModelAndView类型未能实现数据与视图之间的解耦,因此在开发时,方法的返回类型通常都会使用String.既然String类型的返回值不能携带数据,那么在方法中如何将数据带入视图页面?这就涌动上面所讲解的Model参数类型,通过该参数类型即可添加需要在视图中显示的属性
4.1.2、void
4.1.3、ModelAndView
4.2、转发和重定向
4.3、ResponseBody响应JSON数据:AJAX
首先需要配置对静态资源不访问:
<!--前端控制器,哪些资源不拦截,设置静态资源不拦截-->
<mvc:resources mapping="/js/**" location="/js/**">
作用:该注解用于将Controller的方法返回的对象,通过HttpMessageConverter接口转换为指定格式对的数据:如JSON,XML等,通过Respose响应给客户端。
需求:使用@RequestBody注解实现将controller方法返回对象转换为json响应给客户端。
前置知识点:SpringMVC默认用MappingJackson对json进行数据转换,需要加入jackson的包
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>
5、Spring MVC实现文件上传
5.1、文件上传的必要前提
5.2、文件上传的原理分析
##5.3、SpringMVC传统方式的文件工作
原理
记得配置文件解析器
6、SpringMVC异常处理
7、SpringMVC中拦截器
7.1、拦截器的作用
SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。
用户可以自己定义一些拦截器来实现特定的功能。
我们要想实现拦截器,要求必须实现:HandlerInterceptor接口。
7.2、拦截器中方法说明
小Demo:登录拦截
步骤一:写拦截器
package cm.itcast.Interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @Author Zhou jian
* @Date 2019 ${month} 2019/11/29 0029 11:42
* 自定义登录拦截器:实现HanlerInterceptor接口并重写其中的方法
*/
public class LoginInterCeptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//获取拦截到的网址
String uri = request.getRequestURI();
System.out.println("访问的网址为"+uri);
//如果拦截的网址为登录网址,则直接方形
if(uri.indexOf("login")!=-1){
return true;
}else{
//如果拦截的网址中无user属性,跳转到登录页面
if(request.getSession().getAttribute("user")==null){
request.getRequestDispatcher("/WEB-INF/pages/login.jsp").forward(request,response);
return false;
}else{
//已经登录正常执行
return true;
}
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
步骤二:注册拦截器
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="cm.itcast.Interceptor.LoginInterCeptor" id="loginInterCeptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
步骤三,准备页面
<!--login.jsp-->
<form method="post" action="login">
姓名:<input type="text" name="username">
<input type="submit" value="提交">
</form>
<!--Welocome.jsp-->
欢迎你,${user}!!
步骤四:准备后台Controller*
**
* @Author Zhou jian
* @Date 2019 ${month} 2019/11/29 0029 11:42
*/
@Controller
@SessionAttributes("user") //需要在注解中准备SessionAttribute
public class LoginController {
@RequestMapping("/login")
public String login(Model model,String username){
System.out.println("登录成功");
model.addAttribute("user",username); //添加会话属性
return "welcome";
}
@RequestMapping("/showPage")
public String showPage(ModelMap model){
if(model.get("user")!=null){ //若存在会话属性则跳转到欢迎页面
return "welcome";
}else{
return "login";//否则跳转到登录页面
}
}
}
/**
* 注销用户
* @param modelMap
* @return
*/
@RequestMapping("/logout")
public String logout(ModelMap modelMap){
if(modelMap.get("user")!=null){
modelMap.addAttribute("user",null);//覆盖原先登录的Uer置气为空
return "login";
}else{
return "login";
}
}