当前位置: 首页 > news >正文

Java web基础知识

Servlet

Servlet是sun公司开发的动态web技术
sun在API中提供了一个接口叫做 Servlet ,一个简单的Servlet 程序只需要完成两个步骤
  • 编写一个实现了Servlet接口的类
  • 把这个Java部署到web服务器中

一般来说把实现了Servlet接口的java程序叫做,Servlet

初步认识Servlet

Servlet接口sun公司有两个默认的实现抽象类:HttpServlet,GenericServlet

看看Serlvet接口是怎么在这两个类中实现的

Servlet接口

package javax.servlet;import java.io.IOException;public interface Servlet {void init(ServletConfig var1) throws ServletException;ServletConfig getServletConfig();void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;String getServletInfo();void destroy();
}

这个接口里有五个抽象方法

  • init(ServletConfig var1)
  • getServletConfig()
  • service(ServletRequest var1, ServletResponse var2)
  • getServletInfo()
  • destroy()

这五个方法建立起了Servlet的基本框架:初始化、获取配置、服务功能、获取状态信息、销毁

也体现了servlet的生命周期

  • Servlet 初始化后调用 init () 方法。
  • Servlet 调用 service() 方法来处理客户端的请求。
  • Servlet 销毁前调用 destroy() 方法。
  • 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

其中比较值得观察的是service方法

GenericServlet

package javax.servlet;import java.io.IOException;
import java.io.Serializable;
import java.util.Enumeration;public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {private static final long serialVersionUID = 1L;private transient ServletConfig config;public GenericServlet() {}public void destroy() {}public String getInitParameter(String name) {return this.getServletConfig().getInitParameter(name);}public Enumeration<String> getInitParameterNames() {return this.getServletConfig().getInitParameterNames();}public ServletConfig getServletConfig() {return this.config;}public ServletContext getServletContext() {return this.getServletConfig().getServletContext();}public String getServletInfo() {return "";}public void init(ServletConfig config) throws ServletException {this.config = config;this.init();}public void init() throws ServletException {}public void log(String message) {this.getServletContext().log(this.getServletName() + ": " + message);}public void log(String message, Throwable t) {this.getServletContext().log(this.getServletName() + ": " + message, t);}public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;public String getServletName() {return this.config.getServletName();}
}

还是那五个抽象方法

  • init(ServletConfig var1)
  • getServletConfig()
  • service(ServletRequest var1, ServletResponse var2)
  • getServletInfo()
  • destroy()

可以看到对于service方法这个类并没有做任何的改变,只是对初始化和状态信息获取做出了改变

HttpServlet


package javax.servlet.http;import java.io.IOException;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.ResourceBundle;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;public abstract class HttpServlet extends GenericServlet {private static final String METHOD_DELETE = "DELETE";private static final String METHOD_HEAD = "HEAD";private static final String METHOD_GET = "GET";private static final String METHOD_OPTIONS = "OPTIONS";private static final String METHOD_POST = "POST";private static final String METHOD_PUT = "PUT";private static final String METHOD_TRACE = "TRACE";private static final String HEADER_IFMODSINCE = "If-Modified-Since";private static final String HEADER_LASTMOD = "Last-Modified";private static final String LSTRING_FILE = "javax.servlet.http.LocalStrings";private static ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.http.LocalStrings");public HttpServlet() {}protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String protocol = req.getProtocol();String msg = lStrings.getString("http.method_get_not_supported");if (protocol.endsWith("1.1")) {resp.sendError(405, msg);} else {resp.sendError(400, msg);}}protected long getLastModified(HttpServletRequest req) {return -1L;}protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {NoBodyResponse response = new NoBodyResponse(resp);this.doGet(req, response);response.setContentLength();}protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String protocol = req.getProtocol();String msg = lStrings.getString("http.method_post_not_supported");if (protocol.endsWith("1.1")) {resp.sendError(405, msg);} else {resp.sendError(400, msg);}}protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String protocol = req.getProtocol();String msg = lStrings.getString("http.method_put_not_supported");if (protocol.endsWith("1.1")) {resp.sendError(405, msg);} else {resp.sendError(400, msg);}}protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String protocol = req.getProtocol();String msg = lStrings.getString("http.method_delete_not_supported");if (protocol.endsWith("1.1")) {resp.sendError(405, msg);} else {resp.sendError(400, msg);}}private Method[] getAllDeclaredMethods(Class<? extends HttpServlet> c) {Class<?> clazz = c;Method[] allMethods;for(allMethods = null; !clazz.equals(HttpServlet.class); clazz = clazz.getSuperclass()) {Method[] thisMethods = clazz.getDeclaredMethods();if (allMethods != null && allMethods.length > 0) {Method[] subClassMethods = allMethods;allMethods = new Method[thisMethods.length + allMethods.length];System.arraycopy(thisMethods, 0, allMethods, 0, thisMethods.length);System.arraycopy(subClassMethods, 0, allMethods, thisMethods.length, subClassMethods.length);} else {allMethods = thisMethods;}}return allMethods != null ? allMethods : new Method[0];}protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {Method[] methods = this.getAllDeclaredMethods(this.getClass());boolean ALLOW_GET = false;boolean ALLOW_HEAD = false;boolean ALLOW_POST = false;boolean ALLOW_PUT = false;boolean ALLOW_DELETE = false;boolean ALLOW_TRACE = true;boolean ALLOW_OPTIONS = true;for(int i = 0; i < methods.length; ++i) {String methodName = methods[i].getName();if (methodName.equals("doGet")) {ALLOW_GET = true;ALLOW_HEAD = true;} else if (methodName.equals("doPost")) {ALLOW_POST = true;} else if (methodName.equals("doPut")) {ALLOW_PUT = true;} else if (methodName.equals("doDelete")) {ALLOW_DELETE = true;}}StringBuilder allow = new StringBuilder();if (ALLOW_GET) {allow.append("GET");}if (ALLOW_HEAD) {if (allow.length() > 0) {allow.append(", ");}allow.append("HEAD");}if (ALLOW_POST) {if (allow.length() > 0) {allow.append(", ");}allow.append("POST");}if (ALLOW_PUT) {if (allow.length() > 0) {allow.append(", ");}allow.append("PUT");}if (ALLOW_DELETE) {if (allow.length() > 0) {allow.append(", ");}allow.append("DELETE");}if (ALLOW_TRACE) {if (allow.length() > 0) {allow.append(", ");}allow.append("TRACE");}if (ALLOW_OPTIONS) {if (allow.length() > 0) {allow.append(", ");}allow.append("OPTIONS");}resp.setHeader("Allow", allow.toString());}protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String CRLF = "\r\n";StringBuilder buffer = (new StringBuilder("TRACE ")).append(req.getRequestURI()).append(" ").append(req.getProtocol());Enumeration reqHeaderEnum = req.getHeaderNames();while(reqHeaderEnum.hasMoreElements()) {String headerName = (String)reqHeaderEnum.nextElement();buffer.append(CRLF).append(headerName).append(": ").append(req.getHeader(headerName));}buffer.append(CRLF);int responseLength = buffer.length();resp.setContentType("message/http");resp.setContentLength(responseLength);ServletOutputStream out = resp.getOutputStream();out.print(buffer.toString());}protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String method = req.getMethod();long lastModified;if (method.equals("GET")) {lastModified = this.getLastModified(req);if (lastModified == -1L) {this.doGet(req, resp);} else {long ifModifiedSince = req.getDateHeader("If-Modified-Since");if (ifModifiedSince < lastModified) {this.maybeSetLastModified(resp, lastModified);this.doGet(req, resp);} else {resp.setStatus(304);}}} else if (method.equals("HEAD")) {lastModified = this.getLastModified(req);this.maybeSetLastModified(resp, lastModified);this.doHead(req, resp);} else if (method.equals("POST")) {this.doPost(req, resp);} else if (method.equals("PUT")) {this.doPut(req, resp);} else if (method.equals("DELETE")) {this.doDelete(req, resp);} else if (method.equals("OPTIONS")) {this.doOptions(req, resp);} else if (method.equals("TRACE")) {this.doTrace(req, resp);} else {String errMsg = lStrings.getString("http.method_not_implemented");Object[] errArgs = new Object[]{method};errMsg = MessageFormat.format(errMsg, errArgs);resp.sendError(501, errMsg);}}private void maybeSetLastModified(HttpServletResponse resp, long lastModified) {if (!resp.containsHeader("Last-Modified")) {if (lastModified >= 0L) {resp.setDateHeader("Last-Modified", lastModified);}}}public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {if (req instanceof HttpServletRequest && res instanceof HttpServletResponse) {HttpServletRequest request = (HttpServletRequest)req;HttpServletResponse response = (HttpServletResponse)res;this.service(request, response);} else {throw new ServletException("non-HTTP request or response");}}
}

可以看到这层的类实现了service方法的处理,每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。

但是它默认处理并不是我们所需要的,所以我们自己写的java类就是要重写这些方法。

现在,这个简单的Servlet基础使用链就明了了

RMI

RMI (Java Remote Method Invocation) Java 远程方法调用,是一种允许一个 JVM 上的 object 调用另一个 JVM 上 object 方法的机制

⼀个RMI Server分为三部分:

  • ⼀个继承了 java.rmi.Remote 的接⼝,其中定义我们要远程调⽤的函数
  • ⼀个实现了此接⼝的类
  • ⼀个主类,⽤来创建Registry,并将上⾯的类实例化后绑定到⼀个地址

来分析一下这个RMI设计的意图

一个RMI服务器的三个部分:一个接口、两个类,我理解的它们的作用如下:

  • 接口:作为远程方法调用的调用目标
  • 实现接口的类:用来承载接口方法
为什么要有这样一个类?
有类就可以序列化,序列化之后就可以把一个难以传输的目标变成一个便于传输的流
  • 一个主类:作为Registry存在。
打个比方,它就像一个车站的售票处一样,你来坐车你就要先去它哪里找他买票,你有了对应的票才能找到、乘坐对应的车。
在RMI整体流程它也差不多扮演这个角色,客户端去向Registry请求某个方法,Registry返回一个stub给客户端,客户端在通过stub种的信息找到对应的地址端口建立TCP连接

RMI简单流程

一个简单的demo

服务端

package rmilearn;import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;public class Learn01 {public static void main(String[] args) throws RemoteException, MalformedURLException {HelloRmi rmi = new HelloRmi();LocateRegistry.createRegistry(1099);Naming.rebind("rmi://127.0.0.1:1099/hello",rmi);}
}class HelloRmi extends  UnicastRemoteObject implements Hello {protected HelloRmi() throws RemoteException {super();}@Overridepublic String HelloRm() throws RemoteException {return "hello rmi";}
}
--------------------------------------------------------------------------
package rmilearn;import java.rmi.Remote;
import java.rmi.RemoteException;public interface Hello extends Remote {String HelloRm() throws RemoteException;
}

客户端

public class client {public static void main(String[] args) throws RemoteException, NotBoundException {Registry re = LocateRegistry.getRegistry("localhost",1099);Hello h = (Hello) re.lookup("hello");String s = h.HelloRm();System.out.println(s);}
}

相关文章:

Java web基础知识

Servlet Servlet是sun公司开发的动态web技术 sun在API中提供了一个接口叫做 Servlet &#xff0c;一个简单的Servlet 程序只需要完成两个步骤 编写一个实现了Servlet接口的类 把这个Java部署到web服务器中 一般来说把实现了Servlet接口的java程序叫做&#xff0c;Servlet 初步…...

【Linux学习】01Linux初识与安装

Linux&#xff08;B站黑马&#xff09;学习笔记 01Linux初识与安装 文章目录 Linux&#xff08;B站黑马&#xff09;学习笔记前言01Linux初识与安装操作系统简述Linux初识虚拟机介绍安装VMware Workstation虚拟化软件VMware中安装CentOS7 Linux操作系统下载CentOS操作系统VMwa…...

android 将数据库中的 BLOB 对象动态加载为 XML,并设置到 Android Activity 的内容视图上

以下是一个示例代码,演示如何将数据库中的 BLOB 对象动态加载为 XML,并设置到 Android Activity 的内容视图上: ```java import android.app.Activity; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import and…...

Android12之强弱智能指针sp/wp循环引用死锁问题(一百六十六)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药. 更多原创,欢迎关注:Android…...

springboot自定义Json序列化返回,实现自动转换字典值

自定义序列化 原理 当你使用Spring Boot的Spring Data或者Spring MVC等组件来处理JSON序列化时&#xff0c;Spring框架会在需要将Java对象转换为JSON字符串时调用JsonSerializer。这通常发生在控制器方法返回JSON响应时&#xff0c;或者在将对象保存到数据库等操作中。 // 注册…...

Lostash同步Mysql数据到ElasticSearch(二)logstash脚本配置和常见坑点

1. logstash脚本编写&#xff08;采用单文件对应单表实例&#xff09; 新建脚本文件夹 cd /usr/local/logstash mkdir sql & cd sql vim 表名称.conf #如: znyw_data_gkb_logstash.conf 建立文件夹&#xff0c;保存资源文件更新Id mkdir -p /data/logstash/data/last_r…...

兔兔答题企业版1.0.0版本全网发布,同时开源前端页面到unicloud插件市场

项目说明 兔兔答题是用户端基于uniapp开发支持多端适配&#xff0c;管理端端采用TypeScriptVue3.jselement-plus&#xff0c;后端采用THinkPHP6PHP8Golang开发的一款在线答题应用程序。 问题反馈 线上预览地址 相关问题可以通过下方的二维码&#xff0c;联系到我。了解更多 …...

76、SpringBoot 整合 MyBatis------使用 sqlSession 作为 Dao 组件(就是ssm那一套,在 xml 写sql)

就是 ssm 那套&#xff0c;在xml 上面写sql ★ 基于SqlSession来实现DAO组件的方式 - MyBatis提供的Starter会自动在Spring容器中配置SqlSession&#xff08;其实SqlSessionTemplate实现类&#xff09;、并将它注入其他组件&#xff08;如DAO组件&#xff09;- DAO组件可直接…...

【ROS】RViz、Gazebo和Navigation的关系

1、RViz RViz(Robot Visualization,机器人可视化)是一个用于可视化机器人系统的开源工具,用于显示和调试机器人的传感器数据、状态信息和运动规划等。它是ROS(Robot Operating System)的一部分,是ROS中最常用的可视化工具之一。 RViz:“我们不生产数据只做数据的搬运…...

智能井盖:提升城市井盖安全管理效率

窨井盖作为城市基础设施的重要组成部分&#xff0c;其安全管理与城市的有序运行和群众的生产生活安全息息相关&#xff0c;体现城市管理和社会治理水平。当前&#xff0c;一些城市已经将智能化的窨井盖升级改造作为新城建的重要内容&#xff0c;推动窨井盖等“城市部件”配套建…...

JavaWeb开发-06-SpringBootWeb-MySQL

一.MySQL概述 1.安装、配置 官网下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/ 2.数据模型 3.SQL简介 二.数据库设计-DDL 1.数据库 官网&#xff1a;http:// https://www.jetbrains.com/zh-cn/datagrip/ 2.表&#xff08;创建、查询、修改、删除&#xff09; #…...

十六、垃圾回收相关概念

目录 一、System.gc()的理解二、内存溢出和内存泄漏2、内存泄漏 三、Stop the World1、什么是 stop the word ? 四、垃圾回收的并行和并发1、并发和并发2、垃圾回收的并行和并发 五、安全点与安全区域1、什么是安全点&#xff1f;2、安全区域 六、强引用&#xff08;不可回收&…...

hive、spark、presto 中的增强聚合-grouping sets、rollup、cube

目录 1、什么是增强聚合和多维分析函数&#xff1f; 2、grouping sets - 指定维度组合 3、with rollup - 上卷维度组合 4、with cube - 全维度组合 5、Grouping__ID、grouping() 的使用场景 6、使用 增强聚合 会不会对查询性能有提升呢&#xff1f; 7、对grouping sets、…...

elasticsearch bulk 批量操作

1&#xff1a;bulk 是 elasticsearch 提供的一种批量增删改的操作API bulk 对 JSON串 有着严格的要求。每个JSON串 不能换行 &#xff0c;只能放在同一行&#xff0c;同时&#xff0c; 相邻的JSON串之间必须要有换行 &#xff08;Linux下是\n&#xff1b;Window下是\r\n&#…...

力扣11、 盛最多水的容器

方法一&#xff1a;双指针 考察&#xff1a; 贪心、数组、双指针 说明 本题是一道经典的面试题&#xff0c;最优的做法是使用「双指针」。如果读者第一次看到这题&#xff0c;不一定能想出双指针的做法。 复杂度分析 时间复杂度&#xff1a;O(N)&#xff0c;双指针总计最多…...

IIC协议详解

目录 1.IIC协议概述 2.IIC总线传输 3.IIC-51单片机应用 1.起始信号 2.终止信号 3.应答信号 4.数据发送 4.IIC-32单片机应用 用到的库函数&#xff1a; 1.IIC协议概述 IIC全称Inter-Integrated Circuit (集成电路总线)是由PHILIPS公司在80年代开发的两线式串行总线&…...

element ui-表头自定义提示框

版本 “element-ui”: “^2.15.5”,需求&#xff1a;鼠标悬浮到该列表头&#xff0c;显示提示框代码 <el-table:data"xxxx"><el-table-column label"序号" width"40" type"index" /><el-table-columnv-for"(ite…...

Python 图形化界面基础篇:创建顶部菜单

Python 图形化界面基础篇&#xff1a;创建顶部菜单 引言 Tkinter 库简介步骤1&#xff1a;导入 Tkinter 模块步骤2&#xff1a;创建 Tkinter 窗口步骤3&#xff1a;创建顶部菜单栏步骤4&#xff1a;处理菜单项的点击事件步骤5&#xff1a;启动 Tkinter 主事件循环 完整示例代码…...

java实现十大排序算法

文章目录 冒泡排序选择排序插入排序希尔排序归并排序快速排序堆排序桶排序基数排序计数排序验证各个排序的时间复杂度和空间复杂度 冒泡排序 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单的比较排序算法&#xff0c;它的基本思想是重复地交换相邻的两个元素&#x…...

Linux日志管理-logrotate(crontab定时任务、Ceph日志转储)

文章目录 一、logrotate概述二、logrotate基本用法三、logrotate运行机制logrotate参数 四、logrotate是怎么做到滚动日志时不影响程序正常的日志输出呢&#xff1f;Linux文件操作机制方案一方案二 五、logrotate实战--Ceph日志转储参考 一、logrotate概述 logrotate是一个用于…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)

文章目录 1.什么是Redis&#xff1f;2.为什么要使用redis作为mysql的缓存&#xff1f;3.什么是缓存雪崩、缓存穿透、缓存击穿&#xff1f;3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...