步骤 1 : 拓扑图点亮 步骤 2 : ApplicationFilterChain 步骤 3 : HttpProcessor 步骤 4 : 测试 步骤 5 : 比较可运行项目,快速定位问题
增值内容,请先登录
自己写一个Tomcat, 几乎使用到了除开框架外的所有Java 技术,如多线程,Socket, J2EE, 反射,Log4j, JSoup, JUnit, Html 等一整套技术栈, 从无到有,循序渐进涵盖全部74个知识点,549个开发步骤, 为竞争高薪资职位加上一个有吸引力的砝码.
增值内容,点击购买
使用爬虫已经被系统记录,请勿使用爬虫,增大封号风险。 如果是误封 ,请联系站长,谢谢
增值内容,请先登录
自己写一个Tomcat, 几乎使用到了除开框架外的所有Java 技术,如多线程,Socket, J2EE, 反射,Log4j, JSoup, JUnit, Html 等一整套技术栈, 从无到有,循序渐进涵盖全部74个知识点,549个开发步骤, 为竞争高薪资职位加上一个有吸引力的砝码.
增值内容,点击购买
使用爬虫已经被系统记录,请勿使用爬虫,增大封号风险。 如果是误封 ,请联系站长,谢谢
package cn.how2j.diytomcat.catalina;
import java.io.IOException;
import java.util.List;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import cn.hutool.core.util.ArrayUtil;
public class ApplicationFilterChain implements FilterChain{
private Filter[] filters;
private Servlet servlet;
int pos;
public ApplicationFilterChain(List<Filter> filterList,Servlet servlet){
this.filters = ArrayUtil.toArray(filterList,Filter.class);
this.servlet = servlet;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
if(pos < filters.length) {
Filter filter= filters[pos++];
filter.doFilter(request, response, this);
}
else {
servlet.service(request, response);
}
}
}
增值内容,请先登录
自己写一个Tomcat, 几乎使用到了除开框架外的所有Java 技术,如多线程,Socket, J2EE, 反射,Log4j, JSoup, JUnit, Html 等一整套技术栈, 从无到有,循序渐进涵盖全部74个知识点,549个开发步骤, 为竞争高薪资职位加上一个有吸引力的砝码.
增值内容,点击购买
使用爬虫已经被系统记录,请勿使用爬虫,增大封号风险。 如果是误封 ,请联系站长,谢谢
package cn.how2j.diytomcat.catalina;
import cn.how2j.diytomcat.http.Request;
import cn.how2j.diytomcat.http.Response;
import cn.how2j.diytomcat.servlets.DefaultServlet;
import cn.how2j.diytomcat.servlets.InvokerServlet;
import cn.how2j.diytomcat.servlets.JspServlet;
import cn.how2j.diytomcat.util.Constant;
import cn.how2j.diytomcat.util.SessionManager;
import cn.how2j.diytomcat.util.WebXMLUtil;
import cn.hutool.core.util.*;
import cn.hutool.log.LogFactory;
import javax.servlet.Filter;
import javax.servlet.Servlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.List;
public class HttpProcessor {
public void execute(Socket s, Request request, Response response){
try {
String uri = request.getUri();
if(null==uri)
return;
prepareSession(request, response);
Context context = request.getContext();
String servletClassName = context.getServletClassName(uri);
HttpServlet workingServlet;
if(null!=servletClassName)
workingServlet = InvokerServlet.getInstance();
else if(uri.endsWith(".jsp"))
workingServlet = JspServlet.getInstance();
else
workingServlet = DefaultServlet.getInstance();
List<Filter> filters = request.getContext().getMatchedFilters(request.getRequestURI());
ApplicationFilterChain filterChain = new ApplicationFilterChain(filters, workingServlet);
filterChain.doFilter(request, response);
if(request.isForwarded())
return;
if(Constant.CODE_200 == response.getStatus()){
handle200(s, request, response);
return;
}
if(Constant.CODE_302 == response.getStatus()){
handle302(s, response);
return;
}
if(Constant.CODE_404 == response.getStatus()){
handle404(s, uri);
return;
}
} catch (Exception e) {
LogFactory.get().error(e);
handle500(s,e);
}
finally{
try {
if(!s.isClosed())
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void handle200(Socket s, Request request, Response response)
throws IOException {
OutputStream os = s.getOutputStream();
String contentType = response.getContentType();
byte[] body = response.getBody();
String cookiesHeader = response.getCookiesHeader();
boolean gzip = isGzip(request, body, contentType);
String headText;
if (gzip)
headText = Constant.response_head_200_gzip;
else
headText = Constant.response_head_200;
headText = StrUtil.format(headText, contentType, cookiesHeader);
if (gzip)
body = ZipUtil.gzip(body);
byte[] head = headText.getBytes();
byte[] responseBytes = new byte[head.length + body.length];
ArrayUtil.copy(head, 0, responseBytes, 0, head.length);
ArrayUtil.copy(body, 0, responseBytes, head.length, body.length);
os.write(responseBytes,0,responseBytes.length);
os.flush();
os.close();
}
private void handle404(Socket s, String uri) throws IOException {
OutputStream os = s.getOutputStream();
String responseText = StrUtil.format(Constant.textFormat_404, uri, uri);
responseText = Constant.response_head_404 + responseText;
byte[] responseByte = responseText.getBytes("utf-8");
os.write(responseByte);
}
private void handle302(Socket s, Response response) throws IOException {
OutputStream os = s.getOutputStream();
String redirectPath = response.getRedirectPath();
String head_text = Constant.response_head_302;
String header = StrUtil.format(head_text, redirectPath);
byte[] responseBytes = header.getBytes("utf-8");
os.write(responseBytes);
}
private void handle500(Socket s, Exception e) {
try {
OutputStream os = s.getOutputStream();
StackTraceElement stes[] = e.getStackTrace();
StringBuffer sb = new StringBuffer();
sb.append(e.toString());
sb.append("\r\n");
for (StackTraceElement ste : stes) {
sb.append("\t");
sb.append(ste.toString());
sb.append("\r\n");
}
String msg = e.getMessage();
if (null != msg && msg.length() > 20)
msg = msg.substring(0, 19);
String text = StrUtil.format(Constant.textFormat_500, msg, e.toString(), sb.toString());
text = Constant.response_head_500 + text;
byte[] responseBytes = text.getBytes("utf-8");
os.write(responseBytes);
} catch (IOException e1) {
e1.printStackTrace();
}
}
public void prepareSession(Request request, Response response) {
String jsessionid = request.getJSessionIdFromCookie();
HttpSession session = SessionManager.getSession(jsessionid, request, response);
request.setSession(session);
}
private boolean isGzip(Request request, byte[] body, String mimeType) {
String acceptEncodings= request.getHeader("Accept-Encoding");
if(!StrUtil.containsAny(acceptEncodings, "gzip"))
return false;
Connector connector = request.getConnector();
if (mimeType.contains(";"))
mimeType = StrUtil.subBefore(mimeType, ";", false);
if (!"on".equals(connector.getCompression()))
return false;
if (body.length < connector.getCompressionMinSize())
return false;
String userAgents = connector.getNoCompressionUserAgents();
String[] eachUserAgents = userAgents.split(",");
for (String eachUserAgent : eachUserAgents) {
eachUserAgent = eachUserAgent.trim();
String userAgent = request.getHeader("User-Agent");
if (StrUtil.containsAny(userAgent, eachUserAgent))
return false;
}
String mimeTypes = connector.getCompressableMimeType();
String[] eachMimeTypes = mimeTypes.split(",");
for (String eachMimeType : eachMimeTypes) {
if (mimeType.equals(eachMimeType))
return true;
}
return false;
}
}
增值内容,请先登录
自己写一个Tomcat, 几乎使用到了除开框架外的所有Java 技术,如多线程,Socket, J2EE, 反射,Log4j, JSoup, JUnit, Html 等一整套技术栈, 从无到有,循序渐进涵盖全部74个知识点,549个开发步骤, 为竞争高薪资职位加上一个有吸引力的砝码.
增值内容,点击购买
使用爬虫已经被系统记录,请勿使用爬虫,增大封号风险。 如果是误封 ,请联系站长,谢谢
增值内容,请先登录
自己写一个Tomcat, 几乎使用到了除开框架外的所有Java 技术,如多线程,Socket, J2EE, 反射,Log4j, JSoup, JUnit, Html 等一整套技术栈, 从无到有,循序渐进涵盖全部74个知识点,549个开发步骤, 为竞争高薪资职位加上一个有吸引力的砝码.
增值内容,点击购买
使用爬虫已经被系统记录,请勿使用爬虫,增大封号风险。 如果是误封 ,请联系站长,谢谢
HOW2J公众号,关注后实时获知最新的教程和优惠活动,谢谢。
问答区域
2021-05-06
关于热加载的问题
2 个答案
打工人 跳转到问题位置 答案时间:2021-05-08 同步锁肯定不能解决,因为context是被移除再新建的,所以ContextFileChangeWatcher也会是新建的,同步锁不起作用啊
how2j 跳转到问题位置 答案时间:2021-05-07 还有这个问题呢,加上同步锁能解决吗?
回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
提问之前请登陆
提问已经提交成功,正在审核。 请于 我的提问 处查看提问记录,谢谢
|