方法1:适用于POST请求,不适用于GET{}拼接参数
方法2:适用于模板,页面必须放到error文件夹下,不需要写任何java代码
方法3:适用于根据status值去判断,但是如果页面的图片地址是有动态参数,建议修改成相对引用,或者注入bean
目录
参考文章
前言
准备工作
404.html和ErrorCtrl
开始内部处理
所有访问
getPath()
applicationContext 之 ApplicationContextFactory
启动类SampleApplication
主要逻辑
404拦截处理WebMvcInterceptor
InterceptorConfig
效果图(略)
参考文章
获取本工程中有哪些请求路径
SpringBoot中使用ApplicationContext获取bean对象
SPRINGBOOT加入拦截器INTERCEPTOR
前言
有时候我们在登录网页的时候会发现,输入了错误的页面路径会变成如下页面:
实际上我们想要他能够跳转到404页面!那么这个需求该如何实现呢?
准备工作
404.html和ErrorCtrl
首先第一步我们先要画好404..html页面和对应的webctrl跳转做准备好:
import cloud.maque.biz.tdsc.config.properties.MaqueServiceProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Cookie;
@Controller
@RequestMapping("/error")
public class ErrorController {
@Autowired
MaqueServiceProperties maqueServiceProperties;
/*404 错误页面*/
@GetMapping("/404")
public String error404(Model model) {
model.addAttribute("subDomainUrl",maqueServiceProperties.getSubDomainUrl());
return "common/404";
}
}
开始内部处理
所有访问
getPath()
这里就比较重要了,我们需要当前访问的web浏览器路径和整个工程中的路径比对,那么前提要获取整个工程的web访问路径,如何获取呢?
参考文章:获取本工程中有哪些请求路径
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import java.util.*;
@Controller
@RequestMapping(value = "/test")
public class SpringBootTest {
@Autowired
ApplicationContext applicationContext;
@RequestMapping(value = "/getPath")
public
@ResponseBody
List getPath() {
Listlist = new ArrayList<>();
AbstractHandlerMethodMappingobjHandlerMethodMapping =
(AbstractHandlerMethodMapping) applicationContext.getBean("requestMappingHandlerMapping");
MapmapRet = objHandlerMethodMapping.getHandlerMethods();
for (RequestMappingInfo requestMappingInfo : mapRet.keySet()) {
Set set = requestMappingInfo.getPatternsCondition().getPatterns();
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
list.add(iterator.next().toString());
}
}
return list;
}
}
applicationContext 之 ApplicationContextFactory
问题随之而来,我要在内容中可以直接获取,那么就是需要一个applicationContext这个对象去手动调用,这个就用到了ApplicationContextFactory:
import org.springframework.context.ApplicationContext;
/**
* Created by xuhy on 2020/7/30.
* 手动获取applicationContext对象
*/
public class ApplicationContextFactory {
private static ApplicationContext applicationContext = null;
public static void setApplicationContext(ApplicationContext applicationContext) {
ApplicationContextFactory.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
}
启动类SampleApplication
然后在启动的时候放进去:
参考文章:SpringBoot中使用ApplicationContext获取bean对象
ConfigurableApplicationContext app = SpringApplication.run(SampleApplication.class, args);
ApplicationContextFactory.setApplicationContext(app);
主要逻辑
我们开始综上所述写404处理逻辑;
404拦截处理WebMvcInterceptor
这里包含了当前url和所有工程url比对:
import org.springframework.context.ApplicationContext;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
/**
* Created by xuhy on 2020/7/30.
* 拦截错误web请求
*/
public class WebMvcInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
// model.addAttribute("subDomainUrl",maqueServiceProperties.getSubDomainUrl());
// 获取所有请求路径
Listpaths = getPath();
// 匹配结果
Object[] result = paths.stream().filter(path -> path.equals(request.getRequestURI())).toArray();
if (result.length == 0) {
return true;
} else {
response.sendRedirect("/error/404");
return false;
}
}
/**
* 获取所有webe请求路径
* @return
*/
ListgetPath() {
Listlist = new ArrayList<>();
ApplicationContext applicationContext = ApplicationContextFactory.getApplicationContext();
AbstractHandlerMethodMappingobjHandlerMethodMapping =
(AbstractHandlerMethodMapping) applicationContext.getBean("requestMappingHandlerMapping");
MapmapRet = objHandlerMethodMapping.getHandlerMethods();
for (RequestMappingInfo requestMappingInfo : mapRet.keySet()) {
Set set = requestMappingInfo.getPatternsCondition().getPatterns();
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
list.add(iterator.next().toString());
}
}
return list;
}
}
InterceptorConfig
/**
* @description: web拦截器
* @author xuhy
* @date: 2020/7/31
*/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
// 如果没写@Bean 则需要通过new xx写,写了则 registry.addInterceptor(webMvcInterceptor()).addPathPatterns("/**")
@Bean
public WebMvcInterceptor webMvcInterceptor() {
return new WebMvcInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
//404.html blank.html 500.html 此方法添加拦截器
registry.addInterceptor(new WebMvcInterceptor()).addPathPatterns("/**");
}
}
值得注意的是
.excludePathPatterns("/js/**");
//404.html blank.html 500.html 此方法添加拦截器
registry.addInterceptor(new WebMvcInterceptor()).addPathPatterns("/**").
excludePathPatterns("/js/**", "/css/**", "/img/**","/api/**");
,不让然会出现图片访问正常的情况!!!
参考文章:SPRINGBOOT加入拦截器INTERCEPTOR
效果图(略)