怎么通过tomcat中ManagerServlet远程部署项目
发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,这篇文章将为大家详细讲解有关怎么通过tomcat中ManagerServlet远程部署项目,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。介绍之前在邮政实习时,lea
千家信息网最后更新 2026年11月04日怎么通过tomcat中ManagerServlet远程部署项目
这篇文章将为大家详细讲解有关怎么通过tomcat中ManagerServlet远程部署项目,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
介绍
之前在邮政实习时,leader让我阅读tomcat的源代码,尝试自己实现远程部署项目的功能,于是便有了这此实践。
在Tomact中有一个Manager应用程序,它是用来管理已经部署的web应用程序,在这个应用程序中,ManagerServlet是他的主servlet,通过它我们可以获取tomcat的部分指标,远程管理web应用程序,不过这个功能会受到web应用程序部署中安全约束的保护。
当你请求ManagerServlet时,它会检查getPathInfo()返回的值以及相关的查询参数,以确定被请求的操作。它支持以下操作和参数(从servlet路径开始):
| 请求路径 | 描述 |
|---|---|
| /deploy?config={config-url} | 根据指定的path部署并启动一个新的web应用程序(详见源码) |
| /deploy?config={config-url}&war={war-url}/ | 根据指定的pat部署并启动一个新的web应用程序(详见源码) |
| /deploy?path=/xxx&war={war-url} | 根据指定的path部署并启动一个新的web应用程序(详见源码) |
| /list | 列出所有web应用程序的上下文路径。格式为path:status:sessions(活动会话数) |
| /reload?path=/xxx | 根据指定path重新加载web应用 |
| /resources?type=xxxx | 枚举可用的全局JNDI资源,可以限制指定的java类名 |
| /serverinfo | 显示系统信息和JVM信息 |
| /sessions | 此方法已过期 |
| /expire?path=/xxx | 列出path路径下的web应用的session空闲时间信息 |
| /expire?path=/xxx&idle=mm | Expire sessions for the context path /xxx which were idle for at least mm minutes. |
| /sslConnectorCiphers | 显示当前connector配置的SSL/TLS密码的诊断信息 |
| /start?path=/xx | 根据指定path启动web应用程序 |
| /stop?path=/xxx | 根据指定path关闭web应用程序 |
| /threaddump | Write a JVM thread dump |
| /undeploy?path=/xxx | 关闭并删除指定path的Web应用程序,然后删除底层WAR文件或文档基目录。 |
我们可以通过ManagerServlet中getPathInfo()提供的操作,将自己的项目远程部署到服务器上,下面将贴出我的实践代码,在实践它之前你只需要引入httpclient包和commons包。
封装统一的远程请求管理类
封装此类用于方便client请求ManagerServlet:
import java.io.File;import java.net.URL;import java.net.URLEncoder;import org.apache.commons.io.IOUtils;import org.apache.commons.lang.StringUtils;import org.apache.http.Header;import org.apache.http.HttpHost;import org.apache.http.HttpResponse;import org.apache.http.HttpStatus;import org.apache.http.auth.AuthScope;import org.apache.http.auth.Credentials;import org.apache.http.auth.UsernamePasswordCredentials;import org.apache.http.client.AuthCache;import org.apache.http.client.methods.HttpGet;import org.apache.http.client.methods.HttpRequestBase;import org.apache.http.client.protocol.ClientContext;import org.apache.http.impl.auth.BasicScheme;import org.apache.http.impl.client.BasicAuthCache;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.impl.conn.PoolingClientConnectionManager;import org.apache.http.protocol.BasicHttpContext;public class TomcatManager { private static final String MANAGER_CHARSET = "UTF-8"; private String username; private URL url; private String password; private String charset; private boolean verbose; private DefaultHttpClient httpClient; private BasicHttpContext localContext; /** constructor */ public TomcatManager(URL url, String username) { this(url, username, ""); } public TomcatManager(URL url, String username, String password) { this(url, username, password, "ISO-8859-1"); } public TomcatManager(URL url, String username, String password, String charset) { this(url, username, password, charset, true); } public TomcatManager(URL url, String username, String password, String charset, boolean verbose) { this.url = url; this.username = username; this.password = password; this.charset = charset; this.verbose = verbose; // 创建网络请求相关的配置 PoolingClientConnectionManager poolingClientConnectionManager = new PoolingClientConnectionManager(); poolingClientConnectionManager.setMaxTotal(5); this.httpClient = new DefaultHttpClient(poolingClientConnectionManager); if (StringUtils.isNotEmpty(username)) { Credentials creds = new UsernamePasswordCredentials(username, password); String host = url.getHost(); int port = url.getPort() > -1 ? url.getPort() : AuthScope.ANY_PORT; httpClient.getCredentialsProvider().setCredentials(new AuthScope(host, port), creds); AuthCache authCache = new BasicAuthCache(); BasicScheme basicAuth = new BasicScheme(); HttpHost targetHost = new HttpHost(url.getHost(), url.getPort(), url.getProtocol()); authCache.put(targetHost, basicAuth); localContext = new BasicHttpContext(); localContext.setAttribute(ClientContext.AUTH_CACHE, authCache); } } /** 根据指定的path部署并启动一个新的应用程序 */ public TomcatManagerResponse deploy(String path, File war, boolean update) throws Exception { StringBuilder buffer = new StringBuilder("/deploy"); buffer.append("?path=").append(URLEncoder.encode(path, charset)); if (war != null) { buffer.append("&war=").append(URLEncoder.encode(war.toString(), charset)); } if (update) { buffer.append("&update=true"); } return invoke(buffer.toString()); } /** 获取所有已部署的web应用程序的上下文路径。格式为path:status:sessions(活动会话数) */ public TomcatManagerResponse list() throws Exception { StringBuilder buffer = new StringBuilder("/list"); return invoke(buffer.toString()); } /** 获取系统信息和JVM信息 */ public TomcatManagerResponse serverinfo() throws Exception { StringBuilder buffer = new StringBuilder("/serverinfo"); return invoke(buffer.toString()); } /** 真正发送请求的方法 */ private TomcatManagerResponse invoke(String path) throws Exception { HttpRequestBase httpRequestBase = new HttpGet(url + path); HttpResponse response = httpClient.execute(httpRequestBase, localContext); int statusCode = response.getStatusLine().getStatusCode(); switch (statusCode) { case HttpStatus.SC_OK: // 200 case HttpStatus.SC_CREATED: // 201 case HttpStatus.SC_ACCEPTED: // 202 break; case HttpStatus.SC_MOVED_PERMANENTLY: // 301 case HttpStatus.SC_MOVED_TEMPORARILY: // 302 case HttpStatus.SC_SEE_OTHER: // 303 String redirectUrl = getRedirectUrl(response); this.url = new URL(redirectUrl); return invoke(path); } return new TomcatManagerResponse().setStatusCode(response.getStatusLine().getStatusCode()) .setReasonPhrase(response.getStatusLine().getReasonPhrase()) .setHttpResponseBody(IOUtils.toString(response.getEntity().getContent())); } /** 提取重定向URL */ protected String getRedirectUrl(HttpResponse response) { Header locationHeader = response.getFirstHeader("Location"); String locationField = locationHeader.getValue(); // is it a relative Location or a full ? return locationField.startsWith("http") ? locationField : url.toString() + '/' + locationField; }}封装响应结果集
@Datapublic class TomcatManagerResponse { private int statusCode; private String reasonPhrase; private String httpResponseBody;}测试远程部署
在测试之前请先在配置文件放通下面用户权限:
下面是测试成功远程部署war包的代码:
import static org.testng.AssertJUnit.assertEquals;import java.io.File;import java.net.URL;import org.testng.annotations.Test;public class TestTomcatManager { @Test public void testDeploy() throws Exception { TomcatManager tm = new TomcatManager(new URL("http://localhost:8080/manager/text"), "sqdyy", "123456"); File war = new File("E:\\tomcat\\simple-war-project-1.0-SNAPSHOT.war"); TomcatManagerResponse response = tm.deploy("/simple-war-project-1.0-SNAPSHOT", war, true); System.out.println(response.getHttpResponseBody()); assertEquals(200, response.getStatusCode()); // output: // OK - Deployed application at context path /simple-war-project-1.0-SNAPSHOT } @Test public void testList() throws Exception { TomcatManager tm = new TomcatManager(new URL("http://localhost:8080/manager/text"), "sqdyy", "123456"); TomcatManagerResponse response = tm.list(); System.out.println(response.getHttpResponseBody()); assertEquals(200, response.getStatusCode()); // output: // OK - Listed applications for virtual host localhost // /:running:0:ROOT // /simple-war-project-1.0-SNAPSHOT:running:0:simple-war-project-1.0-SNAPSHOT // /examples:running:0:examples // /host-manager:running:0:host-manager // /manager:running:0:manager // /docs:running:0:docs } @Test public void testServerinfo() throws Exception { TomcatManager tm = new TomcatManager(new URL("http://localhost:8080/manager/text"), "sqdyy", "123456"); TomcatManagerResponse response = tm.serverinfo(); System.out.println(response.getHttpResponseBody()); assertEquals(200, response.getStatusCode()); // output: // OK - Server info // Tomcat Version: Apache Tomcat/7.0.82 // OS Name: Windows 10 // OS Version: 10.0 // OS Architecture: amd64 // JVM Version: 1.8.0_144-b01 // JVM Vendor: Oracle Corporation }}关于"怎么通过tomcat中ManagerServlet远程部署项目"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
应用
应用程序
程序
信息
路径
项目
源码
篇文章
实践
封装
测试
管理
配置
上下
上下文
代码
功能
参数
文件
更多
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
手磨咖啡
科技平台互联网
互联网电商科技
河南真二互联网科技有限公司
互联网科技公司怎么样
壹账通互联网科技
丰台科技园 互联网
友谊互联网络科技
农村开互联网科技讲堂
北京华百购互联网科技有限公司
茂名市互联网科技产业园
世界互联网科技公司市值排名
中国互联网公司排名锤子科技
互联网方面的科技前沿
黑科技 体验场景 互联网大会
互联网科技职业技能培训学校
互联网科技的前景
青岛易易互联网科技
上海旺乐尼互联网科技有限公司
互联网科技自媒体灵感
广州大一互联网络科技有限公司
云信互联网科技有限公司
金融科技与互联网金融
互联网养老 桔豆科技
互联网之后的科技是什么
北京华百购互联网科技有限公司
互联网与医疗科技
互联网在线教育科技创业
科技互联网海报
浙南科技城互联网大厦招聘