如何将Spring MVC控制器映射到带有和不带斜杠的uri?

我有一个Spring Controller,它有几个RequestMappings用于不同的URI。 我的servlet是“ui”。 servlet的基URI仅适用于尾部斜杠。 我希望我的用户不必输入尾部斜杠。

这个URI有效:

http://localhost/myapp/ui/ 

这个没有:

 http://localhost/myapp/ui 

它给了我一个HTTP状态404消息。

我的web.xml中的servlet和映射是:

  ui org.springframework.web.servlet.DispatcherServlet 1   ui /ui/*  

我的控制器:

 @Controller public class UiRootController { @RequestMapping(value={"","/"}) public ModelAndView mainPage() { DataModel model = initModel(); model.setView("intro"); return new ModelAndView("main", "model", model); } @RequestMapping(value={"/other"}) public ModelAndView otherPage() { DataModel model = initModel(); model.setView("otherPage"); return new ModelAndView("other", "model", model); } } 

如果Web应用程序存在于Web服务器的webapps目录中,例如webapps/myapp/则可以在http://localhost:8080/myapp/访问此应用程序上下文的根目录,并假设使用默认的Tomcat端口。 这应该使用或不使用尾部斜杠, 我认为默认情况下 – Jetty v8.1.5中就是这种情况

一旦你点击/myapp ,Spring DispatcherServlet接管,将请求路由到web.xml配置的 ,在你的情况下是/ui/*

DispatcherServlet然后将所有请求从http://localhost/myapp/ui/路由到@Controller

Controller本身中,你可以使用@RequestMapping(value = "/*")作为mainPage()方法,这将导致http://localhost/myapp/ui/http://localhost/myapp/ui路由到mainPage()

注意:由于SPR-7064,您还应该使用Spring> = v3.0.3

为了完整性,以下是我测试过的文件:

的src /主/爪哇/控制器/ UIRootController.java

 package controllers; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; @Controller public class UiRootController { @RequestMapping(value = "/*") public ModelAndView mainPage() { return new ModelAndView("index"); } @RequestMapping(value={"/other"}) public ModelAndView otherPage() { return new ModelAndView("other"); } } 

WEB-INF / web.xml文件

    ui org.springframework.web.servlet.DispatcherServlet 1    ui /ui/*   

WEB-INF / UI-servlet.xml中

      

还有两个JSP文件,位于WEB-INF/views/index.jspWEB-INF/views/other.jsp

结果:

  • http://localhost/myapp/ – >目录列表
  • http://localhost/myapp/uihttp://localhost/myapp/ui/ – > index.jsp
  • http://localhost/myapp/ui/otherhttp://localhost/myapp/ui/other/ – > other.jsp

希望这可以帮助!

使用Springboot,我的应用程序可以通过在空字符串中设置@RequestMapping的“value”选项来回复斜杠和不斜杠:

 @RestController @RequestMapping("/some") public class SomeController { // value = "/" (default) , // would limit valid url to that with trailing slash. @RequestMapping(value = "", method = RequestMethod.GET) public Collection getAllStudents() { String msg = "getting all Students"; out.println(msg); return StudentService.getAllStudents(); } } 

PathMatchConfigurer api允许您配置与URL映射和路径匹配相关的各种设置。 根据最新版本的spring,默认情况下启用了路径路径匹配。 要进行自定义,请查看以下示例。

对于基于Java的配置

 @Configuration @EnableWebMvc public class AppConfig extends WebMvcConfigurerAdapter { @Override public void configurePathMatch(PathMatchConfigurer configurer) { configurer.setUseTrailingSlashMatch(true); } } 

对于基于XML的配置

    

对于@RequestMapping(“/ foo”),如果尾部斜杠匹配设置为false ,则为example.com/foo/!= example.com/foo,如果设置为true (默认值),则为example.com/foo/ == example .COM /富

干杯!

我最终添加了一个新的RequestMapping来将/ ui请求重定向到/ ui /。 还从mainPage的RequestMapping中删除了空字符串映射。 web.xml不需要编辑。

在我的控制器中结束了这样的事情:

  @RequestMapping(value="/ui") public ModelAndView redirectToMainPage() { return new ModelAndView("redirect:/ui/"); } @RequestMapping(value="/") public ModelAndView mainPage() { DataModel model = initModel(); model.setView("intro"); return new ModelAndView("main", "model", model); } @RequestMapping(value={"/other"}) public ModelAndView otherPage() { DataModel model = initModel(); model.setView("otherPage"); return new ModelAndView("other", "model", model); } 

现在,URL http://myhost/myapp/ui重定向到http://myhost/myapp/ui/ ,然后我的控制器显示介绍页面。

我发现的另一个解决方案是不为mainPage()的请求映射赋值:

 @RequestMapping public ModelAndView mainPage() { DataModel model = initModel(); model.setView("intro"); return new ModelAndView("main", "model", model); } 

尝试添加

@RequestMapping(method = RequestMethod.GET) public String list() { return "redirect:/strategy/list"; }

结果:

  @RequestMapping(value = "/strategy") public class StrategyController { static Logger logger = LoggerFactory.getLogger(StrategyController.class); @Autowired private StrategyService strategyService; @Autowired private MessageSource messageSource; @RequestMapping(method = RequestMethod.GET) public String list() { return "redirect:/strategy/list"; } @RequestMapping(value = {"/", "/list"}, method = RequestMethod.GET) public String listOfStrategies(Model model) { logger.info("IN: Strategy/list-GET"); List strategies = strategyService.getStrategies(); model.addAttribute("strategies", strategies); // if there was an error in /add, we do not want to overwrite // the existing strategy object containing the errors. if (!model.containsAttribute("strategy")) { logger.info("Adding Strategy object to model"); Strategy strategy = new Strategy(); model.addAttribute("strategy", strategy); } return "strategy-list"; } 

**学分:

高级@RequestMapping技巧 – 控制器根和URI模板