栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Springboot 修改内置tomcat全局ErrorPage

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Springboot 修改内置tomcat全局ErrorPage

一、引出

springboot 1.5.22
配置了 server.context-path=/web/v1
我们知道这时访问非该前缀的页面都会报404
现在有个需求,之前的微服客户端如何不通过额外配置,知道新服务的api前缀?
我刚开始的想法是,给一个固定api路径的接口,返回前缀信息。
但是很难做,因为在springmvc全家桶太上层,controller是由dispatcherServlet分发的,
servlet躲在container后面,tomcat的container分好多层,context-path 在context这一层。
所以不管你怎么绕着spring全家桶加东西,最后都会有/web/v1前缀

后续想法是给内置tomcat加新的context,也太复杂,否定了。

改tomcat全局的error page是不错的做法

二、ErrorReportValue

还是上面的问题,你抱着spring全家桶改诸如error handler,最后都只对/web/v1下的请求生效。
这时候搜stackoverflow,发现StandardHost一个属性 errorReportValveClass
这个class就是处理错误请求返回的页面的,那就自定义一个

public class ApiHome404ErrorPageReport extends ErrorReportValve {
	public static String API_HOME;
	@Override
	protected void report(Request request, Response response, Throwable throwable) {
		if (response.getStatus() == HttpStatus.NOT_FOUND.value()) {
			try (Writer p = response.getWriter()) {
				p.write(CommonConstatnt.API_HOME_WITH_404_PREFIX + API_HOME);
			} catch (IOException e) {
				log.error("cannot write 404 result to http response, maybe already closed by client.", e);
			}
		} else {
			super.report(request, response, throwable);
		}
	}
}
三、获取Host并设置

通过Spring提供的customizer 可以把值设置进去。

@Configuration
public class WebConfig implements TomcatContextCustomizer, EmbeddedServletContainerCustomizer {
	
	@Value("${server.context-path:/}")
	private String apiHome;	

	@Override
	public void customize(Context context) {
		if (StringUtils.isNotBlank(apiHome) && !"/".equals(apiHome.replaceAll("/+", "/"))) {
			Container parent = context.getParent();
			if (parent instanceof StandardHost) {
				ApiHome404ErrorPageReport.API_HOME = apiHome;
				((StandardHost) parent).setErrorReportValveClass(ApiHome404ErrorPageReport.class.getName());
			}
		}
	}

	@Override
	public void customize(ConfigurableEmbeddedServletContainer container) {
		if (container instanceof TomcatEmbeddedServletContainerFactory) {
			((TomcatEmbeddedServletContainer) container).addContextCutomizers(this);
		}
	}
}

以上之后就能在404时,返回目前应用的api home信息供客户端进一步操作。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/712679.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号