gpt4 book ai didi

tomcat - Apache Tomcat : how to prevent 404 status during [re]deployment

转载 作者:行者123 更新时间:2023-11-28 21:59:32 25 4
gpt4 key购买 nike

当我更改部署描述符(例如 apache-tomcat/conf/Catalina/localhost/myApp.xml)或用新版本替换 myApp.war 文件时我的 Web 应用程序停止并使用来自 myApp.xml 的更新配置或来自 myApp.war 的新应用程序版本再次启动。

进入上下文路径 /myApp 的请求将获得一个 404 状态错误页面,直到应用程序完全加载并能够为请求提供服务。

我想对此进行自定义并显示一个 503 temporary unavailable 错误页面。某处是否有配置指令?

到目前为止,我想到的解决方法包括:

  • 编辑 apache-tomcat/conf/web.xml 并将 org.apache.catalina.servlets.DefaultServlet 替换为根据需要响应的自定义 Servlet 实现。
  • 或者在 apache-tomcat/webapps/ROOT/ 中提供一个微型自定义 Web 应用程序以根据需要进行响应。

恕我直言,这些有点老套,我希望有人知道更轻量级的解决方案。我也知道部署相同上下文路径的多个版本的可能性(myApp##v001.xmlmyApp##v002.xml、...)但是并行运行的多个应用程序实例还不是一个选项。

最佳答案

我最终写了一个部署为 ROOT.war 的小 servlet。并检查给定请求是否存在具有匹配上下文路径的不可用(=已停止)部署。如果是,则返回 503 状态,否则返回 404。

为了访问外部部署,该应用程序依赖于 tomcat-catalina除了 servlet api:

<dependencies>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>${tomcatVersion}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>${tomcatVersion}</version>
<scope>provided</scope>
</dependency>
</dependencies>

并且它必须通过 context.xml 获得特权:

<Context privileged="true"/>

这是映射到 <url-pattern>/</url-pattern> 的 servlet :

package my.pkg;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.catalina.Container;
import org.apache.catalina.ContainerServlet;
import org.apache.catalina.Context;
import org.apache.catalina.Host;
import org.apache.catalina.Wrapper;

public class DefaultErrorPageServlet extends HttpServlet implements ContainerServlet {

private static final long serialVersionUID = 1L;
private Host host;
private Wrapper wrapper;

@Override
protected void doGet(final HttpServletRequest req, final HttpServletResponse resp)
throws ServletException, IOException {
if (matchesForeignUnavailableContextPath(req)) {
// 503 if there is an unavailabe deployment matching the request
sendUnavailable(resp);
} else {
// 404 if there is no unavailabe deployment matching the request
sendNotFound(resp);
}
}

@Override
protected void doPost(final HttpServletRequest req, final HttpServletResponse resp)
throws ServletException, IOException {
// Redirect to make the client GET the requested URL
resp.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
final String requestUrl = req.getRequestURL().toString();
resp.addHeader("Location", requestUrl);
}

private boolean matchesForeignUnavailableContextPath(HttpServletRequest req) {
if (null != host) {
Container[] children = host.findChildren();
for (Container container : children) {
String contextName = container.getName();
Context context = (Context) host.findChild(contextName);
if (null != context && !contextName.isEmpty()) {
String contextPath = context.getPath();
boolean started = context.getState().isAvailable();
String requestUri = req.getRequestURI();
if (!started && requestUri.startsWith(contextPath)) {
return true;
}
}
}
}
return false;
}

private void sendNotFound(HttpServletResponse resp) throws IOException {
resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
resp.getWriter().append(
// HTML document to show on 404 not found
);
}

private void sendUnavailable(HttpServletResponse resp) throws IOException {
resp.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
resp.getWriter().append(
// HTML document to show on 503 unavailable
);
}

@Override
public Wrapper getWrapper() {
return wrapper;
}

@Override
public void setWrapper(Wrapper wrapper) {
// see also org.apache.catalina.manager.ManagerServlet.setWrapper(Wrapper)
if (null == wrapper) {
return;
}
this.wrapper = wrapper;
final Context context = (Context) wrapper.getParent();
this.host = (Host) context.getParent();
}
}

关于tomcat - Apache Tomcat : how to prevent 404 status during [re]deployment,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54593627/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com