春批注与XML的混合问题 [英] Spring annotation with xml mixing problem

查看:119
本文介绍了春批注与XML的混合问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找到使用最新的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆