使用拦截器的Java Spring MVC转发/重定向POST请求

时间:2014-02-13 15:59:28

标签: java spring spring-mvc post interceptor

我有一个Spring MVC应用程序,允许用户通过以下调用添加/删除收藏夹:

  • POST /api/users/123/favorites/456(将项目456添加为用户123的最爱)
  • DELETE /api/users/123/favorites/456(删除项目456作为用户123的最爱)

我还想支持以下2个完全相同的调用(假设用户123已登录):

  • POST /api/users/me/favorites/456
  • DELETE /api/users/me/favorites/456

我创建了一个拦截器,如下所示:

public class UserMeInterceptor extends HandlerInterceptorAdapter{
    public boolean preHandle( HttpServletRequest request, HttpServletResponse response, Object handler ) throws Exception{
        Integer userId = AccessControlUtil.getUserId();
        String redirectUrl = request.getContextPath() + request.getRequestURI().replace( "/me/", "/" + userId + "/" );
        if( redirectUrl.endsWith( "/me" ) ){
            redirectUrl = redirectUrl.replace( "/me", "/" + userId );
        }
        response.sendRedirect( redirectUrl );
        response.flushBuffer();
        return false;
    }
}

此方法效果很好,但仅适用于GET请求。我可以通过任何方式转发/重定向POST请求并维护所有POSTed数据和方法类型?理想情况下,我想重用已经定义的相同控制器来处理传入ID时的情况。

2 个答案:

答案 0 :(得分:4)

这种方法怎么样:

@RequestMapping("/api/users/{userId}/favorites/{favoriteId}")
public String clientsByGym(@PathVariable("userId") String userId, @PathVariable("favoriteId") Long favoriteId) {
    Integer theUserId = null;
    if("me".equals(userId)) {
        theUserId = AccessControlUtil.getUserId()
    } else {
        theUserId = Integer.valueOf(userId);
    }
    ...
}

基本上,让你的方法接受userId的String,然后从中可以看出它是'me'还是实际的userId值。这样您就不必乱用重定向。如果你必须一直这样做,你可以制作一个这样的辅助方法:

public Integer getUserId(String userId) { 
    return "me".equals(userId) ? AccessControlUtil.getUserId() : Integer.valueOf(userId);
}

答案 1 :(得分:1)

Spring MVC有两种执行属性转换的机制,但是这些在这种情况下无法以干净的方式提供帮助 - 请查看answer。这些并不仅仅意味着仅应用于一个String参数。

最好的方法是将一个方面应用于您希望使用此功能的控制器和方法,请参阅此answer以获取示例。