手写一个民用Tomcat (05)

继续我们这次的优化,上次是request, 这次是response,同时request,response 针对 引入门面模式,把负责的逻辑隐藏起来,展示一个 好的好的门面给servlet 。

先看下 response 

public class JxdResponse implements HttpServletResponse {private static final int BUFFER_SIZE = 1024;JxdRequest request;OutputStream output;PrintWriter writer;String contentType = null;long contentLength = -1;String charset = null;String characterEncoding = null;String protocol = "HTTP/1.1";public OutputStream getOutput() {return output;}public void setOutput(OutputStream output) {this.output = output;}public JxdResponse(OutputStream output) {this.output = output;}public void setRequest(JxdRequest request) {this.request = request;}//headers是一个保存头信息的mapMap<String, String> headers = new ConcurrentHashMap<>();//默认返回OKString message = getStatusMessage(HttpServletResponse.SC_OK);int status = HttpServletResponse.SC_OK;@Overridepublic void addHeader(String name, String value) {headers.put(name, value);if (name.toLowerCase() == DefaultHeaders.CONTENT_LENGTH_NAME) {setContentLength(Integer.parseInt(value));}if (name.toLowerCase() == DefaultHeaders.CONTENT_TYPE_NAME) {setContentType(value);}}@Overridepublic void setHeader(String name, String value) {headers.put(name, value);if (name.toLowerCase() == DefaultHeaders.CONTENT_LENGTH_NAME) {setContentLength(Integer.parseInt(value));}if (name.toLowerCase() == DefaultHeaders.CONTENT_TYPE_NAME) {setContentType(value);}}//"HTTP/1.1 ${StatusCode} ${StatusName}\r\n" +//            "Content-Type: ${ContentType}\r\n" +//            "Server: minit\r\n" +//            "Date: ${ZonedDateTime}\r\n" +public void sendHeaders() throws IOException {PrintWriter outputWriter = getWriter();//下面这一端是输出状态行outputWriter.print(this.getProtocol());outputWriter.print(" ");outputWriter.print(status);if (message != null) {outputWriter.print(" ");outputWriter.print(message);}outputWriter.print("\r\n");if (getContentType() != null) {outputWriter.print("Content-Type: " + getContentType() + "\r\n");if (getContentLength() >= 0) {outputWriter.print("Content-Length: " + getContentLength() + "\r\n");}//输出头信息Iterator<String> names = headers.keySet().iterator();while (names.hasNext()) {String name = names.next();String value = headers.get(name);outputWriter.print(name);outputWriter.print(": ");outputWriter.print(value);outputWriter.print("\r\n");}//最后输出空行outputWriter.print("\r\n");outputWriter.flush();}}/*** 获取状态码返回信息** @param status* @return*/protected String getStatusMessage(int status) {switch (status) {case SC_OK:return ("OK");case SC_ACCEPTED:return ("Accepted");case SC_BAD_GATEWAY:return ("Bad Gateway");case SC_BAD_REQUEST:return ("Bad Request");case SC_CONTINUE:return ("Continue");case SC_FORBIDDEN:return ("Forbidden");case SC_INTERNAL_SERVER_ERROR:return ("Internal Server Error");case SC_METHOD_NOT_ALLOWED:return ("Method Not Allowed");case SC_NOT_FOUND:return ("Not Found");case SC_NOT_IMPLEMENTED:return ("Not Implemented");case SC_REQUEST_URI_TOO_LONG:return ("Request URI Too Long");case SC_SERVICE_UNAVAILABLE:return ("Service Unavailable");case SC_UNAUTHORIZED:return ("Unauthorized");default:return ("HTTP Response Status " + status);}}/*** 这个方法是静态方法演示** @throws IOException*/public void sendStaticResource() throws IOException {byte[] bytes = new byte[BUFFER_SIZE];FileInputStream fis = null;try {File file = new File(JxdHttpServer.FILE_ROOT, request.getUri());if (file.exists()) {fis = new FileInputStream(file);int ch = fis.read(bytes, 0, BUFFER_SIZE);while (ch != -1) {output.write(bytes, 0, ch);ch = fis.read(bytes, 0, BUFFER_SIZE);}output.flush();} else {String errorMessage = "HTTP/1.1 404 FIle Not Found\r\n" +"Content-Type: text/html\r\n" +"Content-Length: 23\r\n" +"\r\n" +"<h1>error未知</h1>";output.write(errorMessage.getBytes());}} catch (Exception e) {System.out.println(e.toString());} finally {if (fis != null) {fis.close();}}}public long getContentLength() {return this.contentLength;}public void setContentLength(long contentLength) {this.contentLength = contentLength;}public String getProtocol() {return protocol;}public void setProtocol(String protocol) {this.protocol = protocol;}@Overridepublic String getContentType() {return this.contentType;}@Overridepublic PrintWriter getWriter() throws IOException {writer = new PrintWriter(new OutputStreamWriter(output, getCharacterEncoding()), true);return writer;}@Overridepublic String getCharacterEncoding() {return characterEncoding;}@Overridepublic void setCharacterEncoding(String characterEncoding) {this.characterEncoding = characterEncoding;}
}

我们整理了一下,返回引入一个getStatusMessage 方法和 sendHeaders 方法 这样不用再拼接字符串了。

在看一下我们的 JxdServletProcessor

    public void process(JxdRequest request, JxdResponse response) {
//首先根据uri最后一个/号来定位,后面的字符串认为是servlet名字String uri = request.getUri();String servletName = uri.substring(uri.lastIndexOf("/") + 1);URLClassLoader loader = null;try {
// create a URLClassLoaderURL[] urls = new URL[1];URLStreamHandler streamHandler = null;File classPath = new File(JxdHttpServer.WEB_ROOT);String repository = (new URL("file", null, classPath.getCanonicalPath() + File.separator)).toString();urls[0] = new URL(null, repository, streamHandler);loader = new URLClassLoader(urls);} catch (IOException e) {System.out.println(e.toString());}//由上面的URLClassLoader加载这个servletClass<?> servletClass = null;Servlet servlet = null;try {HttpRequestFacade requestFacade = new HttpRequestFacade(request);HttpResponseFacade responseFacade = new HttpResponseFacade(response);servletClass = loader.loadClass(servletName);response.setCharacterEncoding("UTF-8");response.addHeader(DefaultHeaders.CONTENT_TYPE_NAME,"text/html;charset=UTF-8");response.sendHeaders();servlet = (Servlet) servletClass.newInstance();servlet.service(requestFacade, responseFacade);} catch (ClassNotFoundException | IOException e) {System.out.println(e.toString());} catch (IllegalAccessException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (ServletException e) {e.printStackTrace();}}
}

之前的 OKMessage 拼接 响应字符串方法就不需要了。

同时引入两个门面HttpRequestFacade,HttpResponseFacade

看下 我们的两个类的代码:

public class HttpRequestFacade implements HttpServletRequest {private HttpServletRequest request;public HttpRequestFacade(JxdRequest request) {this.request = request;}public Object getAttribute(String name) {return request.getAttribute(name);}public Enumeration getAttributeNames() {return request.getAttributeNames();}public String getCharacterEncoding() {return request.getCharacterEncoding();}@Overridepublic void setCharacterEncoding(String s) throws UnsupportedEncodingException {request.setCharacterEncoding(s);}public int getContentLength() {return request.getContentLength();}@Overridepublic long getContentLengthLong() {return 0;}public String getContentType() {return request.getContentType();}@Overridepublic String getAuthType() {return null;}public Cookie[] getCookies() {return request.getCookies();}@Overridepublic long getDateHeader(String s) {return 0;}@Overridepublic String getHeader(String s) {return null;}public Enumeration getHeaderNames() {return request.getHeaderNames();}public Enumeration getHeaders(String name) {return request.getHeaders(name);}public ServletInputStream getInputStream() throws IOException {return request.getInputStream();}public int getIntHeader(String name) {return request.getIntHeader(name);}public String getMethod() {return request.getMethod();}@Overridepublic String getPathInfo() {return null;}@Overridepublic String getPathTranslated() {return null;}@Overridepublic String getContextPath() {return null;}public String getParameter(String name) {return request.getParameter(name);}public Map getParameterMap() {return request.getParameterMap();}@Overridepublic String getProtocol() {return null;}@Overridepublic String getScheme() {return null;}@Overridepublic String getServerName() {return null;}@Overridepublic int getServerPort() {return 0;}public Enumeration getParameterNames() {return request.getParameterNames();}public String[] getParameterValues(String name) {return request.getParameterValues(name);}public String getQueryString() {return request.getQueryString();}@Overridepublic String getRemoteUser() {return null;}@Overridepublic boolean isUserInRole(String s) {return false;}@Overridepublic Principal getUserPrincipal() {return null;}@Overridepublic String getRequestedSessionId() {return null;}public BufferedReader getReader() throws IOException {return request.getReader();}@Overridepublic String getRemoteAddr() {return null;}@Overridepublic String getRemoteHost() {return null;}public String getRequestURI() {return request.getRequestURI();}public StringBuffer getRequestURL() {return request.getRequestURL();}@Overridepublic String getServletPath() {return null;}public HttpSession getSession() {return request.getSession();}@Overridepublic String changeSessionId() {return null;}@Overridepublic boolean isRequestedSessionIdValid() {return false;}@Overridepublic boolean isRequestedSessionIdFromCookie() {return false;}@Overridepublic boolean isRequestedSessionIdFromURL() {return false;}@Overridepublic boolean isRequestedSessionIdFromUrl() {return false;}@Overridepublic boolean authenticate(HttpServletResponse httpServletResponse) throws IOException, ServletException {return false;}@Overridepublic void login(String s, String s1) throws ServletException {}@Overridepublic void logout() throws ServletException {}@Overridepublic Collection<Part> getParts() throws IOException, ServletException {return null;}@Overridepublic Part getPart(String s) throws IOException, ServletException {return null;}@Overridepublic <T extends HttpUpgradeHandler> T upgrade(Class<T> aClass) throws IOException, ServletException {return null;}public HttpSession getSession(boolean create) {return request.getSession(create);}public void removeAttribute(String attribute) {request.removeAttribute(attribute);}@Overridepublic Locale getLocale() {return null;}@Overridepublic Enumeration<Locale> getLocales() {return null;}@Overridepublic boolean isSecure() {return false;}@Overridepublic RequestDispatcher getRequestDispatcher(String s) {return null;}@Overridepublic String getRealPath(String s) {return null;}@Overridepublic int getRemotePort() {return 0;}@Overridepublic String getLocalName() {return null;}@Overridepublic String getLocalAddr() {return null;}@Overridepublic int getLocalPort() {return 0;}@Overridepublic ServletContext getServletContext() {return null;}@Overridepublic AsyncContext startAsync() throws IllegalStateException {return null;}@Overridepublic AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException {return null;}@Overridepublic boolean isAsyncStarted() {return false;}@Overridepublic boolean isAsyncSupported() {return false;}@Overridepublic AsyncContext getAsyncContext() {return null;}@Overridepublic DispatcherType getDispatcherType() {return null;}public void setAttribute(String key, Object value) {request.setAttribute(key, value);}
}

public class HttpResponseFacade implements HttpServletResponse {private HttpServletResponse response;public HttpResponseFacade(JxdResponse response) {this.response = response;}@Overridepublic void addCookie(Cookie cookie) {response.addCookie(cookie);}@Overridepublic boolean containsHeader(String s) {return response.containsHeader(s);}@Overridepublic String encodeURL(String s) {return response.encodeURL(s);}@Overridepublic String encodeRedirectURL(String s) {return response.encodeRedirectURL(s);}@Overridepublic String encodeUrl(String s) {return response.encodeUrl(s);}@Overridepublic String encodeRedirectUrl(String s) {return response.encodeRedirectUrl(s);}@Overridepublic void sendError(int i, String s) throws IOException {response.sendError(i, s);}@Overridepublic void sendError(int i) throws IOException {response.sendError(i);}@Overridepublic void sendRedirect(String s) throws IOException {response.sendRedirect(s);}@Overridepublic void setDateHeader(String s, long l) {response.setDateHeader(s, l);}@Overridepublic void addDateHeader(String s, long l) {response.addDateHeader(s, l);}@Overridepublic void setHeader(String s, String s1) {response.setHeader(s, s1);}@Overridepublic void addHeader(String s, String s1) {response.addHeader(s, s1);}@Overridepublic void setIntHeader(String s, int i) {response.setIntHeader(s, i);}@Overridepublic void addIntHeader(String s, int i) {response.addIntHeader(s, i);}@Overridepublic void setStatus(int i) {response.setStatus(i);}@Overridepublic void setStatus(int i, String s) {response.setStatus(i, s);}@Overridepublic int getStatus() {return response.getStatus();}@Overridepublic String getHeader(String s) {return response.getHeader(s);}@Overridepublic Collection<String> getHeaders(String s) {return response.getHeaders(s);}@Overridepublic Collection<String> getHeaderNames() {return response.getHeaderNames();}@Overridepublic String getCharacterEncoding() {return response.getCharacterEncoding();}@Overridepublic String getContentType() {return response.getContentType();}@Overridepublic ServletOutputStream getOutputStream() throws IOException {return response.getOutputStream();}@Overridepublic PrintWriter getWriter() throws IOException {return response.getWriter();}@Overridepublic void setCharacterEncoding(String s) {response.setCharacterEncoding(s);}@Overridepublic void setContentLength(int i) {response.setContentLength(i);}@Overridepublic void setContentLengthLong(long l) {response.setContentLengthLong(l);}@Overridepublic void setContentType(String s) {response.setContentType(s);}@Overridepublic void setBufferSize(int i) {response.setBufferSize(i);}@Overridepublic int getBufferSize() {return response.getBufferSize();}@Overridepublic void flushBuffer() throws IOException {response.flushBuffer();}@Overridepublic void resetBuffer() {response.resetBuffer();}@Overridepublic boolean isCommitted() {return response.isCommitted();}@Overridepublic void reset() {response.reset();}@Overridepublic void setLocale(Locale locale) {response.setLocale(locale);}@Overridepublic Locale getLocale() {return response.getLocale();}
}

没什么难点,主要就是引入门面模式进行整理,之前都暴露着各种方法,用户在使用的时候会看到,同时 也避免 被更改 和强转的风险。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/821675.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Yolo-world+Python-OpenCV之摄像头视频实时目标检测

上一次介绍了如何使用最基本的 Yolo-word来做检测&#xff0c;现在我们在加opencv来做个实时检测的例子 基本思路 1、读取离线视频流 2、将视频帧给yolo识别 3、根据识别结果 对视频进行绘制边框、加文字之类的 完整代码如下&#xff1a; import datetimefrom ultralytics …

电竞陪玩系统开发平台搭建(小程序,公众号,app)线上线下皆有,线下计算距离。

六大核心功能 1.游戏陪练:可以选择当下火爆的游戏内容&#xff0c;选择游戏大神、职业玩家进行陪练&#xff0c;也可约附近路人玩家或是身边的小伙伴语音组队开黑&#xff0c;一起享受边玩游戏边吐槽的无限乐趣。 2.约玩交友:除了游戏陪玩功能&#xff0c;系统还设置了单独的语…

SpringBlade dict-biz/list SQL 注入漏洞复现

0x01 免责声明 请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;作者不为此承担任何责任。工具来自网络&#xff0c;安全性自测&#xff0c;如有侵权请联系删…

Python LEGB规则

Python在查找“名称”时&#xff0c;是按照LEGB规则查找的&#xff1a; Local&#xff1a; 指的就是函数或者类的方法内部 Enclosed&#xff1a; 指的是嵌套函数&#xff08;一个函数包裹另一个函数&#xff0c;闭包&#xff09; Global&#xff1a; 指的是模块中的全局变量 Bu…

含多种需求响应及电动汽车的微网/虚拟电厂日前优化调度

1 主要内容 程序主要建立一个微网/虚拟电厂的日前优化调度模型&#xff0c;以燃气轮机运行成本、购售电费用、电动汽车电池损耗成本以及需求响应费用之和为目标&#xff0c;在日前经济调度模型中&#xff0c;加入了电动汽车模型&#xff0c;考虑了电动汽车出行规律以及充放电规…

python之flask安装以及使用

1 flask介绍 Flask是一个非常小的Python Web框架&#xff0c;被称为微型框架&#xff1b;只提供了一个稳健的核心&#xff0c;其他功能全部是通过扩展实现的&#xff1b;意思就是我们可以根据项目的需要量身定制&#xff0c;也意味着我们需要学习各种扩展库的使用。 2 python…

进程和线程的区别和联系

目录 进程&#xff08;Process&#xff09;&#xff1a; 定义&#xff1a; 创建与销毁&#xff1a; 独立性&#xff1a; 线程&#xff08;Thread&#xff09;&#xff1a; 联系和区别 进程&#xff08;Process&#xff09;&#xff1a; 定义&#xff1a; 进程是程序执行…

【待解决】Could not find encoder for codec_id=27,opencv-python 保存H264格式的错误记录

【待解决】Could not find encoder for codec_id27&#xff0c;opencv-python 保存H264格式的错误记录 代码 cv2.VideoWriter(vide_save_path, cv2.VideoWriter_fourcc(*avc1), fps, (width, height))报错 [ERROR:039.657] global cap_ffmpeg_impl.hpp:3130 open Could not …

超越GPT-4V,苹果多模态大模型上新,神经网络形态加速MLLM(一)

4月8日&#xff0c;苹果发布了其最新的多模态大语言模型&#xff08;MLLM &#xff09;——Ferret-UI&#xff0c;能够更有效地理解和与屏幕信息进行交互&#xff0c;在所有基本UI任务上都超过了GPT-4V&#xff01; 苹果开发的多模态模型Ferret-UI增强了对屏幕的理解和交互&am…

【触想智能】如何选购到一款合适的工业电脑一体机

工业电脑一体机是专为工业环境而设计的一种工业计算机。工业电脑一体机和普通的计算机不一样&#xff0c;它对产品的参数性能要求很高&#xff0c;因为它们通常会运行在高低温、电磁干扰、高粉尘、湿度大的恶劣环境中&#xff0c;所以相应的要求工业电脑一体机必须具备良好的宽…

UE5下载与安装

官方网站&#xff1a;https://www.unrealengine.com/zh-CN 1、下载启动程序安装包。 登录官网后&#xff0c;点击首页右侧下载按钮下载Epic Games启动程序的安装包&#xff0c;如下图&#xff1a; 2、安装启动程序。 双击步骤1所下载安装软件&#xff0c;如下图&#xff1a;…

华为校招机试 - 健康餐(20240410)

题目描述 某减肥食堂,每一份菜都标记了卡路里。 一位顾客,根据营养师的建议,每次饮食都要将卡路里控制在一定区间内(含上下限的值),请问 他有多少种选择? 为了简单起见,每份菜的卡路里用整数表示,且每份菜的卡路里数各不相同; 同一个菜品可以打任意多份。 输入描…

vivado AXI 接口事件

AXI 接口事件 在 Vivado 硬件管理器中 &#xff0c; 如果使用 System ILA IP 对设计 AXI 接口进行调试 &#xff0c; 那么“波形 (Waveform) ”窗口会显示对 应于 System ILA 所探测的接口的接口插槽、事件和信号组。正如下图所示 &#xff0c; “ Waveform ”窗口会显示…

中立分析腾讯云故障相关的事件

最近腾讯云的故障&#xff0c;让一堆云计算爱好者兴奋地远看指点江山、近看沐猴而冠。我比这群爱好者们更了解云计算&#xff0c;但是我尊重我的读者&#xff0c;你们从我这里看到的科普信息&#xff0c;不仅仅只有情绪价值。 在信息爆炸的时代&#xff0c;大家关注和信任某个媒…

探索人工智能:AI如何改变我们的工作和生活

人工智能&#xff08;AI&#xff09;技术的迅猛发展正逐步改变我们的工作方式和生活习惯。从自动化和数据分析到增强决策和个性化服务&#xff0c;AI的应用范围广泛&#xff0c;其潜力巨大。以下是AI如何在各个方面改变我们的工作和生活的一些关键领域&#xff1a; ### 工作领…

三道模拟题

P1003 [NOIP2011 提高组] 铺地毯 题目描述 原题点这里-->P1003 [NOIP2011 提高组] 铺地毯 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 为了准备一个独特的颁奖典礼&#xff0c;组织者在会场的一片矩形区域&#xff08;可看做是平面直角坐标系的第一象限&#xff09;铺…

【Redis 神秘大陆】007 安全监控

七、Redis 安全&监控 当你发现这些内容对你有帮助时&#xff0c;为了支持我的工作&#xff0c;不妨给一个免费的⭐Star&#xff0c;这将是对我最大的鼓励&#xff01;感谢你的陪伴与支持&#xff01;一起在技术的路上共同成长吧&#xff01;点击链接&#xff1a;GitHub | …

【C++】哈希一

这篇博客要说的是哈希算法&#xff0c;哈希又称为散列&#xff0c;它是将存储的值和存储的位置建立起关联关系的一种算法&#xff0c;或者说是一种将任意长度的数据映射为固定长度的输出的算法。 什么意思呢&#xff1f;我们来看一个例子&#xff1a;比如说我们要存储1&#xf…

excel试题转word格式

序号试题选项答案 格式如上。输出后在做些适当调整就可以。 import pandas as pd from docx import Document from docx.shared import Inches# 读取Excel文件 df pd.read_excel(r"你的excel.xlsx")# 创建一个新的Word文档 doc Document()# 添加标题 doc.add_headi…

【SLAM】在Win10上实现Nerf-Pytorch【GPU版】

文章目录 ReadMe安装依赖运行下载两个示例数据集:lego和fern训练一个低分辨率的Lego NeRF:训练一个低分辨率蕨类植物NeRF:更多数据集预训练模型可复现实现1、下载nerf-pytorch工程2、安装依赖3、下载数据4、运行lego NeRF:ReadMe Github链接 NeRF (神经辐射场)是一种在合成…