标签:B/S结构、javaweb、Tomcat、servlet规范、网络通信
众所周知,互联网通信分为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规范。
- 浏览器→负责封装、解封HTTP请求报文【request请求,response请求】
- web服务器→根据URL寻找资源【Tomcat服务器、jetty服务器】
- 后端人员→负责编写java小程序和配置路径与程序类名的映射关系【YOU!】
- mysql数据库→存储资源,如员工工资表等【mysql,jdbc】
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 //请求体
POST /wodewangzhan/postservlet HTTP/1.1 //请求头 Host: localhost:8080 Connection: keep-alive Content-Length: 34 Cache-Control: max-age=0 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 Origin: http://localhost:8080 Content-Type: application/x-www-form-urlencoded 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/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 server
h1>
区别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.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访问。
只需采用六步法实现servlet接口与jdbc接口,编译到classes文件夹,注册到web.xml,引入mysql驱动到lib包即可用URL访问:
// javac -encoding utf8 -d D:\minisoftware\apache-tomcat-9.0.55\webapps\crm\WEB-INF\classes serverLet\StuInfo_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; /** * @author zhangsan * @create 2021-11-25 16:12 */ 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() { } }
第一步:新建空工程,新建一个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即可见。
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方法执行,进行最终的关闭。
在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;
/**
* @author zhangsan
* @create 2021-11-25 20:08
*/
public abstract class GenericServlet implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
/**
* 该抽象类用于实现接口,屏蔽一些不重要的操作;
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
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;
}
/**
* 该抽象类用于实现接口,屏蔽一些不重要的操作;
* @param servletRequest
* @param servletResponse
* @throws ServletException
* @throws IOException
*/
public abstract void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException ;
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
package source.servlet;
import javax.servlet.*;
import javax.servlet.GenericServlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
/**
*
* configtest_2_config2
*
* source.servlet.configtest_2
*
* Driver
* "com.mysql.cj.jdbc"
*
*
* username
* "小猫腻"
*
*初始化参数信息,封装到servletConfig对象中;
*
*/
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 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(" ");
//this也可以,因为父类Generic已经实现了servletconfig发发发;
pw.print(this.getInitParameter("Driver"));
}
}
一个webapp有一个ServletContext表,属于应用级对象,即整个web.xml文件,是所有servlet的共享对象,而Tomcat是一个容器,可以放多个webapp。
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 con = this.getServletContext();
Enumeration CC = con.getInitParameterNames();
while(CC.hasMoreElements()){
String s = CC.nextElement();
pw.print(s+"→"+con.getInitParameter(s));
pw.print("
");
}*/
前者是每个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;
/**
* @author zhangsan
* @create 2021-11-25 23:27
*/
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中。
为何共享 →共享的放入才有意义,冗余和安全
为何数据量小 →数据量大占用内存,其周期长
为何数据修改不要太多 →多用户修改设计线程安全问题
如此非常快,相当于缓存,下次再使用不用从数据库获取
* 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方法。
上面的haloservet继承了httpservlet,但是没有重写doGet方法,此时浏览器发送了get请求,故会调用父类的doGet方法,而此时调用父类的doGet方法必然会导致405出错,因为父类的本意就是想让你重写需要的方法。
第一步:编写类继承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; /** * @author zhangsan * @create 2021-11-26 12:37 */ 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
测试 get
get请求
post
servlettest
# web.xml
helloservlet helloservlet.haloservlet helloservlet /hello finalservlet helloservlet.loginservlet finalservlet /finalservlet
封装了HTTP请求信息,我们通过HttpServletRequest即可拿到用户的HTTP请求信息
前端的数据格式:aihao=eat&aihao=shui
故可以考虑Map集合,存储key-value值对:
Map
"aihao" {"eat","shui"}
方法1:全局配置
//catalina_HOME_web.xml *
index.html index.htm index.jsp 方法2:局部配置
//web-WEB.XML
xiaobai 法则:就近优先!
【注意】如果不配置,从全局配置可知,访问站点根目录默认访问的是该站点下的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/
第一个:缓存机制
为了提高效率,计算机的世界中引入了缓存机制,例如:
第二个:设计模式
设计模式就是解决某个问题的固定解决方案,分为javaee设计模式,GoF设计模式等等,例如最常用的就是模板方法设计模式,我们通常把普适性的方法写到抽象父类,将一些特殊方法定义,然后让子类重写,例如我们的HttpServlet接口。
第三个:开发经验
java程序员面向接口编程,关注本文的几个接口即可
多看源代码,学习、思考、创新、超越
知识要整理,有逻辑的提前背诵,模拟面试。