Servlet入门

环境

在IDEA中创建JavaEE项目

项目运行后,会显示webapp中的index.htmlindex.jsp中的内容,

调试

  • 用Lombok里的@Log,或者System.out.println()

0、JavaEE项目运行

两种方法:

  1. 直接运行项目
  2. 将项目打包,生成一个war包,之后在Tomcat中运行

下面是第二种方法:

运行startup.bat,启动Tomcat


Tomcat中有默认的servlet-mapping,所以我们才能看到Tomcat 的页面

1、创建Servlet

Servlet是一个标准,web服务器Tomcat支持此标准。官方定义接口,程序员实现,之后Web服务器(Tomcat)运行这些实现。

用注解注册一个Servlet

java 复制代码
@WebServlet("/test")
public class TestServlet implements Servlet {

    public TestServlet(){
        System.out.println("我是构造方法!");
    }


    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init");
    }

    @Override
    public ServletConfig getServletConfig() {
        System.out.println("我是getServletConfig");
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("我是service");
    }

    @Override
    public String getServletInfo() {
        System.out.println("我是getServletInfo");
        return null;
    }

    @Override
    public void destroy() {
        System.out.println("我是destroy");
    }
}

web.xml中注册Servlet【一般不用】

xml 复制代码
<!--    Servlet,对应的是哪个文件-->
<servlet>
    <servlet-name>test</servlet-name>
    <servlet-class>com.example.webtest.TestServlet</servlet-class>
</servlet>
<!--    映射(通过哪个路径访问)-->
<servlet-mapping>
    <servlet-name>test</servlet-name>
    <url-pattern>/test</url-pattern>
</servlet-mapping>

2、Servlet的生命周期

问题:Servlet启动/关闭时,哪些方法被执行了?

答:
请求url时,初始化Servlet(构造方法,init)
调用Service处理客户端请求
//中间的多次请求,只调用Service
销毁前调用destroy方法
最后用JVM的垃圾回收器,进行回收


3、Servlet的Service方法

java 复制代码
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
    System.out.println("我是service");
}

参数:

  • servletRequest:客户端发送的HTTP请求,被接收到这里(可从这获取所有请求信息)
  • servletResponse:返回给客户端的HTTP响应报文
c 复制代码
System.out.println("浏览器发起了一次请求");
System.out.println(servletRequest.getClass().getName());//记录请求对象的类名。
System.out.println(servletResponse.getClass().getName()); //记录响应对象的类名。

3.1 使用HttpServletRequest,处理HTTP请求

在后端查看请求信息

java 复制代码
/*写在service方法中*/
System.out.println("我是service");
// 将通用的ServletRequest对象转换为更具体的HttpServletRequest对象,以便可以访问HttpServletRequest特有的方法和属性。
HttpServletRequest request = (HttpServletRequest) servletRequest;
System.out.println("请求使用的协议: " + request.getProtocol());// 打印请求使用的协议
System.out.println("客户端的IP地址: " + request.getRemoteAddr()); // 打印客户端的IP地址
System.out.println("请求的URI: " + request.getRequestURI());// 打印请求的URI
System.out.println("打印请求的方法(如GET、POST): " + request.getMethod());// 打印请求的方法(如GET、POST)
// 获取头部信息
// 获取请求头的所有名称
Enumeration<String> enumration = request.getHeaderNames();
// 遍历所有请求头名称,并打印其对应的值
while (enumration.hasMoreElements()) {
    String name = enumration.nextElement();// 获取请求头名称
    String value = request.getHeader(name);// 获取当前名称对应的值
    System.out.println(name + "--->" + value);// 打印请求头名称和值
}

运行结果

3.2 使用HttpServletResponse,编写响应内容

java 复制代码
/*写在service方法中*/
// 将Servlet响应转换为HTTP响应对象,以便更直接地操作响应头和内容。
HttpServletResponse response=(HttpServletResponse) servletResponse;
// 设置响应头的Content-Type,指定响应内容类型为HTML,编码为UTF-8。
response.setHeader("Content-Type","text/html;charset=UTF-8");
// 将指定的HTML内容写入响应体。
response.getWriter().write("<h1>我是响应内容!</h1>");

3.3 继承HttpServlet,简化开发

核心思想:重写HttpServlet中的方法,简化JavaWeb项目的开发

类的继承关系:类HttpServlet 继承 类GenericServlet 实现 接口Servlet

  • GenericServlet没有实现service

3.3.1 直接访问,会执行doGet(),显示方法不可用

3.3.2 重写doGet()方法后,会执行重写后doGet()方法

java 复制代码
@WebServlet("/test")
public class TestServlet extends HttpServlet {
	//重写doGet()方法
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        resp.getWriter().write("<h1>恭喜你解锁了全新玩法</h1>");
    }
}


3.4 @WebServlet注解,怎么写

注解的作用:把这个类注册为Servlet,之后该类会按Servlet的方式运行。

注解中的参数:这个Servlet运行时的一些配置

常用tips

  • *代表任意

3.4.1 指定访问的URL

此处URL是/test/任意字符,如/test,/test/123,/test/456asdf

java 复制代码
@WebServlet("/test/*")  //  URL: /test/任意字符
@WebServlet(value = "/test/*")  //  另一种写法,更全

3.4.2 指定文件后缀

java 复制代码
// 解释:获取以.html结尾的文件时,会调用这个Servlet
@WebServlet("*.html")
// 解释:获取以.js结尾的文件时,会调用这个Servlet
@WebServlet("*.js")

3.4.3 特殊URL

/代表若Tomcat没有找到对应的URL,则进入这个路由(一般是404)

  • 注:前缀URL必须正确,如
java 复制代码
@WebServlet("/")

3.4.4 配置多个URL

java 复制代码
@WebServlet({"/test1","/test2"})

3.4.5 Servelet在项目启动时是否加载(init方法)

  • loadOnStartup = 1加载
    • 数字代表启动顺序,顺序:1,2,3,....
  • loadOnStartup = -1不在启动时加载,在被访问时才会加载
java 复制代码
//写了多个参数,要用 name=value 格式
@WebServlet(value = {"/t21","/t22"},loadOnStartup = 2)

3.4.6 其他参数

怎么看?

查看@WebServlet的定义即可

4、用Post请求实现登录

实现一个登录页面+功能,代码见下方链接。

简易的Web登录功能(Servlet,mybatis,MySQL)

5、Servlet实现文件的上传/下载

JavaWeb文件上传/下载(Servlet)

6、前端XHR请求数据

  • 页面上的部分内容,动态显示
  • 如:时间旁有个按钮,点击按钮可刷新时间

前端XHR请求数据

7、重定向VS请求转发

7.1 重定向

  • 登陆后,跳转到主页
  • 关键:resp.sendRedirect("main");
  • 流程
    • 前端:输入账号密码,登录,访问/login
    • 后端:执行/login的doPost(),执行重定向
    • 前端:收到重定向响应(状态码302),访问主页/main
    • 后端:执行/main的doGet(),返回主页面的页面html

基础程序:简易的Web登录功能(Servlet,mybatis,MySQL)

修改1:登录成功

修改2:创建类MainServlet

手动设置重定向

java 复制代码
//自动重定向
resp.sendRedirect("main");//执行重定向
//手动重定向
resp.setStatus(302);
resp.setHeader("Location", "main");
//重定向到百度
resp.setStatus(302);
resp.setHeader("Location", "https://www.baidu.com");

7.2 请求转发:

  • 后端内部转发
  • req.getRequestDispatcher("/main").forward(req,resp);
  • 流程
    • 前端:输入账号密码,登录,访问/login
    • 后端:执行/login的doPost(),执行请求转发
    • 后端:执行/main的doPost(),返回主页面信息
    • 前端:接收到主页面信息,显示

基础程序:简易的Web登录功能(Servlet,mybatis,MySQL)

修改1:登录成功

修改2:创建类MainServlet

对比

重定向 请求转发
前端发起请求次数 2 1
前端地址栏变化 不变
能否共享请求参数 不能
只能转发给项目内的Servlet

8、ServletContext对象

ServletContext是个全局变量,属于整个Web App,可通过getServletContext()获取

功能1:传递数据(键值对)

存储数据:

java 复制代码
// 获取Servlet上下文对象,该对象在整个Web应用程序中都是唯一的
ServletContext context = getServletContext();
// 设置一个属性"test_data",并赋值为"我是数据test_data"
// 这个属性可以在Web应用的任何地方访问,只要拥有对ServletContext的引用
// 这种方式常用于在多个Servlet之间共享数据,或者存储配置信息
context.setAttribute("test_data", "我是数据test_data");

获取数据:

java 复制代码
// 获取Servlet上下文对象,该对象在整个Web应用程序中都是唯一的
ServletContext context = getServletContext();
// 从Servlet上下文中尝试获取之前设置的"test_data"属性的值
// 如果存在该属性,将打印其值;否则,将打印null
System.out.println(context.getAttribute("test_data"));

功能2:请求转发

java 复制代码
// 获取Servlet上下文对象,该对象在整个Web应用程序中都是唯一的
ServletContext context = getServletContext();
// 使用Servlet上下文的Dispatcher来转发请求到"/main"路径的资源
// 这将导致请求和响应对象被传递给"/main"路径所映射的Servlet或JSP页面
// 请求转发是一个服务器端操作,客户端浏览器不会看到实际的URL改变
// "/main"应该是Web应用内部的一个有效路径,例如一个Servlet或JSP页面
context.getRequestDispatcher("/main").forward(req, resp);

9、初始化参数

在Servlet中存储初始化参数,如

  • 数据库连接信息:账号,密码,url
  • 系统设置:如缓存策略、日志级别、邮件服务器设置
  • APIKey:如高德地图,百度AI等的APIKey

9.1 Servlet中的初始化参数

格式(键值对形式)

java 复制代码
@WebServlet(value = "/login", initParams = {
        @WebInitParam(name = "test", value = "我是初始化参数test")//初始化参数在这
})

通过getInitParameterNames()方法获取初始化参数的"名称"(name)

java 复制代码
// 获取初始化参数的名称枚举
Enumeration<String> paramNames = getInitParameterNames();
// 遍历并输出所有初始化参数的名称
while (paramNames.hasMoreElements()) {
//while (paramNames.hasMoreElements())检查枚举是否还有未处理的元素(即参数名)。
//如果有的话,paramNames.nextElement()会获取下一个参数名,并将其赋值给paramName。
    String paramName = paramNames.nextElement();
    System.out.println(paramName);
}

通过Servlet的getInitParameter()方法获取初始化参数

java 复制代码
//根据name获取value
System.out.println(getInitParameter("test"));

9.2 全局初始化参数

web.xml编写

xml 复制代码
<context-param>
    <param-name>test_quanjv</param-name>
    <param-value>我是全局初始化参数</param-value>
</context-param>

ServletContext来读取全局初始化参数:

java 复制代码
/**
 * 获取Web应用程序的ServletContext对象。
 * ServletContext对象代表了整个Web应用程序的上下文环境。
 * 之后,从ServletContext对象中获取名为"test_quanjv"的初始化参数的值。
 * 如果该参数存在,其值将被输出到控制台。
 */
ServletContext context = getServletContext();
// 输出名为"test_quanjv"的初始化参数的值
System.out.println(context.getInitParameter("test_quanjv"));

参考

https://www.itbaima.cn/document/ycpagby2v7j4p728

相关推荐
识途老码2 天前
Centos7安装Jenkins
运维·servlet·jenkins
奔跑吧邓邓子2 天前
Jenkins从入门到精通,构建高效自动化流程
servlet·自动化·jenkins
人生匆匆3 天前
bluefs _flush_range allocated: osd用空间但是显示ceph_bluefs_db_used_bytes is 100%
数据库·ceph·servlet
天下蒂一厨4 天前
jenkins微服务
linux·servlet·微服务·jenkins
cyt涛7 天前
WEB服务器——Tomcat
运维·服务器·http·servlet·tomcat·web·jsp
算法与编程之美7 天前
通过两个类计算一个长方形的周长和面积
java·开发语言·javascript·jvm·servlet
不修×蝙蝠7 天前
后端(实例)08
java·后端·servlet·eclipse
学习Java的aki7 天前
Servlet——springMvc底层原理
servlet
未 顾8 天前
JavaWeb--小白笔记07-2:超链接以及servlet对表单数据的完整处理
笔记·servlet
程序猿小D9 天前
第二百五十五节 JPA教程 - JPA 多对多连接表示例
java·开发语言·数据库·mysql·servlet·mybatis·jpa