简体   繁体   中英

Not repeating a path twice in Spring 3.0 MVC Restful mappings

I'm mapping the url /modules/tips/SOME_ID/small to access the tip with id SOME_ID and to render it using the view small.jsp . The following code works great for this, however I am forced to repeat the string modules/tips in two places. Spring MVC doesn't seem to have a convention for this that I can determine. Other than using a constant, is there a better way to reduce this repetition?

@Controller
public class TipsController{

  @RequestMapping(value="/modules/tips/{tipId}/{viewName}",method=RequestMethod.GET)
  public ModelAndView get(
    @PathVariable String tipId,
    @PathVariable String viewName) {
    Tip tip = findTip(tipId);
    return new ModelAndView("modules/tips/" + viewName,"tip",tip);
  }
}

You view name mapping logic looks too "custom", so Spring hardly can offer some build-in support for it. Hovewer, as a theoretical possibility, you can implement a custom ModelAndViewResolver and register it in the AnnotationMethodHandlerAdapter

You can do what you're trying to do by simply omitting the view name, as long as your views match up with your URLs. If you don't provide a view name, Spring will use a RequestToViewNameTranslator to try to figure out a view name. You can look at the source for that class to see exactly how it work. Here's a good quote from the docs:

"... a request URL of ' http://localhost/registration.html ' will result in a logical view name of 'registration' being generated by the DefaultRequestToViewNameTranslator. This logical view name will then be resolved into the '/WEB-INF/jsp/registration.jsp' view by the InternalResourceViewResolver bean."

So it could, for example, make it so that a controller method handling "/modules/tips" would by default try to use a view named "modules/tips", presumably you would have a JSP at "/WEB-INF/jsp/modules/tips.jsp".

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-coc-r2vnt

EDIT: I just noticed that you said you tried omitting the view name, and it didn't seem like that worked. You could always write your own implementation of the RequestToViewNameTranslator and replace the DefaultRequestToViewNameTranslator with your own custom implentation. Check the docs for how to inject your own translator.

If you change your <url-pattern> element in web.xml to include modules/tips , you can effectively omit it from all of your Spring binding configuration:

<servlet-mapping>
        <servlet-name>spring-mvc</servlet-name>
        <url-pattern>/myapp/modules/tips/*</url-pattern>
</servlet-mapping>


@RequestMapping(value="/{tipId}/{viewName}",method=RequestMethod.GET)
public ModelAndView get(
    @PathVariable String tipId,
    @PathVariable String viewName) {
    Tip tip = findTip(tipId);
    return new ModelAndView(viewName,"tip",tip);
}

You can put a @requestMappings annotation on your class. The @requestMapping annotations on methods are then relative to this:

@Controller
@RequestMapping(value="/modules/tips")
public class TipsController{

    @RequestMapping(value="{tipId}/{viewName}",method=RequestMethod.GET)
    public ModelAndView get(
        @PathVariable String tipId,
        @PathVariable String viewName) {
        Tip tip = findTip(tipId);
        return new ModelAndView("modules/tips/" + viewName,"tip",tip);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM