Announcement Announcement Module
Collapse
No announcement yet.
Spring Servlet MVC RequestMapping breaks with AOP Advice Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring Servlet MVC RequestMapping breaks with AOP Advice

    To start off, I have searched the web and forums thoroughly and couldn't find anybody having the same problem. I have been working with Spring 3 for nearly a year now and for the past six months have been successfully using Spring @MVC to create and autowire all of my beans/dependencies and map requests to my many controllers using the @RequestMapping annotation. My configuration has been working fine for some time now...

    I am using Spring 3.0.2-RELEASE-A in JDK 1.6.0_20, running under Tomcat 6. I don't have any errors on start-up at all and appear to have all necessary dependencies included in my project. My project package structure is assumed to be com.my.package.... and my application has a myapp-servlet.xml and an applicationContext.xml in the WEB-INF directory.

    I followed the procedures outlined in http://static.springsource.org/sprin...#aop-ataspectj and have spent several hours reading the documentation on that page and for AspectJ.

    I recently added AOP AspectJ autoproxy to my myapp-servlet.xml file like so:

    Code:
    ...
    	<context:component-scan base-package="com.my.package"/>
    	<context:component-scan base-package="someOtherPackage"/>
    	<context:annotation-config/>
    	<aop:aspectj-autoproxy/>
    ...
    Note that only the "aop:" tag is new ... the other three tags were already there. I then defined the following bean, per the documentation:

    Code:
    @Aspect
    @Component
    public class AnnotationParameterValidatorProxy
    {
    	private Validator validator;
    
    	public AnnotationParameterValidatorProxy()
    	{
    
    	}
    
    	@Autowired
    	public void setValidator(Validator validator)
    	{
    		this.validator = validator;
    	}
    
    	@Pointcut("execution(* com.my.package..*.*(..))")
    	public void methodRequestingValidBean() { }
    
    	@Before("methodRequestingValidBean()")
    	public void validate(JoinPoint joinPoint)
    	{
    		// code that does stuff
    	}
    }
    Please forget, for a moment, that my pointcut definition is very broad (it matches every method in my application). I plan on narrowing it down eventually, but I need to get it working first.

    This bit of code successfully intercepts methods in my package and everything looks like it's working. However, now NONE of my controller methods annotated with @RequestMapping work. Instead, every page I try to go to, this error gets logged:

    Code:
    2010-07-19 11:24:55,461 2797    [ttp-8080-1] WARN  org.springframework.web.servlet.PageNotFound.noHandlerFound - No mapping found for HTTP request with URI [/myapp/do/something] in DispatcherServlet with name 'myapp'
    Taking the simple line <aop:aspectj-autoproxy/> out of my myapp-servlet.xml is enough to get my request mappings to work again, but then obviously my pointcut is broken. Additionally, if I change my pointcut to point to a more granular package or a specific class, all of the request mappings not in that package/class work again, but that's not an option for me. Any clue what I'm doing wrong here?

    Thanks,

    Nick

  • #2
    Post a controller and try forcing the use of classproxies.

    Comment


    • #3
      Here's the code for a controller. The controller maps all requests for /config/*. The first method maps /config/home, /config/accounts, /config, /config/, /config/[everything else not mapped] and the second method maps /config/json/listAccounts. Again, this controller worked perfectly before turning on my pointcut...

      Code:
      @Controller
      @RequestMapping("config")
      public class AccountConfigController implements ServletConfigAware
      {
      	protected Log logger = LogFactory.getLog(AccountConfigController.class);
      	
      	...
      
      	@RequestMapping(value={"", "*", "home", "accounts"}, method={RequestMethod.GET, RequestMethod.POST})
      	public ModelAndView displayAccounts(Map<String, Object> model, HttpServletRequest request)
      	{
      		...
      
      		return new ModelAndView("config/index");
      	}
      
      	@RequestMapping(value={"json/listAccounts"}, method={RequestMethod.GET, RequestMethod.POST})
      	public View listAccounts(Map<String, Object> model, HttpServletRequest request)
      	{
      		...
      
      		return new MappingJacksonJsonView();
      	}
      	
      	...
      }
      I'll try out forcing class proxies...

      Comment


      • #4
        I suggest a read of the aop chapter of the reference guide. Spring by default uses interface based proxies, you are implementing an interface and thus you get a interface based proxy. Hence my advice to create class proxies...

        Comment


        • #5
          You gut advice at the beginning was correct Marten. As you said later, I'm implementing an interface so only that interface was being proxied, and all my non-interface @RequestMapping methods were being ignored. When I forced the use of class proxies using CGLIB, everything started working exactly like I wanted it to.

          Thanks!

          Comment

          Working...
          X