Skip to content

Commit 10be940

Browse files
noeargitee-org
authored andcommitted
!5 尝试为tomcat适配jsp支持
Merge pull request !5 from 小xu中年/dev
2 parents 9a89880 + a9e0183 commit 10be940

File tree

8 files changed

+237
-17
lines changed

8 files changed

+237
-17
lines changed

solon-jakarta-projects/solon-server/solon-server-tomcat-add-jsp-jakarta/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
<packaging>jar</packaging>
1717

1818
<dependencies>
19+
<dependency>
20+
<groupId>org.noear</groupId>
21+
<artifactId>solon-server-tomcat-jakarta</artifactId>
22+
</dependency>
1923
<dependency>
2024
<groupId>jakarta.servlet</groupId>
2125
<artifactId>jakarta.servlet-api</artifactId>

solon-jakarta-projects/solon-server/solon-server-tomcat-jakarta/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,10 @@
7070
<artifactId>solon-logging-simple</artifactId>
7171
<scope>test</scope>
7272
</dependency>
73+
<dependency>
74+
<groupId>org.noear</groupId>
75+
<artifactId>solon-view-jsp-jakarta</artifactId>
76+
<scope>test</scope>
77+
</dependency>
7378
</dependencies>
7479
</project>

solon-jakarta-projects/solon-server/solon-server-tomcat-jakarta/src/main/java/org/noear/solon/server/tomcat/TomcatServerJsp.java

Lines changed: 92 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,27 @@
1515
*/
1616
package org.noear.solon.server.tomcat;
1717

18+
import java.io.FileNotFoundException;
19+
import java.io.IOException;
20+
import java.net.MalformedURLException;
21+
import java.net.URL;
22+
import java.util.ArrayList;
23+
import java.util.List;
24+
import java.util.Map;
25+
1826
import org.apache.catalina.Context;
1927
import org.apache.catalina.Wrapper;
28+
import org.apache.catalina.startup.Tomcat;
2029
import org.apache.jasper.servlet.JasperInitializer;
21-
import org.apache.jasper.servlet.JspServlet;
30+
import org.noear.solon.Solon;
31+
import org.noear.solon.Utils;
32+
import org.noear.solon.core.runtime.NativeDetector;
33+
import org.noear.solon.core.util.ResourceUtil;
2234
import org.noear.solon.server.prop.impl.HttpServerProps;
35+
import org.noear.solon.server.tomcat.jsp.JspTldLocator;
2336

24-
import java.io.IOException;
37+
import jakarta.servlet.descriptor.JspConfigDescriptor;
38+
import jakarta.servlet.descriptor.TaglibDescriptor;
2539

2640
/**
2741
* @author noear 2025/11/29 created
@@ -34,28 +48,92 @@ public TomcatServerJsp(HttpServerProps props) {
3448
@Override
3549
protected void initContext() throws IOException {
3650
Context ctx = getContext();
37-
51+
3852
//jsp
3953
try {
40-
addJspServlet(ctx);
41-
42-
JasperInitializer jasperInstance = new JasperInitializer();
43-
ctx.addServletContainerInitializer(jasperInstance, null);
54+
String resourcePath = getResourceRoot();
55+
if(Utils.isBlank(resourcePath)) {
56+
resourcePath = getClass().getClassLoader().getResource("").getPath();
57+
}
58+
ctx.setDocBase(resourcePath);
59+
addJspSupport(ctx);
60+
addTldSupport(ctx);
4461
} catch (Exception e) {
4562
log.debug(e.getMessage(), e);
4663
}
4764
}
4865

49-
private void addJspServlet(Context context) {
50-
Wrapper jspServlet = context.createWrapper();
51-
jspServlet.setName("jsp");
52-
jspServlet.setServlet(new JspServlet());
66+
67+
private void addJspSupport(Context context) throws IOException {
68+
// 注册JSP Servlet(Tomcat需要显式注册JspServlet)
69+
Wrapper jspServlet = Tomcat.addServlet(context, "jsp", "org.apache.jasper.servlet.JspServlet");
5370
jspServlet.addInitParameter("fork", "false");
5471
jspServlet.addInitParameter("xpoweredBy", "false");
55-
jspServlet.setLoadOnStartup(3);
56-
57-
context.addChild(jspServlet);
72+
// jspServlet.addInitParameter("development", "true"); // 开发模式,便于调试
73+
74+
// 设置JSP文件映射
5875
context.addServletMappingDecoded("*.jsp", "jsp");
5976
context.addServletMappingDecoded("*.jspx", "jsp");
77+
78+
JasperInitializer jasperInstance = new JasperInitializer();
79+
context.addServletContainerInitializer(jasperInstance, null);
80+
}
81+
82+
private void addTldSupport(Context ctx) throws IOException {
83+
// 扫描TLD文件并注册
84+
Map<String, TaglibDescriptor> tagLibInfos = JspTldLocator.createTldInfos("WEB-INF", "templates");
85+
86+
if (tagLibInfos.size()>0) {
87+
List<TaglibDescriptor> taglibs = new ArrayList<>(tagLibInfos.values());
88+
JspConfigDescriptor jspConfigDescriptor = new org.apache.tomcat.util.descriptor.web.JspConfigDescriptorImpl(
89+
new ArrayList<>(), taglibs);
90+
ctx.setJspConfigDescriptor(jspConfigDescriptor);
91+
// ctx.getServletContext().setAttribute("jakarta.servlet.context.tldScan", true);
92+
}
93+
}
94+
95+
private String getResourceRoot() throws FileNotFoundException {
96+
URL rootURL = getRootPath();
97+
if (rootURL == null) {
98+
if (NativeDetector.inNativeImage()) {
99+
return "";
100+
}
101+
102+
throw new FileNotFoundException("Unable to find root");
103+
}
104+
105+
String resURL = rootURL.toString();
106+
107+
if (Solon.cfg().isDebugMode() && (resURL.startsWith("jar:") == false)) {
108+
int endIndex = resURL.indexOf("target");
109+
return resURL.substring(0, endIndex) + "src/main/resources/";
110+
}
111+
112+
return "";
113+
}
114+
115+
private URL getRootPath() {
116+
URL root = ResourceUtil.getResource("/");
117+
if (root != null) {
118+
return root;
119+
}
120+
try {
121+
URL temp = ResourceUtil.getResource("");
122+
if (temp == null) {
123+
return null;
124+
}
125+
126+
String path = temp.toString();
127+
if (path.startsWith("jar:")) {
128+
int endIndex = path.indexOf("!");
129+
path = path.substring(0, endIndex + 1) + "/";
130+
} else {
131+
return null;
132+
}
133+
return new URL(path);
134+
} catch (MalformedURLException e) {
135+
return null;
136+
}
60137
}
138+
61139
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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.jsp;
17+
18+
import org.apache.tomcat.util.descriptor.tld.TaglibXml;
19+
import org.apache.tomcat.util.descriptor.tld.TldParser;
20+
import org.apache.tomcat.util.descriptor.tld.TldResourcePath;
21+
import org.noear.solon.Utils;
22+
import org.noear.solon.core.AppClassLoader;
23+
import org.noear.solon.core.util.ResourceUtil;
24+
import org.noear.solon.core.util.ScanUtil;
25+
import org.slf4j.Logger;
26+
import org.slf4j.LoggerFactory;
27+
28+
import jakarta.servlet.descriptor.TaglibDescriptor;
29+
30+
import java.io.IOException;
31+
import java.net.URL;
32+
import java.util.HashMap;
33+
import java.util.Map;
34+
import java.util.Set;
35+
36+
/**
37+
* TLD文件定位器
38+
*/
39+
public class JspTldLocator {
40+
private static final Logger log = LoggerFactory.getLogger(JspTldLocator.class);
41+
42+
private JspTldLocator() {
43+
44+
}
45+
public static Map<String, TaglibDescriptor> createTldInfos(String... tldDirs) throws IOException {
46+
Map<String, TaglibDescriptor> tagLibInfos = new HashMap<>();
47+
48+
TldParser tldParser = new TldParser(true, true, true);
49+
50+
for (String tldDir : tldDirs) {
51+
// 扫描指定目录下的TLD文件
52+
Set<String> urls = ScanUtil.scan(AppClassLoader.global(), tldDir, n -> n.endsWith(".tld"));
53+
54+
if (Utils.isNotEmpty(urls)) {
55+
for (String uri : urls) {
56+
uri = "/" + uri;
57+
58+
URL resUri = ResourceUtil.getResource(uri);
59+
TldResourcePath tldResourcePath = new TldResourcePath(resUri, uri);
60+
61+
try {
62+
TaglibXml taglibXml = tldParser.parse(tldResourcePath);
63+
64+
// 创建TLD描述符
65+
final String taglibUri = taglibXml.getUri();
66+
final String taglibLocation = uri;
67+
68+
TaglibDescriptor descriptor = new TaglibDescriptor() {
69+
@Override
70+
public String getTaglibURI() {
71+
return taglibUri;
72+
}
73+
74+
@Override
75+
public String getTaglibLocation() {
76+
return taglibLocation;
77+
}
78+
};
79+
80+
tagLibInfos.put(taglibUri, descriptor);
81+
} catch (Exception e) {
82+
log.warn("TLD failed to load, uri={}", uri, e);
83+
}
84+
}
85+
}
86+
}
87+
88+
return tagLibInfos;
89+
}
90+
91+
}

solon-jakarta-projects/solon-server/solon-server-tomcat-jakarta/src/test/java/demo3013/controller/HelloworldController.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,25 @@ public Object helloworld(Context ctx){
3333

3434
return vm;
3535
}
36+
37+
@Mapping("/hellotld")
38+
public Object hellotld(Context ctx){
39+
UserModel m = new UserModel();
40+
m.setId(11);
41+
m.setName("刘之西东2");
42+
m.setSex(2);
43+
44+
ModelAndView vm = new ModelAndView("helloworld2.jsp");
45+
46+
vm.put("title","demo2");
47+
vm.put("message","hello world2!");
48+
49+
vm.put("m",m);
50+
51+
vm.put("user", user);
52+
53+
vm.put("ctx",ctx);
54+
55+
return vm;
56+
}
3657
}

solon-jakarta-projects/solon-server/solon-server-tomcat-jakarta/src/test/resources/app.properties

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,7 @@ solon.output.meta=1
99

1010
custom.user=world
1111

12-
solon.view.mapping.vm: org.noear.solon.view.jsp.JspRender
12+
#solon.view.mapping.vm: org.noear.solon.view.jsp.JspRender
13+
solon.view.mapping.jsp=org.noear.solon.view.jsp.JspRender
14+
15+
solon.view.prefix=/templates

solon-jakarta-projects/solon-server/solon-server-tomcat-jakarta/src/test/resources/templates/helloworld.jsp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<%@ page import="java.util.Random" %>
22
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
3-
<%@ taglib prefix="ct" uri="/tags" %>
43
<html>
54
<head>
65
<title>${title}</title>
@@ -15,6 +14,5 @@
1514
<main>
1615
${m.name} : ${message} (我想<a href="/jinjin.htm">静静</a>)
1716
</main>
18-
<ct:footer/>
1917
</body>
2018
</html>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<%@ page import="java.util.Random" %>
2+
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
3+
<%@ taglib prefix="ct" uri="/tags" %>
4+
<html>
5+
<head>
6+
<title>${title}</title>
7+
</head>
8+
<body>
9+
<div>
10+
page path: ${ctx.path()}
11+
</div>
12+
<div>
13+
properties: custom.user :${user}
14+
</div>
15+
<main>
16+
${m.name} : ${message} (我想<a href="/jinjin.htm">静静</a>)
17+
</main>
18+
<ct:footer/>
19+
</body>
20+
</html>

0 commit comments

Comments
 (0)