Skip to content

Commit 478466b

Browse files
committed
添加 solon-server-tomcat-jakarta
1 parent 7fd2e1e commit 478466b

9 files changed

Lines changed: 348 additions & 1 deletion

File tree

__release/solon-jakarta-bundle1/pom.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929

3030
<module>../../solon-jakarta-projects/solon-server/solon-server-undertow-jakarta</module>
3131

32+
<module>../../solon-jakarta-projects/solon-server/solon-server-tomcat-jakarta</module>
33+
3234
<module>../../solon-jakarta-projects/solon-view/solon-view-jsp-jakarta</module>
3335

3436
<module>../../solon-jakarta-projects/solon-web/solon-web-servlet-jakarta</module>

__test/pom.xml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,9 +309,14 @@
309309

310310
<dependency>
311311
<groupId>org.noear</groupId>
312-
<artifactId>solon-server-undertow-jakarta</artifactId>
312+
<artifactId>solon-server-tomcat-jakarta</artifactId>
313313
</dependency>
314314

315+
<!-- <dependency>-->
316+
<!-- <groupId>org.noear</groupId>-->
317+
<!-- <artifactId>solon-server-undertow-jakarta</artifactId>-->
318+
<!-- </dependency>-->
319+
315320

316321
<!-- <dependency>-->
317322
<!-- <groupId>org.noear</groupId>-->

solon-jakarta-parent/pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
<undertow.jakarta.version>2.3.19.Final</undertow.jakarta.version>
3333
<undertow.jastow.jakarta.version>2.2.8.Final</undertow.jastow.jakarta.version>
3434
<undertow.jboss-metadata.jakarta.version>16.1.0.Final</undertow.jboss-metadata.jakarta.version>
35+
36+
<tomcat.jakarta.version>11.0.11</tomcat.jakarta.version>
3537
</properties>
3638

3739
<dependencyManagement>
@@ -66,6 +68,12 @@
6668
<version>${project.version}</version>
6769
</dependency>
6870

71+
<dependency>
72+
<groupId>org.noear</groupId>
73+
<artifactId>solon-server-tomcat-jakarta</artifactId>
74+
<version>${project.version}</version>
75+
</dependency>
76+
6977
<dependency>
7078
<groupId>org.noear</groupId>
7179
<artifactId>solon-server-undertow-jakarta</artifactId>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<parent>
8+
<groupId>org.noear</groupId>
9+
<artifactId>solon-jakarta-parent</artifactId>
10+
<version>3.6.0-SNAPSHOT</version>
11+
<relativePath>../../../solon-jakarta-parent/pom.xml</relativePath>
12+
</parent>
13+
14+
<artifactId>solon-server-tomcat-jakarta</artifactId>
15+
<name>${project.artifactId}</name>
16+
<packaging>jar</packaging>
17+
18+
<dependencies>
19+
<dependency>
20+
<groupId>org.noear</groupId>
21+
<artifactId>solon-server</artifactId>
22+
</dependency>
23+
24+
<dependency>
25+
<groupId>org.noear</groupId>
26+
<artifactId>solon-web-servlet-jakarta</artifactId>
27+
</dependency>
28+
29+
<dependency>
30+
<groupId>org.apache.tomcat.embed</groupId>
31+
<artifactId>tomcat-embed-core</artifactId>
32+
<version>${tomcat.jakarta.version}</version>
33+
</dependency>
34+
</dependencies>
35+
36+
37+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright 2017-2025 noear.org and authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.noear.solon.server.tomcat;
17+
18+
import org.apache.catalina.Context;
19+
import org.apache.catalina.connector.Connector;
20+
import org.apache.catalina.startup.Tomcat;
21+
import org.noear.solon.core.util.IoUtil;
22+
import org.noear.solon.server.ServerProps;
23+
import org.noear.solon.server.handle.SessionProps;
24+
import org.noear.solon.server.tomcat.http.TCHttpContextHandler;
25+
26+
import jakarta.servlet.MultipartConfigElement;
27+
28+
/**
29+
* @author Yukai
30+
* @since 2019/3/28 15:49
31+
*/
32+
public class TomcatServer extends TomcatServerBase {
33+
@Override
34+
protected Connector addConnector(int port) throws Throwable {
35+
Connector connector = _server.getConnector();
36+
37+
connector.setPort(port);
38+
connector.setMaxPostSize(ServerProps.request_maxBodySizeAsInt());
39+
connector.setProperty("maxHttpHeaderSize", String.valueOf(ServerProps.request_maxHeaderSize));
40+
connector.setProperty("relaxedQueryChars", "[]|{}");
41+
connector.setURIEncoding(ServerProps.request_encoding);
42+
connector.setUseBodyEncodingForURI(true);
43+
44+
return connector;
45+
}
46+
47+
@Override
48+
protected Context initContext() {
49+
Context context = _server.addContext("/", null);//第二个参数与文档相关
50+
51+
String _tempdir = IoUtil.getTempDirAsString("solon-server");
52+
53+
MultipartConfigElement multipartConfig = new MultipartConfigElement(
54+
_tempdir,
55+
ServerProps.request_maxFileSize,
56+
ServerProps.request_maxFileRequestSize(),
57+
ServerProps.request_fileSizeThreshold);
58+
59+
context.getServletContext().setAttribute("org.apache.catalina.MultipartConfigElement", multipartConfig);
60+
context.setAllowCasualMultipartParsing(true);
61+
62+
if (SessionProps.session_timeout > 0) {
63+
context.setSessionTimeout(SessionProps.session_timeout);
64+
}
65+
66+
// for http
67+
Tomcat.addServlet(context, "solon", new TCHttpContextHandler())
68+
.setAsyncSupported(true);
69+
70+
context.addServletMappingDecoded("/", "solon");//Servlet与对应uri映射
71+
72+
return context;
73+
}
74+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright 2017-2025 noear.org and authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.noear.solon.server.tomcat;
17+
18+
import org.apache.catalina.Context;
19+
import org.apache.catalina.connector.Connector;
20+
import org.apache.catalina.startup.Tomcat;
21+
import org.noear.solon.Utils;
22+
import org.noear.solon.server.ServerLifecycle;
23+
24+
/**
25+
* @author Yukai
26+
* @since 2022/8/26 17:01
27+
**/
28+
public abstract class TomcatServerBase implements ServerLifecycle {
29+
protected Tomcat _server;
30+
31+
@Override
32+
public void start(String host, int port) throws Throwable {
33+
_server = new Tomcat();
34+
35+
if (Utils.isNotEmpty(host)) {
36+
_server.setHostname(host);
37+
}
38+
39+
//初始化链接
40+
addConnector(port);
41+
42+
//初始化上下文
43+
initContext();
44+
45+
_server.start();
46+
}
47+
48+
49+
@Override
50+
public void stop() throws Throwable {
51+
if (_server != null) {
52+
_server.destroy();
53+
_server = null;
54+
}
55+
}
56+
57+
protected abstract Context initContext() throws Throwable;
58+
59+
protected abstract Connector addConnector(int port) throws Throwable;
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2017-2025 noear.org and authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.noear.solon.server.tomcat.http;
17+
18+
import org.noear.solon.server.ServerProps;
19+
import org.noear.solon.server.tomcat.integration.TomcatPlugin;
20+
import org.noear.solon.core.handle.Context;
21+
import org.noear.solon.web.servlet.SolonServletHandler;
22+
23+
import jakarta.servlet.ServletException;
24+
import jakarta.servlet.http.HttpServletRequest;
25+
import jakarta.servlet.http.HttpServletResponse;
26+
27+
import java.io.IOException;
28+
29+
public class TCHttpContextHandler extends SolonServletHandler {
30+
@Override
31+
protected void preHandle(Context ctx) {
32+
if (ServerProps.output_meta) {
33+
ctx.headerSet("Solon-Server", TomcatPlugin.solon_server_ver());
34+
}
35+
}
36+
37+
@Override
38+
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
39+
if (request.getCharacterEncoding() == null) {
40+
request.setCharacterEncoding(ServerProps.request_encoding);
41+
}
42+
43+
super.service(request, response);
44+
}
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Copyright 2017-2025 noear.org and authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.noear.solon.server.tomcat.integration;
17+
18+
import org.apache.catalina.util.ServerInfo;
19+
import org.noear.solon.Solon;
20+
import org.noear.solon.SolonApp;
21+
import org.noear.solon.server.ServerConstants;
22+
import org.noear.solon.server.ServerLifecycle;
23+
import org.noear.solon.server.ServerProps;
24+
import org.noear.solon.server.prop.impl.HttpServerProps;
25+
import org.noear.solon.core.*;
26+
import org.noear.solon.core.util.ClassUtil;
27+
28+
import org.noear.solon.server.tomcat.TomcatServer;
29+
import org.slf4j.Logger;
30+
import org.slf4j.LoggerFactory;
31+
32+
import jakarta.servlet.annotation.WebFilter;
33+
import jakarta.servlet.annotation.WebListener;
34+
import jakarta.servlet.annotation.WebServlet;
35+
36+
public final class TomcatPlugin implements Plugin {
37+
static final Logger log = LoggerFactory.getLogger(TomcatPlugin.class);
38+
39+
private static Signal _signal;
40+
41+
public static Signal signal() {
42+
return _signal;
43+
}
44+
45+
private ServerLifecycle _server = null;
46+
47+
public static String solon_server_ver() {
48+
return ServerInfo.getServerInfo() + "/" + Solon.version();
49+
}
50+
51+
@Override
52+
public void start(AppContext context) {
53+
if (Solon.app().enableHttp() == false) {
54+
return;
55+
}
56+
57+
context.beanBuilderAdd(WebFilter.class, (clz, bw, ano) -> {
58+
});
59+
context.beanBuilderAdd(WebServlet.class, (clz, bw, ano) -> {
60+
});
61+
context.beanBuilderAdd(WebListener.class, (clz, bw, ano) -> {
62+
});
63+
64+
context.lifecycle(ServerConstants.SIGNAL_LIFECYCLE_INDEX, () -> {
65+
start0(Solon.app());
66+
});
67+
}
68+
69+
private void start0(SolonApp app) throws Throwable {
70+
//初始化属性
71+
ServerProps.init();
72+
73+
Class<?> jspClz = ClassUtil.loadClass("org.apache.jasper.servlet.JspServlet");
74+
75+
HttpServerProps props = HttpServerProps.getInstance();
76+
final String _host = props.getHost();
77+
final int _port = props.getPort();
78+
final String _name = props.getName();
79+
80+
_server = new TomcatServer();
81+
82+
long time_start = System.currentTimeMillis();
83+
84+
_server.start(_host, _port);
85+
86+
final String _wrapHost = props.getWrapHost();
87+
final int _wrapPort = props.getWrapPort();
88+
_signal = new SignalSim(_name, _wrapHost, _wrapPort, "http", SignalType.HTTP);
89+
90+
app.signalAdd(_signal);
91+
92+
long time_end = System.currentTimeMillis();
93+
94+
String connectorInfo = "solon.connector:main: tomcat: Started ServerConnector@{HTTP/1.1,[http/1.1]";
95+
if (app.enableWebSocket()) {
96+
String wsServerUrl = props.buildWsServerUrl(false);
97+
log.info(connectorInfo + "[WebSocket]}{" + wsServerUrl + "}");
98+
}
99+
100+
String httpServerUrl = props.buildHttpServerUrl(false);
101+
log.info(connectorInfo + "}{" + httpServerUrl + "}");
102+
log.info("Server:main: tomcat: Started (" + solon_server_ver() + ") @" + (time_end - time_start) + "ms");
103+
}
104+
105+
@Override
106+
public void stop() throws Throwable {
107+
if (_server != null) {
108+
_server.stop();
109+
_server = null;
110+
111+
log.info("Server:main: tomcat: Has Stopped (" + solon_server_ver() + ")");
112+
}
113+
}
114+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
solon.plugin=org.noear.solon.server.tomcat.integration.TomcatPlugin
2+
solon.plugin.priority=18

0 commit comments

Comments
 (0)