详解如何通过tomcat的ManagerServlet远程部署项目
程序员文章站
2022-03-19 08:27:20
介绍
之前在邮政实习时,leader让我阅读tomcat的源代码,尝试自己实现远程部署项目的功能,于是便有了这此实践。
在tomact中有一个manager应用程序...
介绍
之前在邮政实习时,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; } }
封装响应结果集
@data public class tomcatmanagerresponse { private int statuscode; private string reasonphrase; private string httpresponsebody; }
测试远程部署
在测试之前请先在配置文件放通下面用户权限:
<role rolename="admin-gui"/> <role rolename="admin-script"/> <role rolename="manager-gui"/> <role rolename="manager-script"/> <role rolename="manager-jmx"/> <role rolename="manager-status"/> <user username="sqdyy" password="123456" roles="manager-gui,manager-script,manager-jmx,manager-status,admin-script,admin-gui"/>
下面是测试成功远程部署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 } }
参考资料
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点
-
Tomcat 7通过设置不同的端口部署两个项目
-
IDEA是如何部署tomcat项目的,了解一下它的实现原理
-
详解如何通过tomcat的ManagerServlet远程部署项目
-
maven项目远程部署&&使用tomcat配置数据库连接的方法
-
详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点
-
jenkins中通过Publish Over SSH插件将项目部署到远程机器上的讲解说明
-
Tomcat 7通过设置不同的端口部署两个项目
-
IDEA是如何部署tomcat项目的,了解一下它的实现原理
-
详解如何通过tomcat的ManagerServlet远程部署项目