spring的一个组件 替换控制层 ——Struts
一、SpringMVC入门
是⼀种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架
让我们能⾮常简单的设计出⼲净的Controller层和薄薄的Controller层
进⾏更简洁的Controller层的开发
天⽣与Spring框架集成(如IoC容器、AOP等)
提供强⼤的约定⼤于配置的契约式编程⽀持 ⼤量的代码都是约定好了。直接⽤即可。
⾮常灵活的数据验证、格式化——(⽇期格式化)和数据绑定机制
⽀持Restful⻛格
springMVC 的请求流程
二、SpringMVC怎么用(jar包注意)
pom文件
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<spring-version>4.3.7.RELEASE</spring-version>
</properties>
----------------------------------------
<!-- servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0-alpha-1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring-version}</version>
</dependency>
1 在web.xml里面加载DispatcherServlet
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!-- 1、核心控制器 -->
<servlet>
<servlet-name>aaa</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>aaa</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2.创建一个配置文件
<!-- 2、HandlerMapping负责路劲解析 告诉下一个该怎么调用Hander: 控制层 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"> </bean>
<!--3、 适配器-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!-- 5, ViewResoutrver: 视图解析 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
</bean>
<bean id="/user/login" class="com.controller.UserController"></bean>
3.书写处理器(继承接口 Controller)即Adapter处理器
public class UserController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
System.out.println("这是一个Hander类");
//包含会 路劲
ModelAndView modelAndView=new ModelAndView();
modelAndView.addObject("info","这是一个测试类");
modelAndView.setViewName("/index.jsp");
return modelAndView;
}
}
4 书写jsp
<%--
Created by IntelliJ IDEA.
User: 15836
Date: 2021/10/27
Time: 9:47
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>${info}</h1>
</body>
</html>
三、SpringMVC注解使用
四、SpringMVC拦截器 、异常处理
1、拦截器 拦截器是有去有回的
不是基于web的 是基于自己的框架的
基于SpringMvc框架的拦截器只能拦截器SpringMvc的请求
所有控制层请求 js css 不走
底层其实是反射或者代理
确定spring的是反射还是代理==============------=--------====
2、两种方式
HandlerInterceptor(处理程序拦截器)实现了Spring 的HandlerInterceptor 接口或者继承实现了
HandlerInterceptor 接口的(比如抽象类HandlerInterceptorAdapter );
/**
* @author zhangyifan
* @version 8.0
* @description:
* @date 2021/11/23 9:17
*/
public class Myinter01 implements HandlerInterceptor {
/*preHandle( ):该方法在控制器的处理请求方法前执行,其返回值表示是否中断后续操作,
返回 true 表示继续向下执行,返回 false 表示中断后续操作。
postHandle( ):该方法在控制器的处理请求方法调用之后、解析视图之前执行,
可以通过此方法对请求域中的模型和视图做进一步的修改。
afterCompletion( ):该方法在控制器的处理请求方法执行完成后执行,即视图渲染结束后执行,
可以通过此方法实现一些资源清理、记录日志信息等工作。*/
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
System.out.println("preHadn=====preHandle方法在控制器的处理请求方法调用之前执行");
System.out.println(httpServletRequest.getRequestURI());
HttpSession session = httpServletRequest.getSession();
Object user = session.getAttribute("user");
if (user!=null){
return true;
}else {
httpServletResponse.sendRedirect("/module/login/login.html");
return false;
}/* SpringMVC就不栏jsp 栏html*/
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("preHadn=====postHandle方法在控制器的处理请求方法调用之后,解析视图之前执行");
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
System.out.println("preHadn=====afterCompletion方法在控制器的处理请求方法执行完成后执行,即视图渲染结束之后执行");
}
/*
* Hander: hander 是一个处理器·--自己书写的控制层类就是处理器
* pre:前 执行 Hander 之前 。 调用控制类前
* return true :请求继续 return false 拦截
* */
}
WebRequestInterceptor(Web 请求拦截器)实现Spring的WebRequestInterceptor接口或者是继承实现了
WebRequestInterceptor的类
参数WebRequest 是Spring 定义的一个接口,它里面的方法定义跟HttpServletRequest基本 一
样,在WebRequestInterceptor 中对WebRequest 进行的所有操作都将同步到
HttpServletRequest 中,然后在当前请求中一直传递。
/**
* @author zhangyifan
* @version 8.0
* @description:
* @date 2021/11/23 9:22
*/
public class Myinter02 implements WebRequestInterceptor {
@Override
public void preHandle(WebRequest webRequest) throws Exception {
System.out.println( " myInter02=============preHandle");
}
@Override
public void postHandle(WebRequest webRequest, ModelMap modelMap) throws Exception {
System.out.println( " myInter02=============postHandle");
}
@Override
public void afterCompletion(WebRequest webRequest, Exception e) throws Exception {
System.out.println( " myInter02=============afterCompletion");
}
}
总结:WebRequestInterceptor和HandlerInterceptor这两个拦截接口的区别:
- HandlerInterceptor接口的perHandle 方法有Boolean类型返回值,而
WebRequestInterceptor对应方法没有返回值 - HandlerInterceptor是针对请求的整个过程的,方法中都有response参数,而
WebRequestInterceptor是针对请求的,接口方法中没有response
3、拦截器的配置
<!-- 配置一个全局拦截器,拦截所有请求 -->
<!-- <bean class="com.Inter.Myinter02"/>-->
<mvc:interceptors>配置一组拦截器。
<mvc:interceptor><!--包含 用于定义指定路径的拦截器。 -->
<!-- 配置拦截器作用的路径 /**时,表示拦截所有路径 /gotoTest时,表示拦截所有以/gotoTest结尾的路径-->
<mvc:mapping path="/**"/>
<!-- 配置不需要拦截作用的路径 -->
<mvc:exclude-mapping path="/resources/**"/>
<mvc:exclude-mapping path="/user/loginB"/>
<mvc:exclude-mapping path="/module/login/login.html"/>
<!-- 定义<mvc:interceptor>元素中,表示匹配指定路径的请求才进行拦截 -->
<bean class="com.Inter.Myinter01"/>
</mvc:interceptor>
</mvc:interceptors>
注意interceptor元素中的子元素 必须按照< mvc:mapping…/>、mvc:exclude-mapping.../、<bean…/> 的顺序配置。
3、拦截器和过滤器的区别
Filter:过滤器 Filter基于WEB工程,所以什么都可以拦截 ,并且只拦截请求,响应不拦截
拦截器:是基于各自的框架。基于SpringMVC框架的拦截器只能拦截器SPringMVC能拦的请求。是有去有回的
springMVC拦截器应该是基于Java的反射机制。但是底层还是 jdk的动态代理实现的。
五、SpringMVC异常处理
1、为什么要异常处理
异常 在代码运行会通过代码一层一层的抛到前台
现实情况 是 异常是不需要看客户看到的 应该将异常处理成一个较为美观的状态页面 ,这样就需要异常的统一管理了
2、三种异常实现方式(spring MVC)
异常 设置
本案例 以设置视图映射
(1)Sprin MVC 提供的简单 异常处理器 SimpleMappingExceptionResolver
只能处理同步
<!--系统提供的统一异常处理:会走:InternalResourceViewResolver——只能处理同步 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionR
<!-- 定义默认的异常处理页面,当该异常类型的注册时使用 module/error.jsp -->
<property name="defaultErrorView" value="error/error"></property>
<!-- 定义异常处理页面用来获取异常信息的变量名,默认名为exception request.setA
<property name="exceptionAttribute" value="e"></property>
<!-- 定义需要特殊处理的异常,用类名或完全路径名作为key,异常也页名作为值 -->
<property name="exceptionMappings">
<props>
<prop key="java.lang.NullPointerException">error/null</prop>
<prop key="java.lang.ArithmeticException">error/athri</prop>
<!-- 这里还可以继续扩展对不同异常类型的处理 -->
</props>
</property>
</bean>
(2)、实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author zhangyifan
* @version 8.0
* @description:
* @date 2021/11/23 11:08
*/
public class MyExceptionResoler implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
String message="统一异常,请 联系管理员";
String url="error/error";
if (e instanceof NullPointerException){
message="出现空指针异常。请联系管理员";
url="error/null";
}else if (e instanceof ArithmeticException){
message="出现数学异常";
url="error/athri";
}
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("e",message);
modelAndView.setViewName(url);
return modelAndView;
}
}
自定义统一 异常处理 可以 处理同步 ,自定义
可以处理异步但是非常麻烦 异步都要走 application、json判断
(3)、使用@ExceptionHandler注解实现异常处理;
注意:该注解不是加在产生异常的方法上,而是加在处理异常的方法上。
/**
* @author zhangyifan
* @version 8.0
* @description:
* @date 2021/11/23 11:08
*/
@ControllerAdvice//全局生效 ,这是一个增强的 Controller
/*全局异常处理
全局数据绑定
全局数据预处理
* */
public class MyExceptionResoler2 {
@ExceptionHandler(ArithmeticException.class)
@ResponseBody
public LayUIEntity athChLI(Exception e){
return new LayUIEntity(-1,"出现数学异常");
}
@ExceptionHandler(NullPointerException.class)
@ResponseBody
public LayUIEntity kzz(Exception e){
return new LayUIEntity(-1,"空指针");
}
@ExceptionHandler(Exception.class)
@ResponseBody
public LayUIEntity ty(Exception e){
return new LayUIEntity(-1,"统一");
}
}
@ExceptionHandler 注解定义的方法优先级问题:例如发生的是 NullPointerException,但是声明的异常有 RuntimeException 和 Exception,这时候会根据异常的最近继承关系找到继承深度最浅的那个
如果单使用@ExceptionHandler,只能在当前Controller中处理异常。但当配合
@ControllerAdvice一起使用的时候,就可以摆脱那个限制了。