springboot 访问路径错误跳转到404(实现方法一)

  1. 方法1:适用于POST请求,不适用于GET{}拼接参数
  2. 方法2:适用于模板,页面必须放到error文件夹下,不需要写任何java代码
  3. 方法3:适用于根据status值去判断,但是如果页面的图片地址是有动态参数,建议修改成相对引用,或者注入bean
  • 目录

    参考文章

     前言

    准备工作

    404.html和ErrorCtrl

    开始内部处理

    所有访问

    getPath()

    applicationContext 之 ApplicationContextFactory

    启动类SampleApplication

    主要逻辑

    404拦截处理WebMvcInterceptor

    InterceptorConfig 

    效果图(略)


  • 参考文章

  1. 获取本工程中有哪些请求路径
  2. SpringBoot中使用ApplicationContext获取bean对象
  3. SPRINGBOOT加入拦截器INTERCEPTOR

  •  前言

有时候我们在登录网页的时候会发现,输入了错误的页面路径会变成如下页面:

springboot 访问路径错误跳转到404(实现方法一)_第1张图片

实际上我们想要他能够跳转到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() {
        List list = new ArrayList<>();
        AbstractHandlerMethodMapping objHandlerMethodMapping =
                (AbstractHandlerMethodMapping) applicationContext.getBean("requestMappingHandlerMapping");
        Map mapRet = 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);

springboot 访问路径错误跳转到404(实现方法一)_第2张图片

  • 主要逻辑

我们开始综上所述写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());

        // 获取所有请求路径
        List paths = 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
     */
    List getPath() {
        List list = new ArrayList<>();

        ApplicationContext applicationContext = ApplicationContextFactory.getApplicationContext();
        AbstractHandlerMethodMapping objHandlerMethodMapping =
                (AbstractHandlerMethodMapping) applicationContext.getBean("requestMappingHandlerMapping");

        Map mapRet = 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

  • 效果图(略)

 

你可能感兴趣的:(springboot 访问路径错误跳转到404(实现方法一))