为了方便后续的BinCat版本处理Http请求和响应处理结果,我们简单的封装了BinCatDispatcherServlet和BinCatResponseHandler对象。BinCatDispatcherServlet会根据浏览器请求的不同URL地址去调用对应的Servlet服务,除此之外还提供了一个简单的静态资源文件处理逻辑和PHP解析功能。
BinCatDispatcherServlet实现代码:
package com.anbai.sec.server.handler;import com.anbai.sec.server.servlet.BinCatRequest;import com.anbai.sec.server.servlet.BinCatResponse;import com.anbai.sec.server.servlet.BinCatServletContext;import com.anbai.sec.server.servlet.BinCatServletRegistrationDynamic;import org.javaweb.utils.FileUtils;import org.javaweb.utils.StringUtils;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.IOException;import java.nio.file.Files;import java.util.Collection;import java.util.Set;import java.util.regex.Pattern;public class BinCatDispatcherServlet {public void doDispatch(BinCatRequest req, BinCatResponse resp, ByteArrayOutputStream out) throws IOException {// 请求URI地址String uri = req.getRequestURI();// 获取ServletContextBinCatServletContext servletContext = (BinCatServletContext) req.getServletContext();// 获取Http请求的文件File requestFile = new File(req.getRealPath(uri));// 处理Http请求的静态文件,如果文件存在(.php后缀除外)就直接返回文件内容,不需要调用Servletif (requestFile.exists() && requestFile.isFile() && !uri.endsWith(".php")) {// 修改状态码resp.setStatus(200, "OK");// 解析文件的MimeTypeString mimeType = Files.probeContentType(requestFile.toPath());if (mimeType == null) {String fileSuffix = FileUtils.getFileSuffix(requestFile.getName());resp.setContentType("text/" + fileSuffix);} else {resp.setContentType(mimeType);}out.write(Files.readAllBytes(requestFile.toPath()));} else {// 遍历所有已注册得Servlet,处理Http请求Set<BinCatServletRegistrationDynamic> dynamics = servletContext.getRegistrationDynamics();for (BinCatServletRegistrationDynamic dynamic : dynamics) {Collection<String> urlPatterns = dynamic.getMappings();for (String urlPattern : urlPatterns) {try {// 检测请求的URL地址和Servlet的地址是否匹配if (Pattern.compile(urlPattern).matcher(uri).find()) {// 修改状态码resp.setStatus(200, "OK");// 调用Servlet请求处理方法dynamic.getServlet().service(req, resp);return;}} catch (Exception e) {// 修改状态码,输出服务器异常信息到浏览器resp.setStatus(500, "Internal Server Error");e.printStackTrace();out.write(("<pre>" + StringUtils.exceptionToString(e) + "</pre>").getBytes());}}}}}}
