我有一个有效的@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应用程序时,我将此端点称为。问题是axios
HTTP客户端库将具有身份验证标头的 get 请求转换为 options 请求,以探测服务器的实际访问权限。
现在,我需要使用此 options 请求,并为 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网络终结点是在OPTIONS处理程序之前 处理的。 在Spring MVC中,我怎样才能真正将OPTIONS处理程序放在其他处理程序之前? 我希望它像拦截器一样
OR
实现所需行为的最佳实践方法是什么?我有点觉得我正在寻找更好的解决方案。
答案 0 :(得分: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
}