春批注与XML的混合问题 [英] Spring annotation with xml mixing problem
问题描述
我试图找到使用最新的Spring 3.0的最佳方式。我真的很喜欢适用于它的所有功能@RequestMapping注解。不过,我不喜欢的,就是绑定到动作的URL应该java文件指定完整。
I'm trying to find an optimal way to use the latest Spring 3.0. I really like the @RequestMapping annotation with all features applied to it. However, what I don't like, is that the URL bound to the action should be fully specified in the java file.
这将是最好的以某种方式发送整个网址结合配置的上下文xml文件。然而,它也将尽如果URL结合至少可以部分地转移到XML。
It would be the best to somehow send the whole url-binding configuration to the context xml file. However, it would also do if that url-binding could be moved to xml at least partially.
这是我的意思是:
当前code:
@Controller
@RequestMapping("myController")
class MyController {
@RequestMapping("**/someMethod")
String someMethod(...) {
}
}
这code结合myController的/到的someMethod :: myController的的someMethod。我不喜欢这里要说的是myController的部分结合也是这个Java文件。我想让它尽可能模块化,而这部分起着非常对我不好。
This code binds the myController/someMethod to MyController::someMethod. What I don't like here is that "myController" part binding is also in this java file. I want to make it as modular as possible, and this part plays very bad for me.
我想看到的是这样的事情,要达到同样的结果:
What I'd like to see is something like this, to achieve the same result:
context.xml中
<mapping>
<url>myController</url>
<controller>MyController</controller>
</mapping>
的Java
@Controller
//-- No request mapping here --// @RequestMapping("myController")
class MyController {
@RequestMapping("**/someMethod")
String someMethod(...) {
}
}
是这样的事情可能在注解控制器春3?
Is something like this possible on annotated controllers in Spring 3?
推荐答案
根据要求。你想为没有Spring控制器注释创建自己的URL模式。
As requested. You want to create your own URL pattern without Spring controllers annotations.
首先,创建一个CustomController注释为避免被@Controller <一个被检测href=\"http://static.springsource.org/spring/docs/2.5.6/api/org/springframework/web/servlet/mvc/annotation/DefaultAnnotationHandlerMapping.html\"相对=nofollow>的HandlerMapping
First of all, create a CustomController annotation To avoid to be detected by @Controller HandlerMapping
package br.com.ar.web.stereotype;
@Target(value=TYPE)
@Retention(value=RUNTIME)
@Component
public @interface CustomController {}
下面我们去AccountController中
Here goes our AccountController
@CustomController
public class AccountController {
public void form(Long id) {
// do something
}
}
我们的的HandlerAdapter - 它需要调用我们的控制器的护理 - 成才类似与Spring Validator接口的方法
Our HandlerAdapter - It takes care of calling our controller - Someting similar to Spring Validator interface approach
package br.com.ar.web.support;
public class CustomHandlerAdapter implements HandlerAdapter {
public boolean supports(Object handler) {
Annotation [] annotationArray = handler.getClass().getAnnotations();
for(Annotation annotation: annotationArray) {
/**
* Make sure your annotation contains @SomeController
*/
}
}
/**
* Third parameter is our CustomController
*/
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Method[] methods = handler.getClass().getMethods();
/**
* Logic To verify whether Target method fullfil request goes here
*/
/**
* It can be useful To see MultiActionController.invokeNamedMethod and MultiActionController.isHandlerMethod
*/
method.invoke(// parameters goes here);
}
public long getLastModified(HttpServletRequest request, Object handler) {
return -1;
}
}
最后,我们的HandlerMapping。确保您的HandlerMapping延伸WebApplicationObjectSupport。它可以让你通过调用
And finally, our HandlerMapping. Make sure your HandlerMapping extends WebApplicationObjectSupport. It allows you To retrieve any Spring managed bean by calling
getApplicationContext().getBean(beanName);
package br.com.ar.web.servlet.handler;
public class CustomeHandlerMapping extends WebApplicationObjectSupport implements HandlerMapping, Ordered {
private static final String CUSTOM_HANDLER_ADAPTER_NAME = "CUSTOM_HANDLER_ADAPTER_NAME";
/**
* Bind each URL path-CustomController bean name
*/
private final Map handlerMap = new LinkedHashMap();
/**
* Ordered interface will make sure your HandlerMapping should be intercepted BEFORE or AFTER DefaultAnnotationHandlerMapping
*/
public final void setOrder(int order) {
this.order = order;
}
public final int getOrder() {
return this.order;
}
/**
* HandlerMapping interface method
*/
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
String url = extractUrl(request);
if(handlerMap.get(url) == null) {
/**
* Because Spring 3.0 controller is stateful
* Let's just store CustomController class (Not an instance) in ApplicationContext
*
* Or use a FactoryBean to retrieve your CustomController
*/
handlerMap.put(url, getApplicationContext().getBean(beanName));
}
/**
* instantiateClass needs no-arg constructor
*/
Object handler = BeanUtils.instantiateClass(handlerMap.get(url));
return new HandlerExecutionChain(handler);
}
private String extractUrl(HttpServletRequest request) {
/**
* Here goes code needed To retrieve URL path from request
*
* Take a look at AntPathMatcher, UrlPathHelper and PathMatcher
*
* It can be useful To see AbstractUrlHandlerMapping.getHandlerInternal method
*/
}
}
不要忘记注册这两个的HandlerAdapter和HandlerMapping的
Do not forget register both HandlerAdapter and HandlerMapping
<bean id="br.com.ar.web.servlet.handler.CustomHandlerMapping"/>
<bean id="br.com.ar.web.support.CustomHandlerAdapter"/>
<!--To allow Spring 3.0 controller-->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
我希望它可以给你一个很好的开球
I hope it can gives you a good kick off
序列(幕后)Spring的DispatcherServlet会调用我们的对象是
The sequence (Behind The scenes) Spring DispatcherServlet will call our objects are
/**
* Our HandlerMapping goes here
*/
HandlerMapping handlerMapping = getHandler(request);
HandlerExecutionChain handlerExecutionChain = handlerMapping.getHandler(request);
for(HandlerInterceptor interceptor: handlerExecutionChain.getInterceptors) {
interceptor.preHandle(request, response, handlerExecutionChain.getHandler());
}
/**
* Our CustomController goes here
*/
Object handler = handlerExecutionChain.getHandler();
/**
* Our CustomHandlerAdapter goes here
*/
HandlerAdapter handlerAdapter = getHandlerAdapter(handler);
ModelAndView mav = handlerAdapter.handle(request, response, handler);
for(HandlerInterceptor interceptor: handlerExecutionChain.getInterceptors) {
interceptor.postHandle(request, response, handlerExecutionChain.getHandler());
}
这篇关于春批注与XML的混合问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!