Spring MVC 4 - 怎么用 a HandlerInterceptor去拦截Rest 请求---Gradle

本文来自于https://www.boraji.com/spring-mvc-4-how-to-intercept-request-with-a-handlerinterceptor, 翻译此文如下.

技术栈: Java SE 1.8 、Spring 4.3.10.RELEASE、 Maven 3.3.9 、 Eclipse Neon.3 、 Apache Tomcat  7.0.47

本文将会介绍如何通过使用 HandlerInterceptor 接口 、HandlerInterceptorAdapter 类在 Spring MVC 应用程序中拦截WEB 请求。

HandlerInterceptor 接口提供了三个抽象方法如下:

preHandle() - 这个方法会在一个控制器类的处理方法被调用之前执行此方法。

afterCompletion() - 这个方法会在一个请求完成之后被调用 。如渲染视图之后。

postHandle() - 这个方法会在controller类的处理方法调用之后, 但是在渲染视力之前运行。

类 HandlerInterceptorAdapter 是接口 HandlerInterceptor 的一个实现类。如果你想使用这些方法, 可以继承这个类, 然后覆盖它。

我们需要创建一个自定义的处理拦截器,可以通过实现 HandlerInterceptor 接口或者继承 HandlerInterceptorAdapter类。接下来看一下完整的demo例子。

Project structure

下面的项目结构由Gradle构建:

关于如何创建一个Web项目,参考https://www.boraji.com/how-to-create-a-web-project-using-maven-in-eclipse

Jar包依赖 - build.gradle


apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'eclipse-wtp'
apply plugin: 'jetty'

// JDK 8
sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    mavenLocal()
    mavenCentral()
}

dependencies {
 
	compile 'ch.qos.logback:logback-classic:1.1.3'
	compile 'javax.servlet:jstl:1.2'	
	//compile group: 'javax.servlet.jsp.jstl', name: 'jstl', version: '1.2'
	compile group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0'
	
	//Spring boot
	compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '1.5.9.RELEASE'
    compile group: 'org.aspectj', name: 'aspectjrt', version: '1.8.13'
	compile group: 'org.aspectj', name: 'aspectjweaver', version: '1.8.13'
	compile "commons-io:commons-io:2.5" 
	compile group: 'javax.annotation', name: 'jsr250-api', version: '1.0'
	compile group: 'javax', name: 'javaee-web-api', version: '8.0'
	compile group: 'javax.servlet.jsp', name: 'jsp-api', version: '2.2'
	compile group: 'org.springframework', name: 'spring-tx', version: '5.0.2.RELEASE'
	compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25'
	compile group: 'log4j', name: 'log4j', version: '1.2.17'
	compile group: 'org.slf4j', name: 'jcl-over-slf4j', version: '1.7.25'
	compile group: 'ch.qos.logback', name: 'logback-core', version: '1.2.3'
	compile group: 'ch.qos.logback', name: 'logback-access', version: '1.2.3'
	compile group: 'org.springframework', name: 'spring-core', version: '5.0.2.RELEASE'	
	compile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: '2.9.3'
	compile group: 'atg.taglib.json', name: 'json-taglib', version: '0.4.1'
    compile group: 'org.ops4j.pax.runner.profiles', name: 'felix.webconsole', version: '3.0.0'
	
	
	// https://mvnrepository.com/artifact/org.springframework/spring-test
	testCompile group: 'org.springframework', name: 'spring-test', version: '5.0.2.RELEASE'
	testCompile group: 'ch.qos.logback', name: 'logback-classic', version: '1.2.3'
	testCompile group: 'junit', name: 'junit', version: '4.12'
	
}


jettyRun{
	contextPath = "SpringMVCInterceptor2"
	httpPort = 8080
}

jettyRunWar{
	contextPath = "SpringMVCInterceptor2"
	httpPort = 8080
}


eclipse {

  wtp {
    component {
      
      //define context path, default to project folder name
      contextPath = 'SpringMVCInterceptor2'
      
   }
    }
 }

自定义拦截器

创建一个拦截控制器类, 命名为:GuestInterceptor,实现接口HandlerInterceptor,代码如下:

GuestInterceptor.java

package com.boraji.tutorial.spring.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class GuestInterceptor implements HandlerInterceptor {

   // Called before handler method invocation
   @Override
   public boolean preHandle(HttpServletRequest req, HttpServletResponse res,
         Object handler) throws Exception {
      System.out.println("Called before handler method");
      req.setAttribute("fname", "Elizabeth");
      return true;
   }

   // Called after handler method request completion, before rendering the view
   @Override
   public void postHandle(HttpServletRequest req, HttpServletResponse res, 
         Object handler, ModelAndView model)  throws Exception {
      System.out.println("Called after handler method request completion,"
            + " before rendering the view");

      model.addObject("lname", "Brown");
   }

   // Called after rendering the view
   @Override
   public void afterCompletion(HttpServletRequest req, HttpServletResponse res,
         Object handler, Exception ex)  throws Exception {
      System.out.println("Called after rendering the view");
   }
}

- 创建另外一个拦截类,命名为AdminInterceptor, 通过继承HandlerInterceptorAdapter类和重写postHandle()方法,具体如下:

AdminInterceptor.java

package com.boraji.tutorial.spring.interceptor;

import java.time.LocalTime;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class AdminInterceptor extends HandlerInterceptorAdapter {

   @Override
   public void postHandle(HttpServletRequest req, HttpServletResponse res,
         Object handler, ModelAndView model)  throws Exception {

      System.out.println("Called after handler method request completion,"
            + " before rendering the view");

      LocalTime time = LocalTime.now();
      int hrs = time.getHour();
      if (hrs >= 0 && hrs <= 12) {
         model.addObject("greeting", "Good morning!");
      } else if (hrs > 12 && hrs <= 17) {
         model.addObject("greeting", "Good afternoon!");
      } else {
         model.addObject("greeting", "Good evening!");
      }
   }
}

Spring配置+注册拦截器

WebConfig.java

package com.boraji.tutorial.spring.interceptor;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.boraji.tutorial.spring.interceptor" })
public class WebConfig extends WebMvcConfigurerAdapter {

   @Override
   public void addInterceptors(InterceptorRegistry registry) {
      // Register guest interceptor with single path pattern
      registry.addInterceptor(new GuestInterceptor()).addPathPatterns("/guest");

      // Register admin interceptor with multiple path patterns
      registry.addInterceptor(new AdminInterceptor())
              .addPathPatterns(new String[] { "/admin", "/admin/*" });
   }

   @Bean
   public InternalResourceViewResolver resolver() {
      InternalResourceViewResolver resolver = new InternalResourceViewResolver();
      resolver.setPrefix("/WEB-INF/views/");
      resolver.setSuffix(".jsp");
      return resolver;
   }

}

拦截器类

创建一个简单的拦截器类UserController , 用于处理访客和admin用户的请求.

UserController.java

package com.boraji.tutorial.spring.interceptor;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class UserController {

   @RequestMapping("/")
   public String index() {
      return "index";
   }

   @RequestMapping("/guest")
   public String guestHandler(@RequestAttribute("fname")String fname,Model model) {
      model.addAttribute("mname", "Smith");
      return "guest";
   }

   @RequestMapping("/admin")
   public String adminHandler(Model model) {
      model.addAttribute("name", "Mike");
      return "admin";
   }
}

JSP视图

在\src\main\webapp\WEB-INF\目录下, 创建views文件夹. 同时在\src\main\webapp\WEB-INF\views\下创建index.jsp,guest.jsp,admin.jsp三个文件.

index.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
  pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>BORAJI.COM</title>
</head>
<body>
  <h2>Spring MVC 4 - HandlerInterceptor example</h2>
  <p>
    <a href="guest">Guest</a> | <a href="admin">Admin</a>
  </p>
</body>
</html>

guest.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
  pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>BORAJI.COM</title>
</head>
<body>
  <h2>Spring MVC 4 - HandlerInterceptor example</h2>
  <h3>Guest user name is : ${fname} ${mname} ${lname}</h3>
</body>
</html>

admin.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
  pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>BORAJI.COM</title>
</head>
<body>
  <h2>Spring MVC 4 - HandlerInterceptor example</h2>
  <h3>${greeting} ${name}</h3>
</body>
</html>

Servlet窗口初始化

最后, 创建一个继承AbstractAnnotationConfigDispatcherServletInitializer 类的容器初始化类,用于引导Spring MVC的应用程序:

MyWebAppInitializer.java

package com.boraji.tutorial.spring.interceptor;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

   @Override
   protected Class<?>[] getRootConfigClasses() {
      return new Class[] {};
   }

   @Override
   protected Class<?>[] getServletConfigClasses() {
      return new Class[] { WebConfig.class };
   }

   @Override
   protected String[] getServletMappings() {
      return new String[] { "/" };
   }
}

AbstractAnnotationConfigDispatcherServletInitializer 类, 它实现了WebApplicationInitializer, 它的实现是为了使ServletContext 通过编程的方式在Servlet 3.0环境里配置.

Build+Deploy+Run application

如果你使用的是Maven,可以使用以下命令去编译运行.

- mvn clean install(它用于打war包)

-mvn tomcat7:run(它用于绑定tomcat7并且自动发布运行)

此例, 我使用的eclipse IDE直接启动运行:

项目名称鼠标右键->Run as ->Run on server.

通过访问http://localhost:8080/ 查看以下结果:

当你点击'Guest;链接时, 打开guest页面:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值