我有一个Spring MVC应用程序,它允许用户通过以下调用添加/删除收藏夹:
-
POST /api/users/123/favorites/456
(将项目 456 添加为用户 123 的收藏夹) -
DELETE /api/users/123/favorites/456
(删除作为用户 123 收藏的项目 456)
我还想支持以下 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 请求并维护所有 POST 数据和方法类型?理想情况下,我想重用已定义的同一控制器来处理传入 ID 时的情况。
这种方法怎么样:
@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的字符串,从那里你可以确定它是"我"还是实际的用户ID值。这样您就不必弄乱重定向。如果你必须一直这样做,你可以创建一个帮助程序方法,如下所示:
public Integer getUserId(String userId) {
return "me".equals(userId) ? AccessControlUtil.getUserId() : Integer.valueOf(userId);
}
Spring MVC 有两种进行属性转换的机制,但这些机制在这种情况下以干净的方式无济于事 - 检查此答案。这些参数不能选择性地只应用于一个 String 参数。
最好是将某个方面应用于需要此功能的控制器和方法,有关示例,请参阅此答案。