SpringBoot拦截器

/**
* 环境 
*Windows 7 
*JDK 1.8 
*SpringBoot 2.0.2 
*Eclipse Photon
*/

所有的开发之中拦截器一定是一个必须要使用的功能,利用拦截器可以更加有效的实现数据的验证处理,而且最为幸运的是在 SpringBoot 之中所使用的拦截器与 Spring 中的拦截器完全一样。

项目所需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>

第一部分 基础拦截器

1.创建SpringBoot启动类 (StartSpringBootMain.java)

package com.dxf.myspringboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication  // 启动SpringBoot程序,而后自带子包扫描
public class StartSpringBootMain {
    public static void main(String[] args) throws Exception {
        SpringApplication.run(StartSpringBootMain.class, args);
    }
}

2.创建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.创建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.编写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">
        用户编号:<input type="text" name="mid" placeholder="请输入mid"/><br/>
        用户姓名:<input type="text" name="name" placeholder="请输入用户名"/><br/>
        <input type="submit" value="表单提交"/>
    </form>
</body>
</html>

5.SpringBoot配置文件(application.yml)

server:
  port: 80

此时一个正常的 MVC 的代码就实现完成了,在这里我们进行个小测试看下能否正常运行呢
首先在浏览器输入 localhost/add_member_pre


image

再输入各种参数


image

我们看下能否正常输出Restful
image

6.拦截器配置(MyInterceptor.java)

为了更好的说明问题,现在将拦截器定义在外包中;

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表示不继续请求,如果返回true表示继续请求
    }

    @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.那么此时如果要想使用拦截器则必须有一个拦截器的配置类。现在不在编写配置文件了,所有的配置直接利用一个类完成。(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) { // 进行拦截器的注册处理操作
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**") ;   // 匹配路径
        super.addInterceptors(registry);
    }
}

现在只要找到了可以操作的控制器程序类,那么就可以依照在 Spring 中讲解的拦截器代码那样进行各种验证规则的编写以及相应的错误提示输出了。
附件(项目结构)


image

第二部分 AOP拦截器

在 Spring 里面还提供有一种 AOP 拦截器配置,不过大部分的 AOP 拦截器都是围绕着业务层进行拦截处理的。

1.业务层接口(IMemberService.java)

package com.dxf.myspringboot.service;

import com.dxf.myspringboot.model.Member;

public interface IMemberService {
 public Member get(long mid) ;
}

2.业务层实现类(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.现在业务层的操作完成之后随意去修改控制层,让控制层进行业务层的调用

@Resource
    private IMemberService memberService ;
    @RequestMapping(value = "/member_get", method = RequestMethod.GET)
    @ResponseBody
    public Object get(long mid) {
        return this.memberService.get(mid) ;
    }

访问地址:http://localhost/member_get?mid=100

4.现在的业务层只是一个纯粹的调用而已,但是现在希望对调用的过程进行拦截处理,所以要想实现这样的处理,那么就需要

引入新的开发依赖包,修改 pom.xml 配置文件(这个我在之前已经加了):

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

5.编写一个 AOP 拦截的控制程序类。

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 { // 此时定义有一个业务层的拦截处理
    private Logger log = LoggerFactory.getLogger(ServiceAspect.class);
    @Around("execution(* com.dxf..service..*.*(..))")
    public Object arroundInvoke(ProceedingJoinPoint point) throws Throwable {
        this.log.info("【*** Service-Before ***】执行参数:"
                + Arrays.toString(point.getArgs()));
        Object obj = point.proceed(point.getArgs()); // 进行具体业务调用
        this.log.info("【*** Service-After ***】返回结果:" + obj);
        return obj;
    }
}

如果大家也是用Eclispe的话,切入成功会出现以下标记

image

6.测试
【启动StartSpringBootMain】---》【在浏览器输入http://localhost/member_get?mid=100
image

看下后台输出
image

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容