/**
* 環(huán)境
*Windows 7
*JDK 1.8
*SpringBoot 2.0.2
*Eclipse Photon
*/
所有的開(kāi)發(fā)之中攔截器一定是一個(gè)必須要使用的功能梯醒,利用攔截器可以更加有效的實(shí)現(xiàn)數(shù)據(jù)的驗(yàn)證處理吸重,而且最為幸運(yùn)的是在 SpringBoot 之中所使用的攔截器與 Spring 中的攔截器完全一樣刽辙。
項(xiàng)目所需JAR(pom文件)
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>com.github.kischang</groupId>
<artifactId>fastdfs-client</artifactId>
<version>0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
第一部分 基礎(chǔ)攔截器
1.創(chuàng)建SpringBoot啟動(dòng)類(lèi) (StartSpringBootMain.java)
package com.dxf.myspringboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication // 啟動(dòng)SpringBoot程序,而后自帶子包掃描
public class StartSpringBootMain {
public static void main(String[] args) throws Exception {
SpringApplication.run(StartSpringBootMain.class, args);
}
}
2.創(chuàng)建Model(Member.java)
package com.dxf.myspringboot.model;
public class Member {
private Long mid;
private String name;
private int age;
private Double salary;
public Long getMid() {
return mid;
}
public void setMid(Long mid) {
this.mid = mid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Member [mid=" + mid + ", name=" + name + ", age=" + age + ", salary=" + salary + "]";
}
}
3.創(chuàng)建Member控制器(MemberController.java)
package com.dxf.myspringboot.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.dxf.myspringboot.model.Member;
@Controller
public class MemberController {
@RequestMapping(value="/add_member_pre",method=RequestMethod.GET)
public String addMemberPre() {
return "add_member";
}
@RequestMapping(value="/add_member",method=RequestMethod.POST)
@ResponseBody
public Object addMember(Member member) {
return member;
}
}
4.編寫(xiě)HTML界面(add_member.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form th:action="@{/add_member}" method="post">
用戶編號(hào):<input type="text" name="mid" placeholder="請(qǐng)輸入mid"/><br/>
用戶姓名:<input type="text" name="name" placeholder="請(qǐng)輸入用戶名"/><br/>
<input type="submit" value="表單提交"/>
</form>
</body>
</html>
5.SpringBoot配置文件(application.yml)
server:
port: 80
此時(shí)一個(gè)正常的 MVC 的代碼就實(shí)現(xiàn)完成了精盅,在這里我們進(jìn)行個(gè)小測(cè)試看下能否正常運(yùn)行呢
首先在瀏覽器輸入 localhost/add_member_pre
再輸入各種參數(shù)
我們看下能否正常輸出Restful
6.攔截器配置(MyInterceptor.java)
為了更好的說(shuō)明問(wèn)題胳施,現(xiàn)在將攔截器定義在外包中;
package com.dxf.utils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
public class MyInterceptor implements HandlerInterceptor {
private Logger log = LoggerFactory.getLogger(MyInterceptor.class) ;
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
HandlerMethod handlerMethod = (HandlerMethod) handler ;
this.log.info("【*** MyInterceptor.preHandle() ***】" + handlerMethod.getBean().getClass().getSimpleName());
return true; // 如果返回false表示不繼續(xù)請(qǐng)求羽嫡,如果返回true表示繼續(xù)請(qǐng)求
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
HandlerMethod handlerMethod = (HandlerMethod) handler ;
this.log.info("【*** MyInterceptor.postHandle() ***】" + handlerMethod.getBean().getClass().getSimpleName());
this.log.info("【*** MyInterceptor.postHandle() ***】" + modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
this.log.info("【*** MyInterceptor.afterCompletion() ***】攔截處理完畢" );
}
}
7.那么此時(shí)如果要想使用攔截器則必須有一個(gè)攔截器的配置類(lèi)”纠眩現(xiàn)在不在編寫(xiě)配置文件了,所有的配置直接利用一個(gè)類(lèi)完成杭棵。(MyWebApplicationConfig.java)
package com.dxf.myspringboot.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.dxf.utils.MyInterceptor;
@Configuration
public class MyWebApplicationConfig extends WebMvcConfigurerAdapter{
@SuppressWarnings("deprecation")
@Override
public void addInterceptors(InterceptorRegistry registry) { // 進(jìn)行攔截器的注冊(cè)處理操作
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**") ; // 匹配路徑
super.addInterceptors(registry);
}
}
現(xiàn)在只要找到了可以操作的控制器程序類(lèi)婚惫,那么就可以依照在 Spring 中講解的攔截器代碼那樣進(jìn)行各種驗(yàn)證規(guī)則的編寫(xiě)以及相應(yīng)的錯(cuò)誤提示輸出了。
附件(項(xiàng)目結(jié)構(gòu))
第二部分 AOP攔截器
在 Spring 里面還提供有一種 AOP 攔截器配置魂爪,不過(guò)大部分的 AOP 攔截器都是圍繞著業(yè)務(wù)層進(jìn)行攔截處理的先舷。
1.業(yè)務(wù)層接口(IMemberService.java)
package com.dxf.myspringboot.service;
import com.dxf.myspringboot.model.Member;
public interface IMemberService {
public Member get(long mid) ;
}
2.業(yè)務(wù)層實(shí)現(xiàn)類(lèi)(MemberServiceImpl.java)
package com.dxf.myspringboot.service.imp;
import org.springframework.stereotype.Service;
import com.dxf.myspringboot.model.Member;
import com.dxf.myspringboot.service.IMemberService;
@Service
public class MemberServiceImpl implements IMemberService {
@Override
public Member get(long mid) {
Member member = new Member();
member.setMid(mid);
member.setName("韓信");
member.setSalary(100000.00);
return member;
}
}
3.現(xiàn)在業(yè)務(wù)層的操作完成之后隨意去修改控制層,讓控制層進(jìn)行業(yè)務(wù)層的調(diào)用
@Resource
private IMemberService memberService ;
@RequestMapping(value = "/member_get", method = RequestMethod.GET)
@ResponseBody
public Object get(long mid) {
return this.memberService.get(mid) ;
}
訪問(wèn)地址:http://localhost/member_get?mid=100
4.現(xiàn)在的業(yè)務(wù)層只是一個(gè)純粹的調(diào)用而已滓侍,但是現(xiàn)在希望對(duì)調(diào)用的過(guò)程進(jìn)行攔截處理蒋川,所以要想實(shí)現(xiàn)這樣的處理,那么就需要
引入新的開(kāi)發(fā)依賴(lài)包撩笆,修改 pom.xml 配置文件(這個(gè)我在之前已經(jīng)加了):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
5.編寫(xiě)一個(gè) AOP 攔截的控制程序類(lèi)捺球。
package com.dxf.myspringboot.config;
import java.util.Arrays;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class ServiceAspect { // 此時(shí)定義有一個(gè)業(yè)務(wù)層的攔截處理
private Logger log = LoggerFactory.getLogger(ServiceAspect.class);
@Around("execution(* com.dxf..service..*.*(..))")
public Object arroundInvoke(ProceedingJoinPoint point) throws Throwable {
this.log.info("【*** Service-Before ***】執(zhí)行參數(shù):"
+ Arrays.toString(point.getArgs()));
Object obj = point.proceed(point.getArgs()); // 進(jìn)行具體業(yè)務(wù)調(diào)用
this.log.info("【*** Service-After ***】返回結(jié)果:" + obj);
return obj;
}
}
如果大家也是用Eclispe的話,切入成功會(huì)出現(xiàn)以下標(biāo)記
6.測(cè)試
【啟動(dòng)StartSpringBootMain】---》【在瀏覽器輸入http://localhost/member_get?mid=100】
看下后臺(tái)輸出