如何将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.jsp
和WEB-INF/views/other.jsp
。
结果:
-
http://localhost/myapp/
– >目录列表 -
http://localhost/myapp/ui
和http://localhost/myapp/ui/
– > index.jsp -
http://localhost/myapp/ui/other
和http://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模板