我一直在寻找如何使用Spring 3.2.x管理REST API版本,但我找不到任何易于维护的东西.我先解释一下我遇到的问题,然后解决一个问题...但我想知道我是否在这里重新发明了这个问题.
我想基于Accept标头管理版本,例如,如果请求具有Accept标头application/vnd.company.app-1.1+json,我希望spring MVC将此转发给处理此版本的方法.并且由于并非API中的所有方法都在同一版本中发生更改,因此我不希望转到每个控制器并更改任何版本之间未更改的处理程序.我也不想有逻辑来确定控制器本身使用哪个版本(使用服务定位器),因为Spring已经发现了要调用的方法.
因此,采用版本1.0到1.8的API,其中版本1.0中引入了处理程序并在v1.7中进行了修改,我希望以下列方式处理它.想象一下,代码在控制器内部,并且有一些代码能够从头部中提取版本.(以下在Spring中无效)
@RequestMapping(...)
@VersionRange(1.0,1.6)
@ResponseBody
public Object method1() {
// so something
return object;
}
@RequestMapping(...) //same Request mapping annotation
@VersionRange(1.7)
@ResponseBody
public Object method2() {
// so something
return object;
}
Run Code Online (Sandbox Code Playgroud)
这在春天是不可能的,因为2个方法具有相同的RequestMapping注释并且Spring无法加载.这个想法是VersionRange注释可以定义一个开放或封闭的版本范围.第一种方法从版本1.0到1.6有效,而第二种方法从版本1.7开始(包括最新版本1.8).我知道如果有人决定通过99.99版本,这种方法会中断,但这是我可以忍受的.
现在,由于上面的内容是不可能的,如果没有对Spring的工作方式进行认真的修改,我就会考虑修改处理程序与请求匹配的方式,特别是编写我自己的方式ProducesRequestCondition,并在那里有版本范围.例如
码:
@RequestMapping(..., produces = "application/vnd.company.app-[1.0-1.6]+json)
@ResponseBody
public Object method1() {
// so something
return object;
}
@RequestMapping(..., produces = "application/vnd.company.app-[1.7-]+json)
@ResponseBody
public Object method2() {
// so something
return object;
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式,我可以在注释的产生部分中定义关闭或打开的版本范围.我工作的这个解决方案现在,随着我仍然不得不更换一些核心Spring MVC类(的问题RequestMappingInfoHandlerMapping …
到目前为止,<mvc:annotation-driven />给我带来了很多麻烦,所以我想摆脱它.尽管spring框架文档清楚地说明它应该做什么,但实际上summar的标签列表<mvc:annotation-driven /> 却缺乏.
所以我坚持删除<mvc:annotation-driven />,现在得到错误
WARN osweb.servlet.PageNotFound - 在名为'workoutsensor'的DispatcherServlet中找不到具有URI [/ webapp/trainees]的HTTP请求的映射
对于所有应该由控制器类解决的Url(在这种情况下:) ./trainees.有什么建议,我可以阅读更多关于<mvc:annotation-driven />?我非常想知道究竟是什么标签代表<mvc:annotation-driven />.
假设我们有一个使用Spring MVC和Spring Security配置的API端点.我们希望能够处理成对的@RequestMapping和@Secured注释,其中唯一的@Secured注释值因配对而异.这样,我们就可以根据同一请求的安全规则返回不同的响应主体.
这可以通过避免直接检查方法体中的安全规则来允许我们的代码更易于维护.
有一个不成功的例子,这是我们想要做的:
@Controller
@RequestMapping("/api")
public class Controller {
@Secured ({"ROLE_A"})
@RequestMapping(value="{uid}", method=RequestMethod.GET)
@ResponseBody
public Response getSomething(@PathVariable("uid") String uid) {
// Returns something for users having ROLE_A
}
@Secured ({"ROLE_B"})
@RequestMapping(value="{uid}", method=RequestMethod.GET)
@ResponseBody
public Response getSomethingDifferent(@PathVariable("uid") String uid) {
// Returns something different for users having ROLE_B
}
}
Run Code Online (Sandbox Code Playgroud)
我们怎样才能做到这一点?如果可以这样做:如何为同时拥有ROLE_A和ROLE_B的用户管理优先级?
我有一个Spring mvc(3.1.1)应用程序,我想定义条件超出RequestMapping中可用的条件.我有几件事我想用它.
首先,如果我可以为不同的用户类型显示不同的主页,那将是很好的:
@Controller
public class HomepageController {
@RequestMapping(value = "/")
@CustomCondition(roles = Guest.class)
public String guestHome() { /*...*/ }
@RequestMapping(value = "/")
@CustomCondition(roles = Admin.class)
public String adminHome() { /*...*/ }
}
Run Code Online (Sandbox Code Playgroud)
其次,我希望应用程序既可以作为网站也可以作为REST服务(例如移动应用程序),所以我想让网站访问html和json操作,并让服务(不同的子域)访问json动作(某种@CustomCondition(web = true)只与网站网址匹配)
这可以用于我正在计划的两种用途中的任何一种吗?
我发现很少有关于自定义条件的文档,但我确实找到了一个实现自定义条件的示例,这可能是我想要的,但它使用的是一个@Configuration类,而不是我正在使用的XML配置,我不想移动我的整个spring xml定义到一个@Configuration类.
我可以RequestMappingHandlerMapping在XML中定义customMethodCondition 吗?
我尝试了子类化RequestMappingHandlerMapping和覆盖getCustomMethodCondition,以返回我的自定义RequestCondition,但它没有工作 - getMatchingCondition()在我的条件下没有开火.
任何帮助将不胜感激!
UPDATE
我读了一点,看起来像是RequestMappingHandlerMapping一个新类(从3.1开始).
在我的应用程序中发生的是,尝试覆盖从而重新定义requestMappingHandlerMappingbean 的@Configuration 实际上有效,但是url映射(s中的@RequestMapping方法@Controller)似乎被处理两次,一次由子类处理 …