Spring-在调用控制器的方法之前执行代码

时间:2019-01-25 11:29:15

标签: java spring

在调用Controller中的方法之前,是否可以使用类似于@PreAuthorize@PreFilter的注释来运行代码?

我需要将信息添加到请求上下文(特定于被调用的方法)中,然后由ExceptionHandler检索。

例如

@RestController
public MyController{

  @UnkwonwAnnotation("prepareContext(request.getAgentId())"){
  public ResponseEntity method1(RequestA requestA) {
    ...
  }

  @UnkwonwAnnotation("prepareContext(request.getUserName())"){
  public ResponseEntity method1(RequestB requestB) {
    ...
  }

}

我实际上可以只使用@PreAuthorize,但感觉不正确

4 个答案:

答案 0 :(得分:4)

Spring Aspect也是在控制器之前执行代码的好选择。

@Component
@Aspect
public class TestAspect {

    @Before("execution(* com.test.myMethod(..)))")
    public void doSomethingBefore(JoinPoint jp) throws Exception {

        //code  
    }
}

这里myMethod()将在控制器之前执行。

答案 1 :(得分:3)

您可以为此添加拦截器

样本拦截器

Public class CustomInterceptor implements HandlerInterceptor{


    @Override
    public boolean preHandle(HttpServletRequest request,HttpServletResponse  response){
    //Add Login here 
        return true;
    }
} 

配置

@Configuration
public class MyConfig extends WebMvcConfigurerAdapter{
    @Override
    public void addInterceptors(InterceptorRegistry registry){
        registry.addInterceptor(new MyCustomInterceptor()).addPathPatterns("/**");
    }
}

希望这会有所帮助

答案 2 :(得分:0)

也许一个不错的选择是实现一个自定义过滤器,该过滤器在每次收到请求时都会运行。

您需要扩展“ OncePerRequestFilter”并覆盖方法“ doFilterInternal”

public class CustomFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {

        //Add attributes to request
        request.getSession().setAttribute("attrName", new String("myValue"));

        // Run the method requested by petition
        filterChain.doFilter(request, response);

        //Do something after method runs if you need.

    }
}

必须在Spring中使用FilterRegistrationBean注册过滤器之后。如果您具有Spring安全性,则需要在安全性过滤器之后添加过滤器。

答案 3 :(得分:0)

扩展Sai Prateek的答案,我创建了一个自定义注释:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OperationContext {

  String clientId();

  String userId();

  String operation();
}

和处理它的组件:

@Aspect
@Component
public class OperationContextAspect {

  @Before(value = "@annotation(operationContext)", argNames = "operationContext")
  public void preHandle(OperationContext operationContext) {

    RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

    requestAttributes.setAttribute("operation", operationContext.operation, RequestAttributes.SCOPE_REQUEST);
    requestAttributes.setAttribute("clientId", operationContext.clientId(), RequestAttributes.SCOPE_REQUEST);
    requestAttributes.setAttribute("userId", operationContext.userId(), RequestAttributes.SCOPE_REQUEST);

  }
}

然后我注释提供所需参数的控制器方法:

@RestController
public class MyController {

  @OperationContext(clientId = '#request.getClientId', userId = '#request.getUserId', operation = "OPERATION_A")
  public ResponseEntity aMethod(MyRequest request) {
    ...
  }
}