Spring Controller 处理所有其他 Controller 不匹配的请求

Posted

技术标签:

【中文标题】Spring Controller 处理所有其他 Controller 不匹配的请求【英文标题】:Spring Controller to handle all requests not matched by other Controllers 【发布时间】:2016-08-04 07:51:32 【问题描述】:

我有一系列具有与特定 URL 匹配的请求映射的控制器。我还想要一个与其他控制器不匹配的任何其他 URL 匹配的控制器。 有没有办法在 Spring MVC 中做到这一点?例如,我是否可以拥有一个带有 @RequestMapping(value="**") 的控制器并更改 Spring 控制器的处理顺序,以便最后处理该控制器以捕获所有不匹配的请求?还是有另一种方法来实现这种行为?

【问题讨论】:

如果我理解正确,您想处理所有 404 吗?但可能做一些有用的事情,而不是返回“未找到”? 是的,你的想法会奏效。你试过了吗?以github.com/stormpath/spring-mvc-rest-exhandler/blob/master/… 为例 是的,我想要一种方法来处理与我制作的任何其他控制器都不匹配的 URL。 您在该链接中提供的默认控制器不会在其他 requestMappings 之前匹配吗? ***.com/questions/7276989/… 【参考方案1】:
@RequestMapping (value = "/**", method = RequestMethod.GET, RequestMethod.POST)
public ResponseEntity<String> defaultPath() 
    LOGGER.info("Unmapped request handling!");
    return new ResponseEntity<String>("Unmapped request", HttpStatus.OK);

这将以正确的控制器匹配顺序完成工作。不匹配时使用。

【讨论】:

这是有问题的。由于某种原因,这个控制器方法也捕获了对静态资源的请求。【参考方案2】:

如果您的基本网址是这样的 = http://localhost/myapp/ 其中 myapp 是您的上下文,那么 myapp/a.html、myapp/b.html myapp/c.html 将映射到以下控制器中的前 3 个方法。但是其他任何东西都会到达匹配**的最后一个方法。请注意,如果您将 ** 映射方法放在控制器顶部,则所有请求都将到达此方法。

然后这个控制器满足你的要求:

@Controller
@RequestMapping("/")
public class ImportController

    @RequestMapping(value = "a.html", method = RequestMethod.GET)
    public ModelAndView getA(HttpServletRequest req) 
        ModelAndView mv;
        mv = new ModelAndView("a");
        return mv;
    

    @RequestMapping(value = "b.html", method = RequestMethod.GET)
    public ModelAndView getB(HttpServletRequest req) 
        ModelAndView mv;
        mv = new ModelAndView("b");
        return mv;
    

    @RequestMapping(value = "c.html", method = RequestMethod.GET)
    public ModelAndView getC(HttpServletRequest req) 
        ModelAndView mv;
        mv = new ModelAndView("c");
        return mv;
    

@RequestMapping(value="**",method = RequestMethod.GET)
public String getAnythingelse()
return "redirect:/404.html";

【讨论】:

在这个配置之后,我的招摇停止了工作。 github.com/springfox/springfox/issues/2532 使用 @RequestMapping("/anything/") 而不是 @RequestMapping("/") 进行此配置 但这只会处理/anything下的非映射请求 然后从这个类中删除最后一个方法value="**",并使用自定义异常处理程序......这将确保任何非映射请求都进入某个404页面 异常处理程序不能解决我的问题,想在@RequestMapping 方法中处理它。无论如何谢谢和加1。【参考方案3】:

你应该使用“*”作为值,但在括号内

@RequestMapping(value="*", method=RequestMethod.GET, RequestMethod.POST)
public String allRequests() 
    return "index.html";

【讨论】:

以上是关于Spring Controller 处理所有其他 Controller 不匹配的请求的主要内容,如果未能解决你的问题,请参考以下文章

spring学习9 Spring工作原理及其作用

Spring中的统一异常处理

Spring中的统一异常处理方式

spring的全局自定义异常案例「完美拦截Controller层全部异常」

Spring MVC 常用注解@Controller,@RequestMapping,Model和ModelAndView

Thymeleaf视图不会将实体ID传递给Spring @Controller,而是将其与其他属性一起传递