spring boot添加http请求拦截器

ris*_*p89 90 java spring spring-mvc spring-boot

在Spring启动应用程序中添加HttpRequest拦截器的正确方法是什么?我想要做的是为每个http请求记录请求和响应.

Spring启动文档根本不涉及此主题.(http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/)

我发现了一些关于如何对旧版本的spring执行相同操作的Web示例,但这些示例与applicationcontext.xml一起使用.请帮忙.

iku*_*men 138

由于您使用的是Spring Boot,我认为您更愿意尽可能依赖Spring的自动配置.要添加其他自定义配置(如拦截器),只需提供配置或bean WebMvcConfigurerAdapter.

这是一个配置类的示例:

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

  @Autowired 
  HandlerInterceptor yourInjectedInterceptor;

  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(...)
    ...
    registry.addInterceptor(getYourInterceptor()); 
    registry.addInterceptor(yourInjectedInterceptor);
    // next two should be avoid -- tightly coupled and not very testable
    registry.addInterceptor(new YourInterceptor());
    registry.addInterceptor(new HandlerInterceptor() {
        ...
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

注意如果要保留mvc的Spring Boots自动配置,请不要使用@EnableWebMvc对此进行注释.

  • 在Spring 5中,只需实现WebMvcConfigurer而不是扩展WebMvcConfigurerAdapter。由于Java 8接口允许默认实现,因此不再需要使用适配器(这是不推荐使用的原因)。 (7认同)
  • 在yourInjectedInceptor上使用@Component注释 (6认同)
  • 我收到错误消息“ WebMvcConfigurerAdapter类型已弃用”。我正在使用Spring Web MVC 5.0.6 (3认同)

sed*_*ooe 66

WebMvcConfigurerAdapter将在Spring 5中弃用.来自它的Javadoc:

@deprecated从5.0开始{@link WebMvcConfigurer}具有默认方法(由Java 8基线实现),可以直接实现而无需此适配器

如上所述,您应该做的是实现WebMvcConfigurer和覆盖addInterceptors方法.

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyCustomInterceptor());
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 你的答案是不完整的,因为它缺少`MyCustomInterceptor`的实现 (7认同)
  • @peterchaula 我希望你是在开玩笑...... (3认同)
  • @AndriiDzhyrma,您必须编写完全初学者可以理解的代码。看看这个完整的答案,你就会明白我的意思。/sf/answers/2947914861/ (2认同)

sun*_*tha 27

要将拦截器添加到Spring引导应用程序,请执行以下操作

  1. 创建一个拦截器类

    public class MyCustomInterceptor implements HandlerInterceptor{
    
        //unimplemented methods comes here. Define the following method so that it     
        //will handle the request before it is passed to the controller.
    
        @Override
        public boolean preHandle(HttpServletRequest request,HttpServletResponse  response){
        //your custom logic here.
            return true;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 定义配置类

    @Configuration
    public class MyConfig extends WebMvcConfigurerAdapter{
        @Override
        public void addInterceptors(InterceptorRegistry registry){
            registry.addInterceptor(new MyCustomInterceptor()).addPathPatterns("/**");
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 而已.现在,您的所有请求都将通过MyCustomInterceptor的preHandle()方法中定义的逻辑.


Ng *_*Qin 19

我在这个网站上找到了一个很好的教程,介绍如何使用注释向特定控制器添加请求拦截器:

  1. 定义注释
  2. 定义拦截器
  3. 将拦截器添加到路径中
  4. 在特定控制器上使用注释

https://programmer.group/how-do-spring-boot-2.x-add-interceptors.html

我知道这个问题是如何向所有请求添加拦截器,并且已经得到解答。我正在搜索使用注释向特定控制器添加请求拦截器的解决方案,但在 stackoverflow 中找不到解决方案。决定将此内容添加到此问题中,而不是提出新问题。

定义注解NeedLogin.class

package com.example.helloSpringBoot.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface NeedLogin {
}
Run Code Online (Sandbox Code Playgroud)

然后定义inceptor类

package com.example.helloSpringBoot.config;

import com.example.helloSpringBoot.annotation.NeedLogin;
import com.example.helloSpringBoot.util.WxUserInfoContext;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

/**
 * Logon interceptor
 *
 * @Author: Java Fragment
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {

    //This method is executed before accessing the interface. We only need to write the business logic to verify the login status here to verify the login status before the user calls the specified interface.
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        if (handler instanceof HandlerMethod) {
            NeedLogin needLogin = ((HandlerMethod) handler).getMethodAnnotation(NeedLogin.class);
            if (null == needLogin) {
                needLogin = ((HandlerMethod) handler).getMethod().getDeclaringClass()
                        .getAnnotation(NeedLogin.class);
            }
            // Check login if you have login validation annotations
            if (null != needLogin) {
                WxUserInfoContext curUserContext = (WxUserInfoContext) request.getSession()
                        .getAttribute("curUserContext");
                //If session No, not logged in.
                if (null == curUserContext) {
                    response.setCharacterEncoding("UTF-8");
                    response.getWriter().write("Not logged in!");
                    return false;
                }
            }

        }
        return true;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
    }
}
Run Code Online (Sandbox Code Playgroud)

然后将inceptor添加到WebConfig中

package com.example.helloSpringBoot.config;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * WebConfig
 *
 * @Author: Java Fragment
 *
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private LoginInterceptor loginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // Custom interceptor, add intercept path and exclude intercept path
        registry.addInterceptor(loginInterceptor).addPathPatterns("/**");
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,您可以使用新注释 @NeedLogin 自由使用新拦截器

package com.example.helloSpringBoot.controller;

import com.example.helloSpringBoot.annotation.NeedLogin;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    /**
     * Testing does not require login
     *
     *
     */
    @RequestMapping("/testNoLogin")
    public String testNoLogin (){
        return "The call is successful, this interface does not need login validation!-Java Broken read!";
    }

    /**
     * Testing requires login
     *
     *
     */
    @NeedLogin
    @RequestMapping("/testNeedLogin")
    public String testNeedLogin (){
        return "testNeedLogin!";
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 9

我有同样的问题WebMvcConfigurerAdapter被弃用.当我搜索示例时,我几乎找不到任何实现的代码.这是一段工作代码.

创建一个扩展HandlerInterceptorAdapter的类

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import me.rajnarayanan.datatest.DataTestApplication;
@Component
public class EmployeeInterceptor extends HandlerInterceptorAdapter {
    private static final Logger logger = LoggerFactory.getLogger(DataTestApplication.class);
    @Override
    public boolean preHandle(HttpServletRequest request, 
            HttpServletResponse response, Object handler) throws Exception {

            String x = request.getMethod();
            logger.info(x + "intercepted");
        return true;
    }

}
Run Code Online (Sandbox Code Playgroud)

然后实现WebMvcConfigurer接口

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import me.rajnarayanan.datatest.interceptor.EmployeeInterceptor;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Autowired
    EmployeeInterceptor employeeInterceptor ;

    @Override
    public void addInterceptors(InterceptorRegistry registry){
        registry.addInterceptor(employeeInterceptor).addPathPatterns("/employee");
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如何在没有编译问题的情况下只覆盖接口上的一个方法? (3认同)
  • @arjun由于Java 8,其他实现为[默认方法](https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html)。此推理很方便,[已记录](https弃用的类中的://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.html)。 (2认同)

Mag*_*nus 7

您还可以考虑添加一个SpringSandwich依赖项,它允许您直接在控制器中注释要应用的拦截器,就像您注释url路由一样(披露:我是作者).

https://github.com/arikast/springsandwich


Xen*_*ite 7

Since all responses to this make use of the now long-deprecated abstract WebMvcConfigurer Adapter instead of the WebMvcInterface (as already noted by @sebdooe), here is a working minimal example for a SpringBoot (2.1.4) application with an Interceptor:

Minimal.java:

@SpringBootApplication
public class Minimal
{
    public static void main(String[] args)
    {
        SpringApplication.run(Minimal.class, args);
    }
}
Run Code Online (Sandbox Code Playgroud)

MinimalController.java:

@RestController
@RequestMapping("/")
public class Controller
{
    @GetMapping("/")
    @ResponseBody
    public ResponseEntity<String> getMinimal()
    {
        System.out.println("MINIMAL: GETMINIMAL()");

        return new ResponseEntity<String>("returnstring", HttpStatus.OK);
    }
}
Run Code Online (Sandbox Code Playgroud)

Config.java:

@Configuration
public class Config implements WebMvcConfigurer
{
    //@Autowired
    //MinimalInterceptor minimalInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry)
    {
        registry.addInterceptor(new MinimalInterceptor());
    }
}
Run Code Online (Sandbox Code Playgroud)

MinimalInterceptor.java:

public class MinimalInterceptor extends HandlerInterceptorAdapter
{
    @Override
    public boolean preHandle(HttpServletRequest requestServlet, HttpServletResponse responseServlet, Object handler) throws Exception
    {
        System.out.println("MINIMAL: INTERCEPTOR PREHANDLE CALLED");

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception
    {
        System.out.println("MINIMAL: INTERCEPTOR POSTHANDLE CALLED");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) throws Exception
    {
        System.out.println("MINIMAL: INTERCEPTOR AFTERCOMPLETION CALLED");
    }
}
Run Code Online (Sandbox Code Playgroud)

works as advertised

The output will give you something like:

> Task :Minimal.main()

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.4.RELEASE)

2019-04-29 11:53:47.560  INFO 4593 --- [           main] io.minimal.Minimal                       : Starting Minimal on y with PID 4593 (/x/y/z/spring-minimal/build/classes/java/main started by x in /x/y/z/spring-minimal)
2019-04-29 11:53:47.563  INFO 4593 --- [           main] io.minimal.Minimal                       : No active profile set, falling back to default profiles: default
2019-04-29 11:53:48.745  INFO 4593 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2019-04-29 11:53:48.780  INFO 4593 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-04-29 11:53:48.781  INFO 4593 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.17]
2019-04-29 11:53:48.892  INFO 4593 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-04-29 11:53:48.893  INFO 4593 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1269 ms
2019-04-29 11:53:49.130  INFO 4593 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-04-29 11:53:49.375  INFO 4593 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2019-04-29 11:53:49.380  INFO 4593 --- [           main] io.minimal.Minimal                       : Started Minimal in 2.525 seconds (JVM running for 2.9)
2019-04-29 11:54:01.267  INFO 4593 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-04-29 11:54:01.267  INFO 4593 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2019-04-29 11:54:01.286  INFO 4593 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 19 ms
MINIMAL: INTERCEPTOR PREHANDLE CALLED
MINIMAL: GETMINIMAL()
MINIMAL: INTERCEPTOR POSTHANDLE CALLED
MINIMAL: INTERCEPTOR AFTERCOMPLETION CALLED
Run Code Online (Sandbox Code Playgroud)

  • 不,它是一个具有空默认实现的 (Java 8) 接口 (2认同)