Skip to content

Commit 71cabec

Browse files
committed
commit 2022/1/8 2nd
1 parent 8515636 commit 71cabec

File tree

7 files changed

+611
-46
lines changed

7 files changed

+611
-46
lines changed

src/com/xpcf/http4java/Bootstrap.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ public static void main(String[] args) throws ClassNotFoundException, IllegalAcc
4848

4949
m.invoke(serverObject);
5050

51-
System.out.println("com.xpcf.http4java.catalina.Server classloader: " + serverClazz.getClassLoader());
52-
System.out.println("bootstrap classloader: " + Bootstrap.class.getClassLoader());
51+
// System.out.println("com.xpcf.http4java.catalina.Server classloader: " + serverClazz.getClassLoader());
52+
// System.out.println("bootstrap classloader: " + Bootstrap.class.getClassLoader());
5353
// LogFactory.get().error(Thread.currentThread().getName() + " " + Thread.currentThread().getContextClassLoader());
5454
}
5555

src/com/xpcf/http4java/catalina/Context.java

Lines changed: 78 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import cn.hutool.core.io.FileUtil;
66
import cn.hutool.core.util.StrUtil;
77
import cn.hutool.log.LogFactory;
8+
import com.xpcf.http4java.http.StandardServletConfig;
89
import com.xpcf.http4java.watcher.ContextFileChangeWatcher;
910
import com.xpcf.http4java.classloader.WebappClassLoader;
1011
import com.xpcf.http4java.exception.WebConfigDuplicatedException;
@@ -15,7 +16,9 @@
1516
import org.jsoup.nodes.Element;
1617
import org.jsoup.select.Elements;
1718

19+
import javax.servlet.ServletConfig;
1820
import javax.servlet.ServletContext;
21+
import javax.servlet.ServletException;
1922
import javax.servlet.http.HttpServlet;
2023
import java.io.File;
2124
import java.util.*;
@@ -55,6 +58,10 @@ public class Context {
5558

5659
private Map<Class<?>, HttpServlet> servletPool;
5760

61+
private Map<String, Map<String, String>> servletClassNameInitParams;
62+
63+
private List<String> loadOnStartupServletClassNames;
64+
5865
public Context(String path, String docBase, Host host, boolean reloadable) {
5966
TimeInterval timeInterval = DateUtil.timer();
6067

@@ -65,7 +72,8 @@ public Context(String path, String docBase, Host host, boolean reloadable) {
6572
this.reloadable = reloadable;
6673
this.servletContext = new ApplicationContext(this);
6774
this.servletPool = new HashMap<>();
68-
75+
this.servletClassNameInitParams = new HashMap<>();
76+
this.loadOnStartupServletClassNames = new ArrayList<>();
6977
ClassLoader commonClassLoader = Thread.currentThread().getContextClassLoader();
7078

7179
// reload 时重新生成classloader
@@ -82,6 +90,25 @@ public Context(String path, String docBase, Host host, boolean reloadable) {
8290

8391
}
8492

93+
public void parseLoadOnStartup(Document d) {
94+
Elements es = d.select("load-on-startup");
95+
for (Element e : es) {
96+
String loadOnStartupServletClassName = e.parent().select("servlet-class").text();
97+
loadOnStartupServletClassNames.add(loadOnStartupServletClassName);
98+
}
99+
}
100+
101+
public void handleLoadOnStartup() {
102+
for (String loadOnStartupServletClassName : loadOnStartupServletClassNames) {
103+
try {
104+
Class<?> clazz = webappClassLoader.loadClass(loadOnStartupServletClassName);
105+
getServlet(clazz);
106+
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException | ServletException e) {
107+
e.printStackTrace();
108+
}
109+
}
110+
}
111+
85112
public WebappClassLoader getWebappClassLoader() {
86113
return webappClassLoader;
87114
}
@@ -90,14 +117,14 @@ public boolean isReloadable() {
90117
return reloadable;
91118
}
92119

93-
public ServletContext getServletContext() {
94-
return servletContext;
95-
}
96-
97120
public void setReloadable(boolean reloadable) {
98121
this.reloadable = reloadable;
99122
}
100123

124+
public ServletContext getServletContext() {
125+
return servletContext;
126+
}
127+
101128
public String getServletClassName(String uri) {
102129
return urlToServletClassName.get(uri);
103130
}
@@ -118,6 +145,26 @@ public void setDocBase(String docBase) {
118145
this.docBase = docBase;
119146
}
120147

148+
private void parseServletInitParams(Document d) {
149+
Elements servletClassNameElements = d.select("servlet-class");
150+
for (Element servletClassNameElement : servletClassNameElements) {
151+
String servletClassName = servletClassNameElement.text();
152+
Elements initElements = servletClassNameElement.parent().select("init-param");
153+
if (initElements.isEmpty()) {
154+
continue;
155+
}
156+
157+
Map<String, String> initParams = new HashMap<>();
158+
for (Element initElement : initElements) {
159+
String name = initElement.select("param-name").get(0).text();
160+
String value = initElement.select("param-value").get(0).text();
161+
initParams.put(name, value);
162+
}
163+
164+
servletClassNameInitParams.put(servletClassName, initParams);
165+
}
166+
}
167+
121168
private void parseServletMapping(Document d) {
122169
Elements mappingUrlElements = d.select("servlet-mapping url-pattern");
123170

@@ -187,19 +234,43 @@ private void init() {
187234
// 完成重复性检验
188235
String xml = FileUtil.readUtf8String(contextWebXmlFile);
189236
Document d = Jsoup.parse(xml);
237+
190238
parseServletMapping(d);
239+
240+
parseServletInitParams(d);
241+
242+
parseLoadOnStartup(d);
243+
244+
handleLoadOnStartup();
245+
}
246+
247+
private void destroyServlets() {
248+
Collection<HttpServlet> servlets = servletPool.values();
249+
for (HttpServlet servlet : servlets) {
250+
servlet.destroy();
251+
}
191252
}
192253

193254
/**
194255
* 考虑double check lock
256+
*
195257
* @param clazz
196258
* @return
197259
*/
198-
public synchronized HttpServlet getServlet(Class<?> clazz) throws IllegalAccessException, InstantiationException {
260+
public synchronized HttpServlet getServlet(Class<?> clazz) throws IllegalAccessException, InstantiationException, ServletException {
199261
HttpServlet servlet = servletPool.get(clazz);
200262
if (null == servlet) {
263+
201264
servlet = (HttpServlet) clazz.newInstance();
265+
ServletContext servletContext = getServletContext();
266+
String className = clazz.getName();
267+
String servletName = classNameToServletName.get(className);
268+
Map<String, String> initParameters = servletClassNameInitParams.get(className);
269+
ServletConfig servletConfig = new StandardServletConfig(servletContext, initParameters, servletName);
270+
servlet.init(servletConfig);
202271
servletPool.put(clazz, servlet);
272+
273+
203274
}
204275
return servlet;
205276
}
@@ -217,6 +288,7 @@ private void deploy() {
217288
public void stop() {
218289
webappClassLoader.stop();
219290
contextFileChangeWatcher.stop();
291+
destroyServlets();
220292
}
221293

222294
public void reload() {

src/com/xpcf/http4java/catalina/Host.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ public void reload(Context context) {
8484
boolean reloadable = context.isReloadable();
8585

8686
context.stop();
87-
8887
contextMap.remove(context);
8988

9089
Context newContext = new Context(path, docBase, this, reloadable);

src/com/xpcf/http4java/http/Request.java

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@
1717
import java.io.UnsupportedEncodingException;
1818
import java.net.Socket;
1919
import java.security.Principal;
20-
import java.util.Collection;
21-
import java.util.Enumeration;
22-
import java.util.Locale;
23-
import java.util.Map;
20+
import java.util.*;
2421

2522
/**
2623
* @author XPCF
@@ -41,10 +38,15 @@ public class Request extends BaseRequest {
4138

4239
private String method;
4340

41+
private String queryString;
42+
43+
private Map<String, String[]> parameterMap;
44+
4445
public Request(Socket socket, Service service) throws IOException {
4546

4647
this.socket = socket;
4748
this.service = service;
49+
this.parameterMap = new HashMap<>();
4850

4951
parseHttpRequest();
5052
if (StrUtil.isEmpty(requestString)) {
@@ -86,6 +88,40 @@ private void parseContext() {
8688
}
8789
}
8890

91+
private void parseParameters() {
92+
93+
if ("GET".equals(getMethod())) {
94+
String uri = StrUtil.subBetween(requestString, " ", " ");
95+
if (StrUtil.contains(uri, '?')) {
96+
97+
}
98+
}
99+
100+
}
101+
102+
@Override
103+
public String getParameter(String name) {
104+
String[] values = parameterMap.get(name);
105+
if (null != values && values.length != 0) {
106+
return values[0];
107+
}
108+
return null;
109+
}
110+
111+
@Override
112+
public Map<String, String[]> getParameterMap() {
113+
return parameterMap;
114+
}
115+
116+
@Override
117+
public Enumeration<String> getParameterNames() {
118+
return Collections.enumeration(parameterMap.keySet());
119+
}
120+
121+
@Override
122+
public String[] getParameterValues(String name) {
123+
return parameterMap.get(name);
124+
}
89125

90126
@Override
91127
public String getMethod() {

src/com/xpcf/http4java/servlet/InvokerServlet.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ public void service(HttpServletRequest req, HttpServletResponse resp) throws Ser
4444
try {
4545
Class<?> servletClazz = context.getWebappClassLoader().loadClass(servletClassName);
4646

47-
LogFactory.get().info("servletClass: " + servletClazz);
48-
LogFactory.get().info("servletClass ClassLoader: " + servletClazz.getClassLoader());
47+
// LogFactory.get().info("servletClass: " + servletClazz);
48+
// LogFactory.get().info("servletClass ClassLoader: " + servletClazz.getClassLoader());
4949

5050
Object servletObject = context.getServlet(servletClazz);
5151
ReflectUtil.invoke(servletObject, "service", request, response);
Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
11
package com.xpcf.http4java.watcher;
22

3-
import cn.hutool.core.io.watch.WatchMonitor;
43
import cn.hutool.core.io.watch.WatchUtil;
54
import cn.hutool.core.io.watch.Watcher;
5+
import cn.hutool.core.io.watch.watchers.DelayWatcher;
6+
import cn.hutool.core.thread.ThreadUtil;
67
import cn.hutool.log.LogFactory;
78
import com.xpcf.http4java.catalina.Context;
89

910
import java.nio.file.Path;
11+
import java.nio.file.Paths;
1012
import java.nio.file.WatchEvent;
13+
import java.util.HashMap;
14+
import java.util.Map;
15+
import java.util.concurrent.BlockingQueue;
16+
import java.util.concurrent.LinkedBlockingQueue;
1117

1218
/**
1319
* @author XPCF
1420
* @version 1.0
1521
* @date 1/7/2022 7:24 PM
1622
*/
23+
24+
1725
public class ContextFileChangeWatcher {
1826

1927
private WatchMonitor monitor;
@@ -22,59 +30,51 @@ public class ContextFileChangeWatcher {
2230

2331
public ContextFileChangeWatcher(Context context) {
2432

25-
this.monitor = WatchUtil.createAll(context.getDocBase(), Integer.MAX_VALUE, new Watcher() {
26-
private void dealWith(WatchEvent<?> event, Path currentPath) {
27-
// 可能不需要加锁,监听只有一个线程
28-
synchronized (ContextFileChangeWatcher.class) {
29-
30-
31-
// String fileName = event.context().toString();
32-
String fileName = "";
33-
System.err.println(Thread.currentThread().getName() + " ");
34-
35-
System.err.println(currentPath.toString());
36-
System.err.println("process method" + event.kind().name());
37-
if (stop) {
38-
// System.err.println(Thread.currentThread().getName() + " ");
39-
// System.err.println("stop method");
40-
return;
41-
}
42-
43-
if (fileName.endsWith(".jar") || fileName.endsWith(".xml") || fileName.endsWith(".class")) {
44-
// System.err.println(Thread.currentThread().getName() + " ");
45-
// System.err.println("process method");
46-
stop = true;
47-
LogFactory.get().info(ContextFileChangeWatcher.this + " file changes under the Web application were detected {}", fileName);
48-
context.reload();
49-
}
33+
WatchMonitor watchMonitor = new WatchMonitor(Paths.get(context.getDocBase()), Integer.MAX_VALUE, WatchMonitor.EVENTS_ALL);
34+
watchMonitor.setWatcher(new Watcher() {
35+
private void dealWith(WatchEvent<?> event) {
36+
37+
String fileName = event.context().toString();
38+
// System.err.println(fileName);
39+
if (stop) {
40+
return;
41+
}
42+
43+
if (fileName.endsWith(".jar") || fileName.endsWith(".class") || fileName.endsWith(".xml")) {
44+
stop = true;
45+
LogFactory.get().info(ContextFileChangeWatcher.this + " Important file changes under the Web application were detected {} ", fileName);
46+
context.reload();
5047
}
5148
}
5249

5350
@Override
5451
public void onCreate(WatchEvent<?> event, Path currentPath) {
55-
dealWith(event, currentPath);
52+
dealWith(event);
5653
}
5754

5855
@Override
5956
public void onModify(WatchEvent<?> event, Path currentPath) {
60-
dealWith(event, currentPath);
57+
dealWith(event);
58+
6159
}
6260

6361
@Override
6462
public void onDelete(WatchEvent<?> event, Path currentPath) {
65-
dealWith(event, currentPath);
63+
dealWith(event);
64+
6665
}
6766

6867
@Override
6968
public void onOverflow(WatchEvent<?> event, Path currentPath) {
70-
dealWith(event, currentPath);
69+
dealWith(event);
7170
}
71+
7272
});
7373

74+
this.monitor = watchMonitor;
7475
this.monitor.setDaemon(true);
7576
}
7677

77-
7878
public void start() {
7979
monitor.start();
8080
}
@@ -84,3 +84,4 @@ public void stop() {
8484
}
8585
}
8686

87+

0 commit comments

Comments
 (0)