views:

269

answers:

2

Using annotation-based controller mappings.

@Controller
public class AlertsController {

  @RequestMapping(value="create", method=RequestMethod.GET)
  public void create(HttpServletRequest request, Model model) {
  }
}

When access alerts/create, I get the message Does your handler implement a supported interface like Controller?. This seems odd, and counter to what the documentation says.

So, I add in a RequestMapping to the class:

@Controller
@RequestMapping("/alerts")
public class AlertsController {

  @RequestMapping(value="create", method=RequestMethod.GET)
  public void create(HttpServletRequest request, Model model) {
  }
}

This, then, works. I shouldn't need either @RequestMapping, but I do. Now, things get weird. I really wanted to map this to `/profile/alerts', so I change it to this:

@Controller
@RequestMapping("/profile/alerts")
public class AlertsController {

  @RequestMapping(value="create", method=RequestMethod.GET)
  public void create(HttpServletRequest request, Model model) {
  }
}

I get a 404 when going to profile/alerts/create, but it's still mapped to /alerts/create for some reason?!?!?!

I change it to:

@Controller
@RequestMapping("foobar")
public class AlertsController {

  @RequestMapping(value="create", method=RequestMethod.GET)
  public void create(HttpServletRequest request, Model model) {
  }
}

This is very strange and incredibly inconvenient. Anyone have a way to fix this, or even debug what is going on?

+2  A: 

In your first snippet you missed the leading /. It should be something like @RequestMapping(value="/create", method=RequestMethod.GET)

Now you should change your third snippet to this,

@Controller
public class AlertsController {

  @RequestMapping(value="/profile/alerts/create", method=RequestMethod.GET)
  public void create(HttpServletRequest request, Model model) {
  }
}

Moreover, as you are making your method void which expect the DispatcherServlet to fall back on the default view name of "profile/alerts/create". And then it is combined with a suitable view resolver. For example,

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/jsp/" />
    <property name="suffix" value=".jsp" />
</bean>

And there you got 404, may be.

Adeel Ansari
I had the view resolver, and this did work. The weird thing is that I thought the `@RequestMapping` annotations on methods were refinements of the class-level annotation; it seems not.
davetron5000
A: 

You can do url matching on both the class annotation and more finegrained on the methods. The class level annotation gets prepended to the method level annotation

@Controller
@RequestMapping(value = "/admin")
public class AdminController {

  @RequestMapping(value = "/users", method = RequestMethod.GET)
  /* matches on /admin/users */
  public string users() {  ...  }
}

It's very close to your original third snippet except you forgot a leading /.

NA