0

我有一个可以工作的 @RestController 组件,它产生 API Web 端点。

这是这些端点之一

  @CrossOrigin
  @GetMapping(API_VERSION + PLAYER + METHOD_FETCH + "/{uid:^[0-9]*$}")
  public Player fetchPlayer(@PathVariable("uid") String uid) {
    return mongoTemplate.findById(uid, Player.class);
  }

现在,当使用我的 Vue.js 应用程序时,我调用了这个端点。问题是axioshttp 客户端库将具有身份验证标头的get请求转换为选项请求,以探测服务器以进行实际访问。

现在我需要使用这个选项请求并为CORS启用它。因此,我做了以下事情:

@RestController
@Log
@RequestMapping("/**")
public class AuthenticationEndpoint {
  @CrossOrigin
  @RequestMapping(method = RequestMethod.OPTIONS)
  public void handleOptionRequest(){
    log.info("option request handled");
  }
}

我将它映射到每个 url,因此它“应该”拦截每个 OPTIONS 请求。但事实并非如此。当有一个

GET http://{{host}}:80/api/v0.1/player/fetch/4607255831
Authorization: Basic MTIzNTM2NDMyNDphYmMxMjM=

更具体的 API Web 端点在 OPTIONS 处理程序之前处理。我如何才能在 Spring MVC 中将 OPTIONS 处理程序放在其他处理程序之前?我希望它像拦截器一样

或者

实现所需行为的最佳实践方法是什么?我有点觉得我在破解一个更好的解决方案。

4

1 回答 1

0

我如何才能在 Spring MVC 中将 OPTIONS 处理程序放在其他处理程序之前?我希望它起到拦截器的作用。

您可以创建一个组件,一个实现Filter接口的类并给它一个高阶:

@Component
@Order(1)
public class RequestInterceptor implements Filter {

    @Override
    public void doFilter
      ServletRequest request, 
      ServletResponse response, 
      FilterChain chain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        String httpMethod = req.getMethod();
        if(HttpMethod.OPTIONS.name().equals(httpMethod)){
           //do something here before reaching the method handler
        }
        chain.doFilter(request, response);

    }

    // other methods 
}

或者您可以在方法中扩展OncePerRequestFilter.java并进行与上述相同的检查doFilterInternal


编辑

如果您想控制是否继续处理捐赠请求,您可以使用HandlerInterceptor

在适当的 HandlerAdapter 触发处理程序本身的执行之前调用 HandlerInterceptor。这种机制可用于预处理方面的大领域,例如授权检查,或常见的处理程序行为,如语言环境或主题更改。它的主要目的是允许分解重复的处理程序代码。

HandlerInterceptor 基本上类似于 Servlet 过滤器,但与后者相比,它只允许自定义预处理和禁止执行处理程序本身的执行,以及自定义后处理。过滤器更强大,例如它们允许交换传递到链上的请求和响应对象。请注意,过滤器在 web.xml 中配置,它是应用程序上下文中的 HandlerInterceptor。

@Comonent
public class LoggerInterceptor extends HandlerInterceptorAdapter {
     @Override
     public boolean preHandle(HttpServletRequest request,
                          HttpServletResponse response,
                          Object handler)
                   throws Exception{
         // do checks and decide wether to complete or to stop here
         // true if the execution chain should proceed with the next interceptor or the handler itself. 
        // Else, DispatcherServlet assumes that this interceptor has already dealt with the response itself.
        return true;
     }
     // other methods
}
于 2019-04-28T11:03:08.583 回答