Java-Servlet技术入门笔记

本文详细介绍了Servlet的注解配置、生命周期、GET和POST请求分发处理,以及HttpServletRequest和ServletContext的重要作用,包括获取配置信息、请求参数和请求转发等内容。
摘要由CSDN通过智能技术生成
<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns=“http://xmlns.jcp.org/xml/ns/javaee”

xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation=“http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd”

version=“4.0”>

HelloServlet

com.first.cyh.HelloServlet

HelloServlet

/hello

3、通过注解配置访问路径url-pattern

Servlet3.0支持注解配置——@WebServlet()

不用再编写xml文件,只需要在实现了Servlet的类加上该注解即可

  1. 一个servlet可以配置多个访问路径@WebServlet({“/hello”,“/hi”,“nihao”})

  2. 路径定义规则(xxx可以为*,即通配符)

  3. /xxx

  4. /xxx/xxx:多层路径,目录结构

  5. *.do

通配符优先级低,会在匹配不到时才访问

4、url地址到Servlet程序的访问

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7L80toVE-1636276443278)(C:\Users\Ken-Chy\Desktop\大二临时\00自学部分\后端\笔记\url地址如何访问到Servlet程序.png)]

5、Servlet的生命周期

  1. 执行Servlet构造器方法

  2. 执行init初始化方法

  • 第一、二步是在第一次访问的时候创建Servlet程序时才调用
  1. 执行service方法
  • 每次访问都会调用
  1. 执行destroy销毁方法
  • 在web工程停止的时候调用

6、GET和POST请求的分发处理

package com.first.cyh;

import jakarta.servlet.*;

import jakarta.servlet.http.HttpServlet;

import jakarta.servlet.http.HttpServletRequest;

import java.io.IOException;

public class HelloServlet implements Servlet {

public HelloServlet() {

System.out.println(“你好鸭”);

}

@Override

public void init(ServletConfig servletConfig) throws ServletException {

System.out.println(“初始化成功咯!”);

}

@Override

public ServletConfig getServletConfig() {

return null;

}

@Override

public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {

//ServletRequest和HttpServletRequest是两个接口,HttpServletRequest继承自ServletRequest

//此处的形式参数其实是HttpServletRequest接口的实现类,因为接口不能实例化,所以传进来的是实现类

//因为需要实现ServletRequest到HttpServletRequest的强制类型转换(父类到子类)

//只有父类对象是用子类构造方法生成的才能实现强制转换,所以传进来的参数应该是HttpServletRequest接口的实现类

//强制类型转换,因为HTTPServletRequest接口才有getMethod方法来判断请求的类型

HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;

String method = httpServletRequest.getMethod();

if(method.equals(“GET”)){

doGet();

}

else if(“POST”.equals(method)){

doPost();

}

}

private void doGet() {

System.out.println(“我是GET请求”);

}

private void doPost() {

System.out.println(“我是POST请求”);

}

@Override

public String getServletInfo() {

return null;

}

@Override

public void destroy() {

System.out.println(“拜拜QAQ”);

}

}

7、通过继承HttpServlet实现Servlet程序

一般在实际项目开发中,都是使用继承HttpServlet类的方式去实现Servlet程序

  1. 编写一个类去继承HttpServlet类(Servlet是接口,HttpServlet是类)

  2. 根据业务需要重写doGet()或doPost()方法

  3. 到web.xml中配置Servlet程序的访问地址

package com.first.cyh;

import jakarta.servlet.ServletException;

import jakarta.servlet.http.HttpServlet;

import jakarta.servlet.http.HttpServletRequest;

import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

public class HelloServlet2 extends HttpServlet {

@Override

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

System.out.println(“hello doPost”);

}

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

System.out.println(“hello doGet”);

}

}

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns=“http://xmlns.jcp.org/xml/ns/javaee”

xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation=“http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd”

version=“4.0”>

HelloServlet

com.first.cyh.HelloServlet

HelloServlet

/hello

HelloServlet2

com.first.cyh.HelloServlet2

HelloServlet2

/hello2

8、使用IDEA创建Servlet程序

  1. 项目结构->Facets->点开Web工程->在底部“根源”处把选项勾上

  2. 在需要创建Servlet程序的软件包处右键新建->Servlet->为程序命名->去掉创建注解类选项的勾

  3. 配置文件自动生成改Servlet程序的配置->手动配置该Servlet程序访问路径

  4. 重写Servlet程序的doGet()和doPost()方法

9、Servlet的继承体系

Servlet接口

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-glUAuPVZ-1636276443280)(C:\Users\Ken-Chy\Desktop\大二临时\00自学部分\后端\笔记\Servlet接口.png)]

Servlet继承体系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BMmnO2xE-1636276443282)(C:\Users\Ken-Chy\Desktop\大二临时\00自学部分\后端\笔记\Servlet继承关系.png)]

二、ServletConfig类


ServletConfig类是Servlet程序的配置信息类

二者都是由Tomcat负责创建,我们负责使用

Servlet程序默认是第一次访问时创建对象,而ServletConfig是每个Servlet程序创建时就创建一个对应的ServletConfig对象

1、ServletConfig类的三大作用

  1. 可以获取Servlet程序的别名servlet-name的值

  2. 获取初始化参数init-param

  3. 获取ServletContext对象

HelloServlet

com.first.cyh.HelloServlet

username

root

url

jdbc:mysql//localhost/test

public class HelloServlet implements Servlet {

@Override

public void init(ServletConfig servletConfig) throws ServletException {

System.out.println(“初始化成功咯!”);

//获取配置文件中servlet-name的值

System.out.println(“servlet程序的别名是” + servletConfig.getServletName());

//获取配置文件中的初始化参数init-param

System.out.println(“初始化参数username的值是” + servletConfig.getInitParameter(“username”));

System.out.println(“初始化参数url的值是” + servletConfig.getInitParameter(“url”));

//获取ServletContext对象

System.out.println(servletConfig.getServletContext());

}

//其他方法省略

}

//输出结果

/*

初始化成功咯!

servlet程序的别名是HelloServlet

初始化参数username的值是root

初始化参数url的值是jdbc:mysql//localhost/test

org.apache.catalina.core.ApplicationContextFacade@5cd687b4

*/

2、注意事项

如果Servlet程序继承HttpServlet类时重写了init(ServletConfig config) throws ServletException方法,需要加上super.init(config)

//这是GenericServlet类(HttpServlet类的父类)中的方法

public void init(ServletConfig config) throws ServletException {

this.config = config;

this.init();

}

public void init() throws ServletException {

}

public ServletConfig getServletConfig() {

return this.config;

}

public class HelloServlet2 extends HttpServlet {

@Override

//Tomcat生成ServletConfig对象并调用init程序

public void init(ServletConfig config) throws ServletException {

//super.init(config);

//如果没有调用父类的init(config)方法,则Tomcat创建的ServletConfig值丢失

//即config属性(定义在GenericServlet类中)没有保存值

System.out.println(“doSth”);

}

@Override

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

System.out.println(“hello doPost”);

}

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

System.out.println(“hello doGet”);

//由于GenericServlet类中的config没有保存值,所以getServletConfig()方法出现空指针异常

ServletConfig servletConfig = getServletConfig();

System.out.println(“Servlet程序的别名为” + servletConfig.getServletName());

}

}

三、ServletContext类


1、什么是ServletContext

代表整个web工程,可以与程序的容器(Tomcat服务器)通信

  1. ServletContext是一个接口,它表示Servlet上下文对象

  2. 一个web工程,只有一个ServletContext对象实例

  • ServletConfig对象取决于有多少个Servlet程序(一一对应,只能访问到配置文件中属于自己的配置信息)

  • 但ServletContext对象还能访问配置文件中上下文参数

  1. ServletContext对象是一个域对象

  2. ServletContext对象是在web工程部署启动的时候创建,在web工程停止的时候销毁

什么是域对象

域对象指的是可以像Map一样存取数据的对象

这里的域指的是存取数据的操作范围——整个web工程

| | 存数据 | 取数据 | 删除数据 |

| :-: | :-: | :-: | :-: |

| Map | put() | get() | remove() |

| 域对象 | setAttribute() | getAttribute() | removeAttribute() |

2、获取ServletContext对象的方法

  1. 通过HttpServletRequest对象获取
  • request.getServletContext();
  1. 通过HttpServlet获取
  • this.getServletContext();
  1. 通过servletConfig对象获取
  • servletConfig.getServletContext();

@WebServlet(“/getcontext”)

public class GetContextServlet extends HttpServlet {

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

//通过HttpServlet获取

ServletContext servletContext1 = this.getServletContext();

//通过HttpServletRequest req对象获取

ServletContext servletContext2 = req.getServletContext();

//通过servletConfig对象获取

ServletContext servletContext3 = this.getServletConfig().getServletContext();

System.out.println(servletContext1);

System.out.println(servletContext2);

System.out.println(servletContext3);

}

}

3、ServletContext类的四大作用

  1. 获取web.xml中配置的上下文参数context-param

  2. 获取当前工程路径,格式:/工程路径

  3. 获取工程部署在服务器硬盘上的绝对路径

  4. 像Map一样存取数据

1)获取信息
<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns=“http://xmlns.jcp.org/xml/ns/javaee”

xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation=“http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd”

version=“4.0”>

username

context

password

root

HelloServlet

com.first.cyh.HelloServlet

username

root

url

jdbc:mysql//localhost/test

HelloServlet

/hello

public class ContextServlet extends HttpServlet {

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

//获取配置文件中的上下文参数

ServletContext context = getServletConfig().getServletContext();

System.out.println(context.getInitParameter(“username”));

System.out.println(context.getInitParameter(“password”));

//获取当前的工程路径,格式:/工程路径

System.out.println(context.getContextPath());

//获取工程部署后在服务器硬盘的绝对路径

/*

getRealPath()返回一个给定虚拟路径的真实路径

这个斜杆表示站点的根,也就是获取网站的根目录,即工程部署路径

而/css就是表示该路径下的css文件夹

*/

System.out.println(context.getRealPath(“/”));

System.out.println(context.getRealPath(“/css”));

System.out.println(context.getRealPath(“/jpg”));

}

}

上述程序执行后会返回

context

root

/myfirst

E:\eclipse-workspace\Javaweb-servlet\out\artifacts\Javaweb_servlet_war_exploded

E:\eclipse-workspace\Javaweb-servlet\out\artifacts\Javaweb_servlet_war_exploded\css

E:\eclipse-workspace\Javaweb-servlet\out\artifacts\Javaweb_servlet_war_exploded\jpg

而为什么获得的路径为什么和我们项目创建的路径不一样,在我的另一篇博文(web工程部署路径与getServletConfig().getRealPath()_得过且过的勇者y的博客-CSDN博客中详细讲解了

为什么需要获取工程存放路径呢?

因为项目在本地开发后,项目中的文件路径写的是本地的路径。然而当项目部署到其他设备后,物理地址发生改变,就会导致文件找不到而报错。

2)存取数据

public class ContextServlet1 extends HttpServlet {

@Override

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

//GenericServlet获取获取ServletContext对象的方式,等同于getServletConfig().getServletContext()

ServletContext servletContext = getServletContext();

System.out.println(“保存之前Context1中获取域数据key1的值是:” + servletContext.getAttribute(“key1”));

//存数据

servletContext.setAttribute(“key1”,“value1”);

//取数据

System.out.println(“Context1中获取域数据key1的值是:” + servletContext.getAttribute(“key1”));

}

}

public class ContextServlet2 extends HttpServlet {

@Override

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

ServletContext servletContext = getServletContext();

System.out.println(“Context2中获取域数据key1的值是:” + servletContext.getAttribute(“key1”));

}

}

以下为两次访问ContextServlet1输出的结果(没有重新部署)

保存之前Context1中获取域数据key1的值是:null

Context1中获取域数据key1的值是:value1

保存之前Context1中获取域数据key1的值是:value1

Context1中获取域数据key1的值是:value1

重新部署后再次访问ContextServlet1输出的结果

保存之前Context1中获取域数据key1的值是:null

Context1中获取域数据key1的值是:value1

这是因为ServletContext对象是在web工程部署启动的时候创建,在web工程停止的时候销毁,所以没有重新部署的话key1在set之后就一直存在,所以第二次及以后访问时都会有保存之前Context1中获取域数据key1的值是:value1,而重新部署之后第一次访问就又是null

而前文中的getInitParameter()获取的数据是保存在xml文件中的,故一直存在

总结

setAttribute方式存参数相当于把数据存在内存中,工程停止时消失,而xml方式存参数则是持久化到硬盘中

getInitParameter获得的是xml方式存储的参数

getAttribute获得的是setAttribute方式存储的参数

而当我们已经访问完ContextServlet1后再访问ContextServlet2,会输出

Context2中获取域数据key1的值是:value1

这是因为一个web工程,只有一个ServletContext对象实例,两个Servlet程序中的servletContext其实是相同的,如果我们在两个程序中都输出servletContext这个对象,值是相同的

所以当第一个Servlet程序设置完key1参数后,第二个自然也可以使用它

3)获取MIME类型

MIME类型是在互联网通信过程中定义的一种文件数据类型,格式为:大类型/小类型,如text/html,image/jpg

用处:响应头中content-type需要返回响应体的数据类型,这时候就要获取我们返回的数据的MIME类型

获取方法:通过文件后缀名在tomcat配置文件(tomcat的conf目录下的web.xml)中寻找对应的MIME类型(因为context对象可以与tomcat进行通信)

@WebServlet(“/getmime”)

public class GetMime extends HttpServlet {

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

ServletContext servletContext = this.getServletContext();

//定义文件名

String filename = “a.jpg”;

//通过文件名的后缀获取对应MIME类型

String mimeType = servletContext.getMimeType(filename);

System.out.println(mimeType);

}

}

返回image/jpeg

四、HttpServletRequest类


1、作用

每次只要有请求进入Tomcat服务器,Tomcat服务器就会把请求过来的Http协议信息解析封装好到Request对象中,然后传递到service方法(doGet和doPost)中给我们使用。我们可以通过HttpServletRequest对象,获得到所有请求的信息

2、常用方法

  • getRequestURI():获取请求的资源路径

  • getRequestURL():获取请求的统一资源定位符(绝对路径)

  • getRemoteHost():获取客户端的IP地址

  • getHeader():获取请求头

  • getParameter():获取请求的参数

  • getParameterValues():获取请求的参数(多个值得时候使用)

  • getMethod():获取请求的方式(GET或POST)

  • setAttribute(key, value):设置域数据

  • getAttribute(key):获取域数据

  • getRequestDispatcher():获取请求转发对象

public class RequestAPIServlet extends HttpServlet {

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

System.out.println(“URI–>” + req.getRequestURI());//URI–>/myfirst/req

System.out.println(“URL–>” + req.getRequestURL());//URL–>http://localhost:8080/myfirst/req

//如果以localhost访问,则返回0:0:0:0:0:0:0:10:0:0:0:0:0:0:1

//以127.0.0.1访问,则返回127.0.0.1

//以真实ip访问,则返回真实ip

System.out.println(“HOST–>” + req.getRemoteHost());

//HEADER–>Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.30

System.out.println(“METHOD–>” + req.getMethod());//GET

System.out.println(“HEADER–>” + req.getHeader(“User-Agent”));

}

}

public class RequestGetParameter extends HttpServlet {

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

System.out.println(“用户名” + req.getParameter(“username”));

System.out.println(“密码” + req.getParameter(“password”));

String[] hobbies = req.getParameterValues(“hobby”);

try{

System.out.println(“兴趣爱好” + Arrays.asList(hobbies));

}catch (Exception e){

System.out.println(e.getStackTrace());

}

}

}

注意点

如果使用的是post请求,则需要设置字符集,否则在post请求参数是中文会出现乱码

req.setCharacterEncoding(“UTF-8”);

且此设置要在所有获取参数语句(不管会不会获取中文)的前面设置

只要有获取参数的语句在设置语句前面,不管这条语句会不会获取中文,都会导致设置失效,从而使那些在设置语句后的获取参数语句同样会乱码

3、请求转发

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e8l4Ttgx-1636276443283)(C:\Users\Ken-Chy\Desktop\大二临时\00自学部分\后端\笔记\请求转发.png)]

最后

码字不易,觉得有帮助的可以帮忙点个赞,让更多有需要的人看到

又是一年求职季,在这里,我为各位准备了一套Java程序员精选高频面试笔试真题,来帮助大家攻下BAT的offer,题目范围从初级的Java基础到高级的分布式架构等等一系列的面试题和答案,用于给大家作为参考

以下是部分内容截图
架构面试专题及架构学习笔记导图.png

rintln(“METHOD–>” + req.getMethod());//GET

System.out.println(“HEADER–>” + req.getHeader(“User-Agent”));

}

}

public class RequestGetParameter extends HttpServlet {

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

System.out.println(“用户名” + req.getParameter(“username”));

System.out.println(“密码” + req.getParameter(“password”));

String[] hobbies = req.getParameterValues(“hobby”);

try{

System.out.println(“兴趣爱好” + Arrays.asList(hobbies));

}catch (Exception e){

System.out.println(e.getStackTrace());

}

}

}

注意点

如果使用的是post请求,则需要设置字符集,否则在post请求参数是中文会出现乱码

req.setCharacterEncoding(“UTF-8”);

且此设置要在所有获取参数语句(不管会不会获取中文)的前面设置

只要有获取参数的语句在设置语句前面,不管这条语句会不会获取中文,都会导致设置失效,从而使那些在设置语句后的获取参数语句同样会乱码

3、请求转发

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e8l4Ttgx-1636276443283)(C:\Users\Ken-Chy\Desktop\大二临时\00自学部分\后端\笔记\请求转发.png)]

最后

码字不易,觉得有帮助的可以帮忙点个赞,让更多有需要的人看到

又是一年求职季,在这里,我为各位准备了一套Java程序员精选高频面试笔试真题,来帮助大家攻下BAT的offer,题目范围从初级的Java基础到高级的分布式架构等等一系列的面试题和答案,用于给大家作为参考

以下是部分内容截图
[外链图片转存中…(img-8ej15dPq-1714320848584)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 21
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值