标签:B/S结构、javaweb、Tomcat、servlet规范、网络通信
1.B/S和C/S架构
众所周知,互联网通信分为C/S架构和B/S架构,具体如下:
C/S架构:
- C/S:Client/Server,即客户端/服务器架构
- 客户端:即发起请求的一端;如我们的qq客户端打字“你好啊”并且发送到对方;
- 服务器:接收请求的一端,如qq服务器接收到上述信息;
- 使用场景:娱乐市场
- 优点:客户端界面好看,减轻服务器负载,数据更安全
- 缺点:客户端更新频繁,用户必须下载客户端,
- 功能:服务器负责接收客户端发来的请求,称为request阶段,然后将找到的资源返回给客户端,称为response响应阶段。
B/S架构:
- B/S:Brower/Server,即浏览器/服务器架构
- 浏览器:即用户安装的浏览器,如chrome,firefox,edge
- 服务器:接收浏览器请求的一端,又称为web服务器,http服务器
- 其中Tomcat服务器较为常用,轻量级,免费
- 实现了两个JAVAEE规范【共13个】,即servlet规范和jsp规范
- 使用场景:企业
- 优点:轻量级,不必经常更新,可以发送任意指令
- 缺点:服务器负载大,速度慢
- 功能:服务器负责接收浏览器发来的请求,称为request阶段,然后将找到的资源返回给浏览器,称为response响应阶段。
- 关键点:网站的高并发问题
- B/S是学习的重点,因为java后端开发程序员经常会在企业中处理brower的请求,而对于web前端html,css和javascript仅做了解即可;而其中java后端关键就是servlet规范。
2.B/S架构角色划分
- 流程:用户在浏览器输入http://www.baidu.com:80/index.html之后,回车,此时浏览器会把该请求封装为request请求报文,经过dns解析为IP地址找到百度服务器的主机,通过80端口号与百度的web服务器建立通信,想要访问的是百度wb服务器根目录下的index.html页面,web服务器查找后返回response响应报文,即想要的资源。
- 不难发现,角色有:
- 浏览器→负责封装、解封HTTP请求报文【request请求,response请求】
- web服务器→根据URL寻找资源【Tomcat服务器、jetty服务器】
- 后端人员→负责编写java小程序和配置路径与程序类名的映射关系【YOU!】
- mysql数据库→存储资源,如员工工资表等【mysql,jdbc】
- HTTP请求报文【request】
- 结构:请求行【请求方式、URI、HTTP版本号】 、请求头、空白行、响应行
Get请求: GET /wodewangzhan/getservlet?username=45&password=55555 HTTP/1.1 //请求头 Host: localhost:8080 Connection: keep-alive sec-ch-ua: "Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99" sec-ch-ua-mobile: ?0 sec-ch-ua-platform: "Windows" Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,**;q=0.8,application/signed-exchange;v=b3;q=0.9 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document Referer: http://localhost:8080/wodewangzhan/index.html Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9 //请求体 username: 123456 password: 999999999【注意】这里请求行中路径为URI,统一资源标识符,仅仅是资源的在站点的位置,他是整个URL的一部分。
- HTTP响应报文【response】
//第一部分:状态行 版本号 状态码 HTTP/1.1 304 //状态码:200 成功;404 资源不存在,要么路径出错,要么资源并没有启动成功 //405 请求方式和处理方式不一样,post用get处理 //500 服务器后台程序出错 //4开头 浏览器册出错 //5开头 服务器侧出错 // ok正常 not found 资源找不到 //第二部分 响应头 关键是content-type,告诉浏览器我返回的是什么类型的资源 ETag: W/"865-1637892866027" Date: Fri, 26 Nov 2021 02:20:44 GMT Keep-Alive: timeout=20 //响应时间,内容长度和类型; Connection: keep-alive //第三部分:响应体get请求 get serverh1>
- HTTP请求方法中POST和GET方法的区别?
区别1:日常使用除非在form表单的method方法中显式声明为post,否则都是默认为get方式
区别2:post对长度类型无限制,get只能传输字符串,并且有长度限制
区别3:post的请求参数信息在请求体中,get请求参数在请求行中,即明文展示
区别4:get常用于获取服务器的数据,而post常用于向服务器提交数据,如文件上传
区别5:get是安全的,post由于上传文件因此有安全风险,同时为了保密,因此表单大多数使用的是post方法
区别6:get方式支持缓存,而post方式不支持浏览器缓存,因此如果想访问变动大的数据要用post,否则用get
相同点:二者都是name1=value1&name2=value2&name3=value3...的规范,而这里的 name字段就是相当于key字段,value就是对应key的value字段
- 互联网通信协议流程图
资源分类:静态资源和动态资源
- 静态资源
- 如html,js,css样式和图片、文本、视频等资源,有固定的存放位置,内容一般不改变的资源。
- 动态资源
- java小程序,即servlet对象,用户想要输入自己的信息经过网站的程序才能返回某个值,因此java小程序就是动态资源,用户想要获取某些操作的结果。
- web-inf目录:html,js,css资源不能放在这,因为受保护【有配置文件】
3.Tomcat服务器配置_手工配置_初级尝试
3.1 几个明确点:
- Tomcat是web服务器,端口默认为8080
3.2 配置流程
第一步:下载tomcat,如下所示,在左边选择版本,我这里选择tomcat9.
Apache Tomcat® - Welcome!https://tomcat.apache.org/【注意】tomcat10中有些原本中的库名发生了改变,由javax改为了jakarta,这是因为本来是javaee规范,oracle将tomcat捐给了apache开源基金会的原因。Apache Tomcat® - Welcome!
第二步:在系统环境变量添加java_home和catalina_home的环境变量,以便在cmd的dos窗口可以进行开发。
【PS】tomcat是java写的,自然需要jvm,即需要关联jdk包,同时由于tomcat不知道catalina在哪里,故需要加入catalina_home。
第三步:第一次启动关闭tomcat,即进入tomcat安装包bin目录,cmd进入该目录,敲击startup可以发现启动了,然后shutdown即可。
第四步:建立站点文件夹并进行静态资源访问:
→webapp文件夹是站点文件夹,默认是root站点,这里新建crm文件夹
→→在crm文件夹放入静态资源,这里随便放一张图片,如4.jpg
→→→启动tomcat,注意不要关闭任何dos窗口
→→→→在浏览器输入http://localhost:8080/crm/4.jpg,回车,此时成功!
第五步:动态资源访问
【前知】需要知道的是,访问动态资源就是用户输入一段链接,tomcat服务器解析为某个java小程序,这里叫servlet对象,然后去找对应的类,实例化对象,执行其service方法,有可能还会操作数据库进行查询,最后返回。
→上文的crm文件夹下新建WEB-INF文件夹【全部大写!】
→→在WEB-INF文件夹下新建classes文件【存放小程序的.calss文件】
→→在WEB-INF文件夹下新建一个目录,名为lib【用于第三方依赖库,如mysql驱动】
→→→在WEB-INF文件夹下新建web.xml文件,当然这个文件最好复制下面的粘贴到你这里,因为这是tomcat默认的配置文件【tomcat从这里找到用户的urL路径和你写的类的映射】
→→编写小程序:
【注意】事实上,浏览器和web服务器之间由Oracle提供了一套规范,即servlet规范,浏览器、web服务器厂商和java开发人员都要遵循这套规范,实现解耦合、可拓展的目的。
因此,java程序员编写小程序就是实现servlet接口然后重写service方法即可。
小程序第一步:
package source.servlet; import javax.servlet.*; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; public class serve implements Servlet { public serve( ) { System.out.println("serve的构造方法被执行了"); } @Override public void init(ServletConfig servletConfig) throws ServletException { System.out.println("serve的init方法被执行了"); } @Override public ServletConfig getServletConfig() { System.out.println("serve的getserveconfig被执行了");return null; } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("serve的构services被执行了"); //将信息输出到浏览器上;//该语句最好在设置流之前,以免乱码; servletResponse.setContentType("text/html;charset=utf-8"); PrintWriter pw = servletResponse.getWriter(); pw.println("1234"); } @Override public String getServletInfo() { System.out.println("serve的getServletInfo方法被执行了"); return null; } @Override public void destroy() { System.out.println("serve的destroy方法被执行了"); } }然后将其编译到上文讲到的classes文件夹即可。【由于javax.servlet不是JDK规范,因此需要在系统的 jre安装目录下的ext文件夹加入我们下载的javax.servlet包,后者可以在tomcat的lib文件夹找到相关包】
小程序第二步:关联web.xml文件→注册
dd serverLet.FirstDemo dd /SDFAD/SDAS 【tomcat将浏览器的url-pattern找到servlet-name,进而找到serverLet.FirstDemo类执行】
小程序第三步:开启tomcat服务器,输入URL【http://localhost:8080/crm/SDFAD/SDAS 】,关闭服务器
【注意】可能运行会出现乱码问题,可参考如下修改:
至此,一个简单的小程序开发完毕,不过,考虑到有时候链接太长,可以将用户输入URL→返回资源优化为用户点击超链接→解析为URL→返回资源,如下:
第一步:在crm目录下新建index.html文件,内容如下:
<!doctype = html>你好啊 我是打印
我是JDBC
html>第二步:访问http://localhost:8080/crm/INDEX.HTML,然后点击按钮,即可与上文的小程序过程一致。
过程总结:Tomcat启动自动执行main方法,进而执行service方法,我们只需要实现servlet接口,重写service方法,注册web.xml文件即可用urL访问。
4.Tomcat服务器配置_手工配置_JDBC实战
只需采用六步法实现servlet接口与jdbc接口,编译到classes文件夹,注册到web.xml,引入mysql驱动到lib包即可用URL访问:
// javac -encoding utf8 -d D:minisoftwareapache-tomcat-9.0.55webappscrmWEB-INFclasses serverLetStuInfo_Get.java package serverLet; import src.JDBC.Utils; import javax.servlet.*; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class StuInfo_Get implements Servlet { @Override public void init(ServletConfig servletConfig) throws ServletException { } @Override public ServletConfig getServletConfig() { return null; } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { servletResponse.setContentType("text/html;charset = utf-8"); PrintWriter pw = servletResponse.getWriter(); Connection col =null; PreparedStatement ps = null; ResultSet rs = null; try { col = Utils.getConnection(); String sql ="select * from user where sal=?"; ps = col.prepareStatement(sql); ps.setInt(1, 2000); rs = ps.executeQuery(); while(rs.next()){ String name = rs.getString("username"); String sal = rs.getString("sal"); pw.println("name:" + name + "sal is " + sal); } } catch (Exception e) { e.printStackTrace(); }finally { Utils.close(col,ps,rs); } } @Override public String getServletInfo() { return null; } @Override public void destroy() { } }
5. Tomcat服务器配置_IDEA中配置
第一步:新建空工程,新建一个javase普通模块,这里是servlet01
第二步:将上述模块变成javaee模块,方法:模块右键添加框架支持,选择web applcation,其中自动生成的蓝眼睛的web文件夹就相当于我们前面配置的crm文件夹。
第三步:删除index.jsp【暂时用不着】
第四步:写程序【src目录下新建一个source.servlet包】
public class serve implements Servlet { public serve( ) { System.out.println("serve的构造方法被执行了"); } @Override public void init(ServletConfig servletConfig) throws ServletException { System.out.println("serve的init方法被执行了"); } @Override public ServletConfig getServletConfig() { System.out.println("serve的getserveconfig被执行了");return null; } @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("serve的构services被执行了"); servletResponse.setContentType("text/html;charset = utf-8"); PrintWriter pw = servletResponse.getWriter(); Connection col =null; PreparedStatement ps = null; ResultSet rs = null; try { col = Utils.getConnection(); String sql ="select * from user where sal=?"; ps = col.prepareStatement(sql); ps.setInt(1, 2000); rs = ps.executeQuery(); while(rs.next()){ String name = rs.getString("username"); String sal = rs.getString("sal"); pw.println("name:" + name + "sal is " + sal); } } catch (Exception e) { e.printStackTrace(); }finally { Utils.close(col,ps,rs); } } @Override public String getServletInfo() { System.out.println("serve的getServletInfo方法被执行了"); return null; } @Override public void destroy() { System.out.println("serve的destroy方法被执行了"); } }【注意】此时会报错,因为没有引入javaee包,故点击项目结构,在模块中添加jar包,将tomcat安装目录的lib包下的servlrt-api.jar和jsp.api选进来。
第五步:引入mysql包,由于需要操控jdbc,故可以引入mysql驱动,如上一步。
【注意】当然为了统一,也可以在WEB-INF新建lib包,拖入驱动到这里,右键添加为库。
第六步:为web.xml注册,类名必须包括包名,同时路径不能包括根目录,即servlet01.
第七步:将Tomcat服务器与该站点关联
步骤:点击配置,加入tomcat-local,选择部署中加入该站点,同时修改部署页下的application context为/servlet01,这就是URL中本站点的根目录。
第八步:debug模式启动,打开浏览器输入URL即可见。
6.Servlet接口详细剖析
- 是什么?
servlet接口/规范是orcale公司的javaee规范的一员,用于webserver和webapp之间的一套规定,实现解耦合、高拓展的效果。
- 有什么用?
有上述分析可知,servlet设计web服务器和后端工程师,一方面他规定了web服务器如何将小程序与路径映射,如web.xml文件,另一方面,规定了webapp的目录结构、配置文件、类放置目录等。
- 怎么实现的?
首先明确,它是Tomcat服务器实现的,可以从tomcat的servlet-api.jar源可知,Tomcat服务器通过配置文件找到类名,然后通过反射机制new对象,调用service服务进行程序的执行,下图为尝试实现的Tomcat服务器。
- 生命周期
用户第一次请求会创建一个servlet对象,执行其中的init方法和service方法,然后后续每一次访问都会执行该对象的service方法,在关闭服务器时,destroy方法执行,进行最终的关闭。
- 如何让服务器时创建servlet?
在web.xml的每个servlet中加入
DD source.servlet.serve1 3 DD /student_server1
- 结论?
结论1: 后端工程师只需要写好servlet实现类,配置web.xml文件即可。
【注意】因为Tomcat已经把配置文件的格式和位置规定好,我们只需按规定写即可。
结论2:servlet是单实例的,但是由于其构造方法不是私有的,不是有程序员管理,故不是单例模式;同时init方法用于初始化操作,service方法用的最多。
- 存在问题?
编写servlet类是需要实现5个方法的,很麻烦怎么办?
可以将其他方法都抽象为父类中实现,然后子类重写实现service方法即可【适配器模式】。
package source.servlet;
import javax.servlet.*;
import java.io.IOException;
public abstract class GenericServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
public abstract void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException ;
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
由此,不难发现init方法有一个ServletConfig方法,故Tomcat必然是先创建servlet对象,然后创建ServletConfig对象,将其传给init实现初始化,过程大致如下:
public class Tomcat{
public static void main(String[] args){
//创建Servlet对象-反射机制
//创建config对象
servletConfig is org.apache.catalina.core.StandardWrapperFacade@7e7b743b
//调用init方法
public void init( servletConfig) throws ServletException { }
//调用service方法
}
}
对此,我们怎么复用局部变量ServetConfig?
因此可以在GenericServlet中引入类变量ServletConfig,然后将其赋值为父类的getServletConfig即可,同时,为了避免子类重写父类的init方法以免破坏属性,故在父类的init有参方法中调用父类的init无参方法,让子类重写这个无参方法,最终的GenericServlet如下:
package source.servlet;
import javax.servlet.*;
import java.io.IOException;
public abstract class GenericServlet implements Servlet {
private ServletConfig config = null;
public final void init(ServletConfig config) throws ServletException {
this.config = config;
System.out.println("我是父类的,我的servletConfig is" + config);
this.init();
}
public void init(){
System.out.println("我是父类的inite方法,我出现代表程序出错了");
}
@Override
public ServletConfig getServletConfig() {
return config;
}
public abstract void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException ;
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
7.ServletConfig接口详细剖析
- 是什么? 一个接口
- 实现方法? javax.servlet.ServletConfig
- 谁实现的? Tomcat服务器 config is org.apache.catalina.core.StandardWrapperFacade@36c3c0b6
- 与servlet对象的关系? 一个servlet对象有一个servletconfig
- 谁创建的? web服务器创建的,在servlet创建的同时创建servletconfig对象
- 有什么用? servlet对象的配置信息
- 包装了哪些信息? 包装了web.xml中的servet之间的信息
- 怎么包装的? Tomcat服务器解析web.xml,包装到servletconfig对象中
- 有哪些方法? getInitParameter()
- 举例?
package source.servlet; import javax.servlet.*; import javax.servlet.GenericServlet; import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration; public class configtest_2 extends GenericServlet { @Override public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter pw = response.getWriter(); ServletConfig config = this.getServletConfig(); pw.println("config_test_2的 is "+config+""); pw.print(""); //获取servlet的getname方法; pw.println("config_test_2的name is "+config.getServletName()+""); // pw.println("config_test_2的name is "++""); Enumeration "); //this也可以,因为父类Generic已经实现了servletconfig发发发; pw.print(this.getInitParameter("Driver")); } }ee= config.getInitParameterNames(); while(ee.hasMoreElements()){ String x = ee.nextElement(); pw.print(x+"的值是"+config.getInitParameter(x)); pw.print(""); } // pw.print("
"+config.getInitParameter("Driver")); pw.print("
8.ServletContext接口详细剖析
- 是什么? 一个接口
- 实现方法? javax.servlet.ServletConfig
- 谁实现的? Tomcat服务器 org.apache.catalina.core.ApplicationContextFacade
- 与servlet对象的关系?
一个webapp有一个ServletContext表,属于应用级对象,即整个web.xml文件,是所有servlet的共享对象,而Tomcat是一个容器,可以放多个webapp。
- 谁创建的? web服务器创建的,在servlet创建的同时创建servletcontext对象
- 包含哪些信息? 一个webapp中所有的servlet对象的配置信息
- 有哪些方法?
getparameternames方法→共享信息参数
getInitParameter()→共享信息参数
getcontextpath()→动态获取应用的根路径
getrealpath()→获取文件的真实路径
log(String s)→ 将字符串s写入到日志文件中
如:
ServletContext con = this.getServletContext(); con.log("今天是11-25,我很开心");【注意1】Tomcat和磁盘的站点并飞一一对应,一个IDEA可以创建多个Tomcat,多个站点。
【注意2】日志文件分类:
catalina.2021-11-25.log 输出到idea控制台信息
localhost.2021-11-25.log 来自Context对象的log方法
localhost_access_log.2021-11-25.txt 来自浏览器的访问日志
- 举例:
name 我的家乡在中国 age 65 - ServletContext与ServletConfig的区别?
前者是每个webapp的全局配置,后者是每个servlet对象的局部配置,故不依赖于对象选前面。
- 有什么操作?→增删改
增:setAttribute(String name,Object value)→map.put
取:getAttribute(String name,Object value)→map.get
删:deleteAttribute(String name,Object value)→map.del
user user1 = new user(30,1000);
//存
con.setAttribute("张三", user1);
Object obj = con.getAttribute("张三");
pw.println(" "+obj);
package source.servlet;
public class user {
private int age;
private double sal;
@Override
public String toString() {
return "user{" +
"age=" + age +
", sal=" + sal +
'}';
}
public user(int age, double sal) {
this.age = age;
this.sal = sal;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getSal() {
return sal;
}
public void setSal(double sal) {
this.sal = sal;
}
}
- 有什么用?
如果所有用户共享一个数据量小、不经常修改的数据,那么可以放入context中。
为何共享 →共享的放入才有意义,冗余和安全
为何数据量小 →数据量大占用内存,其周期长
为何数据修改不要太多 →多用户修改设计线程安全问题
如此非常快,相当于缓存,下次再使用不用从数据库获取
9.HttpServlet接口详细剖析
- 是什么? 一个接口,专门用来处理http协议的,比genericservlet、servlet更常用
- 位置? javax.servlet.http.httpservlet
- HTTP包有哪些接口?
* http.httpservlet * http.httpservletrequest * 简称request对象 * 封装了请求协议的全部内容 * Tomcat服务器将“请求协议”中的数据全部解析处理,然后封装到request对象中 * 只要面向request就可以获取协议中的数据; * http.httpservletresponse
-
HttpServlet的代码结构?
public class haloservlet extends HttpServlet { //1.第一步创建对象,调用午餐方法 public haloservlet() { } //2.执行父类的init方法 public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {//调用genericServlet的init有参方法,调用该类的无参方法; public void init(ServletConfig config) throws ServletException { this.config = config; this.init(); } public void init() throws ServletException { } } //3.调用老祖宗的原书的service方法 public abstract class HttpServlet extends javax.servlet.GenericServlet { public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { HttpServletRequest request; HttpServletResponse response; try { request = (HttpServletRequest)req;//向下转型; response = (HttpServletResponse)res; } catch (ClassCastException var6) { throw new ServletException(lStrings.getString("http.non_http")); } this.service(request, response);//重载service } 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; try { ifModifiedSince = req.getDateHeader("If-Modified-Since"); } catch (IllegalArgumentException var9) { ifModifiedSince = -1L; } if (ifModifiedSince < lastModified / 1000L * 1000L) { 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); } } } -
结论?
可以重写父类的service方法,但是享受不到404 not found这样的独特的方法,因此建议根据需求重写doGet或者doPost方法,没必要都写,应当根据业务逻辑选择,例如后端重写了doPost方法,那么前端一定是发过来的post方法。
- 405原因解释?
上面的haloservet继承了httpservlet,但是没有重写doGet方法,此时浏览器发送了get请求,故会调用父类的doGet方法,而此时调用父类的doGet方法必然会导致405出错,因为父类的本意就是想让你重写需要的方法。
- 最终的servlet类?
第一步:编写类继承HttpServlet类,按需求实现doGet或doPost方法
第二步:注册到web.xml中【路径不要有站点名】
第三步:准备前端的html、form表单
package helloservlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; public class loginservlet extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter pw = response.getWriter(); pw.print("登陆成功"); } }# HTML
servlettest测试 get get请求
post# web.xml
helloservlet helloservlet.haloservlet helloservlet /hello finalservlet helloservlet.loginservlet finalservlet /finalservlet
10.ServletRequest接口详细剖析
- 是什么? 一个接口,由Tomcat实现了
- 谁实现的? org.apache.catalina.connector.RequestFacade
- 子接口? HttpServletRequest
- HttpServletRequest有哪些信息?
封装了HTTP请求信息,我们通过HttpServletRequest即可拿到用户的HTTP请求信息
- 生命周期? 只在当前请求有效,一个请求对应一个HttpServletRequest
- 如果是你,用户的表单信息如何保存到后端?
前端的数据格式:aihao=eat&aihao=shui
故可以考虑Map集合,存储key-value值对:
Map
"aihao" {"eat","shui"}
- 有哪些方法?
11.配置web欢迎页面
- 配置方式?
方法1:全局配置
//catalina_HOME_web.xml *index.html index.htm index.jsp 方法2:局部配置
//web-WEB.XMLxiaobai 法则:就近优先!
【注意】如果不配置,从全局配置可知,访问站点根目录默认访问的是该站点下的index.html页面。
- 静态欢迎页配置步骤
第一步:配置IDEA站点
第二步:书写index.html,放到web根目录下
第三步:在web.xml中引入index.html,格式见上面的局部配置
【注意】这里面的路径是相对于web文件夹而言,不要加上了web站点的路径。
【注意2】可以设置多个欢迎页,从上到家优先。
【注意3】欢迎页也可以是一个servlet对象,如下。
- 动态欢迎页配置步骤
第一步:写servlet
public class servletonIndex extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter pw = response.getWriter(); pw.println("你好啊,我是servlet"); } }第二步:在web.xml配置
zhagnsan wel.servletonIndex zhagnsan /xiaobai 第三步:web.xml配置欢迎页:
xiaobai 第四步:访问:http://localhost:8080/servlet01/
12.杂谈
第一个:缓存机制
为了提高效率,计算机的世界中引入了缓存机制,例如:
- redis,mongdb
- java中的字符串常量池和int型-128~127的常量池
- 操作系统中的TLB
- 连接池
- 将连接对象放在一个集合,例如jdbc中有mysql和jvm
- 线程池
- Tomcat支持多线程,在启动时就创建若干线程对象,用户发送请求时,就用一个线程来进行处理,提高效率。
- ServletContext应用域
第二个:设计模式
设计模式就是解决某个问题的固定解决方案,分为javaee设计模式,GoF设计模式等等,例如最常用的就是模板方法设计模式,我们通常把普适性的方法写到抽象父类,将一些特殊方法定义,然后让子类重写,例如我们的HttpServlet接口。
第三个:开发经验
- 开发中往往是已经有人写好了多线程,我们的关键是在多线程的环境下代码是否安全。
-
java程序员面向接口编程,关注本文的几个接口即可
-
多看源代码,学习、思考、创新、超越
-
知识要整理,有逻辑的提前背诵,模拟面试。



