From 51e22340af52726dd8606d84920595f9d3708c44 Mon Sep 17 00:00:00 2001 From: luoxiang <2806718453@qq.com> Date: Tue, 18 Dec 2018 22:27:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BE=9B=E9=A1=B9=E7=9B=AE=E8=AF=B4?= =?UTF-8?q?=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spring/springmvc-base-annotation/README.md | 372 ++++++++++++++++++ spring/springmvc-base/README.md | 365 ++++++++++++++++- .../interceptors/MyFirstInterceptor.java | 1 + 3 files changed, 737 insertions(+), 1 deletion(-) diff --git a/spring/springmvc-base-annotation/README.md b/spring/springmvc-base-annotation/README.md index e69de29..bc681ea 100644 --- a/spring/springmvc-base-annotation/README.md +++ b/spring/springmvc-base-annotation/README.md @@ -0,0 +1,372 @@ +# springmvc基础(基于注解) + +**开发环境:IDEA** + +**spring版本:5.1.3.RELEASE** + +**本部分内容官方文档链接:[Web Servlet](https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/web.html#spring-web)** + +## 一、搭建hello spring工程 + +### 1.1 项目搭建 + +1.新建maven web工程,并引入相应的依赖 + +```xml + + 5.1.3.RELEASE + + + + + org.springframework + spring-context + ${spring-base-version} + + + org.springframework + spring-beans + ${spring-base-version} + + + org.springframework + spring-core + ${spring-base-version} + + + org.springframework + spring-web + ${spring-base-version} + + + org.springframework + spring-webmvc + ${spring-base-version} + + + javax.servlet + javax.servlet-api + 4.0.1 + provided + + +``` + +2.得益于servlet3.0和spring的支持,我们可以在没有web.xml的情况下完成关于servlet配置。 + + 新建DispatcherServletInitializer.java文件,这个类的作用相当于我们在xml方式下web.xml中配置的DispatcherServlet + +```java +package com.heibaiying.config; + +import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; + +/** + * @author : heibaiying + */ + +public class DispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { + + protected Class[] getRootConfigClasses() { + return new Class[0]; + } + + protected Class[] getServletConfigClasses() { + return new Class[]{ServletConfig.class}; + } + + protected String[] getServletMappings() { + return new String[]{"/"}; + } +} + +``` + +3.新建ServletConfig.java,文件内容如下(这个类相当于我们在xml配置方式中的springApplication.xml) + +```java +package com.heibaiying.config; + +import com.heibaiying.exception.NoAuthExceptionResolver; +import com.heibaiying.interceptors.MyFirstInterceptor; +import com.heibaiying.interceptors.MySecondInterceptor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.HandlerExceptionResolver; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.view.InternalResourceViewResolver; + +import java.util.List; + +/** + * @author : heibaiying + */ +@Configuration +@EnableWebMvc +@ComponentScan(basePackages = {"com.heibaiying.controller"}) +public class ServletConfig implements WebMvcConfigurer { + + /** + * 配置视图解析器 + */ + @Bean + public ViewResolver viewResolver() { + InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver(); + internalResourceViewResolver.setPrefix("/WEB-INF/jsp/"); + internalResourceViewResolver.setSuffix(".jsp"); + internalResourceViewResolver.setExposeContextBeansAsAttributes(true); + return internalResourceViewResolver; + } + + /** + * 配置静态资源处理器 + */ + public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { + configurer.enable(); + } + +} + +``` + +4.在src 下新建controller用于测试 + +```java +package com.heibaiying.controller; + +import com.heibaiying.exception.NoAuthException; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * @author : heibaiying + * @description : hello spring + */ + +@Controller +@RequestMapping("mvc") +public class HelloController { + + @RequestMapping("hello") + private String hello() { + return "hello"; + } + +} + +``` + +5.在WEB-INF 下新建jsp文件夹,新建hello.jsp 文件 + +```jsp +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + + + Title + + + Hello Spring MVC! + + +``` + +6.启动tomcat服务,访问localhost:8080/mvc/hello + +### 1.2 相关注解说明 + +**1.@Configuration** + +@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。 + +**2.@EnableWebMvc** + +简单的说就是提供了部分springmvc的功能,例如格式转换和参数绑定。 + + + +## 二、配置自定义拦截器 + +1.创建自定义拦截器,实现接口HandlerInterceptor(这里我们创建两个拦截器,用于测试拦截器方法的执行顺序) + +```java +package com.heibaiying.interceptors; + +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author : heibaiying + * @description : spring5 中 preHandle,postHandle,afterCompletion 在接口中被声明为默认方法 + */ +public class MyFirstInterceptor implements HandlerInterceptor { + + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + System.out.println("进入第一个拦截器preHandle"); + return true; + } + + // 需要注意的是,如果对应的程序报错,不一定会进入这个方法 但一定会进入afterCompletion这个方法 + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { + System.out.println("进入第一个拦截器postHandle"); + } + + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { + System.out.println("进入第一个拦截器afterCompletion"); + } +} +``` + +```java +package com.heibaiying.interceptors; + +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author : heibaiying + * @description : spring5 中 preHandle,postHandle,afterCompletion 在接口中被声明为默认方法 + */ +public class MySecondInterceptor implements HandlerInterceptor { + + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + System.out.println("进入第二个拦截器preHandle"); + return true; + } + + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { + System.out.println("进入第二个拦截器postHandle"); + } + + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { + System.out.println("进入第二个拦截器afterCompletion"); + } +} + +``` + +2.在ServletConfig.java中注册自定义拦截器 + +```java + /** + * 添加自定义拦截器 + */ + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(new MyFirstInterceptor()).addPathPatterns("/mvc/**").excludePathPatterns("mvc/login"); + registry.addInterceptor(new MySecondInterceptor()).addPathPatterns("/mvc/**"); + } +``` + +3.关于多个拦截器方法执行顺序的说明 + +拦截器的执行顺序是按声明的先后顺序执行的,先声明的拦截器中的preHandle方法会先执行,然而它的postHandle方法和afterCompletion方法却会后执行。 + + + +## 三、全局异常处理 + +1.定义自定义异常 + +```java +package com.heibaiying.exception; + +/** + * @author : heibaiying + * @description : 自定义无权限异常 + */ +public class NoAuthException extends RuntimeException { + + public NoAuthException() { + super(); + } + + public NoAuthException(String message) { + super(message); + } + + public NoAuthException(String message, Throwable cause) { + super(message, cause); + } + + public NoAuthException(Throwable cause) { + super(cause); + } + +} + +``` + +2.实现自定义异常处理器 + +```java +package com.heibaiying.exception; + +import org.springframework.web.servlet.HandlerExceptionResolver; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author : heibaiying + * @description : 无权限异常处理机制 + */ +public class NoAuthExceptionResolver implements HandlerExceptionResolver { + + public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { + if (ex instanceof NoAuthException && !isAjax(request)) { + return new ModelAndView("NoAuthPage"); + } + return new ModelAndView(); + } + + // 判断是否是Ajax请求 + private boolean isAjax(HttpServletRequest request) { + return "XMLHttpRequest".equalsIgnoreCase(request.getHeader("X-Requested-With")); + } +} + +``` + +3.在ServletConfig.java注册自定义异常处理器 + +```java +/** +* 添加全局异常处理器 +*/ +public void configureHandlerExceptionResolvers(List resolvers) { + resolvers.add(new NoAuthExceptionResolver()); +} +``` + +4.定义测试controller,抛出自定义异常 + +```java +@Controller +@RequestMapping("mvc") +public class HelloController { + + @RequestMapping("hello") + private String hello() { + return "hello"; + } + + + @RequestMapping("auth") + private void auth() { + throw new NoAuthException("没有对应的访问权限!"); + } +} +``` + +注:调用这个controller时,同时也可以验证在拦截器部分提到的:如果对应的程序报错,拦截器不一定会进入postHandle这个方法 但一定会进入afterCompletion这个方法 \ No newline at end of file diff --git a/spring/springmvc-base/README.md b/spring/springmvc-base/README.md index 354ad77..2dcd54d 100644 --- a/spring/springmvc-base/README.md +++ b/spring/springmvc-base/README.md @@ -1 +1,364 @@ -springmvc-base \ No newline at end of file +# springmvc基础(基于xml配置) + +**开发环境:IDEA** + +**spring版本:5.1.3.RELEASE** + +**本部分内容官方文档链接:[Web Servlet](https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/web.html#spring-web)** + +## 一、搭建hello spring工程 + +### 1.1 项目搭建 + +1.新建maven web工程,并引入相应的依赖 + +```xml + + 5.1.3.RELEASE + + + + + org.springframework + spring-context + ${spring-base-version} + + + org.springframework + spring-beans + ${spring-base-version} + + + org.springframework + spring-core + ${spring-base-version} + + + org.springframework + spring-web + ${spring-base-version} + + + org.springframework + spring-webmvc + ${spring-base-version} + + + javax.servlet + javax.servlet-api + 4.0.1 + provided + + +``` + +2.配置web.xml + +```xml + + + + + + springMvc + org.springframework.web.servlet.DispatcherServlet + + contextConfigLocation + classpath:springApplication.xml + + 1 + + + + springMvc + / + + + +``` + +3.在resources下新建springApplication.xml文件,文件内容如下: + +```xml + + + + + + + + + + + + + + + + + + + + + +``` + +4.在src 下新建controller用于测试 + +```java +package com.heibaiying.controller; + +import com.heibaiying.exception.NoAuthException; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * @author : heibaiying + * @description : hello spring + */ + +@Controller +@RequestMapping("mvc") +public class HelloController { + + @RequestMapping("hello") + private String hello() { + return "hello"; + } + +} + +``` + +5.在WEB-INF 下新建jsp文件夹,新建hello.jsp 文件 + +```jsp +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + + + Title + + + Hello Spring MVC! + + +``` + +6.启动tomcat服务,访问localhost:8080/mvc/hello + +### 1.2 相关配置讲解 + +**1.\** + +在web.xml配置中,我们将DispatcherServlet的拦截路径设置为“\”,则spring会捕获所有web请求,包括对静态资源的请求,为了正确处理对静态资源的请求,spring提供了两种解决方案: + +- 配置\ : 配置后,会在Spring MVC上下文中定义一个org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler,它会对进入DispatcherServlet的URL进行筛查,如果发现是静态资源的请求,就将该请求转由Web应用服务器默认的Servlet处理,如果不是静态资源的请求,才由DispatcherServlet继续处理。 + +- 配置\ :指定静态资源的位置和路径映射: + + ```xml + + + + ``` + +**2.\** + + 会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter +两个bean,用以支持@Controllers分发请求。并提供了数据绑定、参数转换、json转换等功能,所以必须加上这个配置。 + + + +## 二、配置自定义拦截器 + +1.创建自定义拦截器,实现接口HandlerInterceptor(这里我们创建两个拦截器,用于测试拦截器方法的执行顺序) + +```java +package com.heibaiying.interceptors; + +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author : heibaiying + * @description : spring5 中 preHandle,postHandle,afterCompletion 在接口中被声明为默认方法 + */ +public class MyFirstInterceptor implements HandlerInterceptor { + + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + System.out.println("进入第一个拦截器preHandle"); + return true; + } + + // 需要注意的是,如果对应的程序报错,不一定会进入这个方法 但一定会进入afterCompletion这个方法 + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { + System.out.println("进入第一个拦截器postHandle"); + } + + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { + System.out.println("进入第一个拦截器afterCompletion"); + } +} +``` + +```java +package com.heibaiying.interceptors; + +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author : heibaiying + * @description : spring5 中 preHandle,postHandle,afterCompletion 在接口中被声明为默认方法 + */ +public class MySecondInterceptor implements HandlerInterceptor { + + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { + System.out.println("进入第二个拦截器preHandle"); + return true; + } + + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { + System.out.println("进入第二个拦截器postHandle"); + } + + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { + System.out.println("进入第二个拦截器afterCompletion"); + } +} + +``` + +2.在springApplication.xml中注册自定义拦截器 + +```xml + + + + + + + + + + + + +``` + +3.关于多个拦截器方法执行顺序的说明 + +拦截器的执行顺序是按声明的先后顺序执行的,先声明的拦截器中的preHandle方法会先执行,然而它的postHandle方法和afterCompletion方法却会后执行。 + + + +## 三、全局异常处理 + +1.定义自定义异常 + +```java +package com.heibaiying.exception; + +/** + * @author : heibaiying + * @description : 自定义无权限异常 + */ +public class NoAuthException extends RuntimeException { + + public NoAuthException() { + super(); + } + + public NoAuthException(String message) { + super(message); + } + + public NoAuthException(String message, Throwable cause) { + super(message, cause); + } + + public NoAuthException(Throwable cause) { + super(cause); + } + +} + +``` + +2.实现自定义异常处理器 + +```java +package com.heibaiying.exception; + +import org.springframework.web.servlet.HandlerExceptionResolver; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author : heibaiying + * @description : 无权限异常处理机制 + */ +public class NoAuthExceptionResolver implements HandlerExceptionResolver { + + public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { + if (ex instanceof NoAuthException && !isAjax(request)) { + return new ModelAndView("NoAuthPage"); + } + return new ModelAndView(); + } + + // 判断是否是Ajax请求 + private boolean isAjax(HttpServletRequest request) { + return "XMLHttpRequest".equalsIgnoreCase(request.getHeader("X-Requested-With")); + } +} + +``` + +3.在springApplication.xml注册自定义异常处理器 + +```xml + + +``` + +4.定义测试controller,抛出自定义异常 + +```java +@Controller +@RequestMapping("mvc") +public class HelloController { + + @RequestMapping("hello") + private String hello() { + return "hello"; + } + + + @RequestMapping("auth") + private void auth() { + throw new NoAuthException("没有对应的访问权限!"); + } +} +``` + +注:调用这个controller时,同时也可以验证在拦截器部分提到的:如果对应的程序报错,拦截器不一定会进入postHandle这个方法 但一定会进入afterCompletion这个方法 \ No newline at end of file diff --git a/spring/springmvc-base/src/main/java/com/heibaiying/interceptors/MyFirstInterceptor.java b/spring/springmvc-base/src/main/java/com/heibaiying/interceptors/MyFirstInterceptor.java index a4765bf..ca16f80 100644 --- a/spring/springmvc-base/src/main/java/com/heibaiying/interceptors/MyFirstInterceptor.java +++ b/spring/springmvc-base/src/main/java/com/heibaiying/interceptors/MyFirstInterceptor.java @@ -17,6 +17,7 @@ public class MyFirstInterceptor implements HandlerInterceptor { return true; } + // 需要注意的是,如果对应的程序报错,不一定会进入这个方法 但一定会进入afterCompletion这个方法 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { System.out.println("进入第一个拦截器postHandle"); }