当前位置:网站首页>Web服务连接器:Servlet
Web服务连接器:Servlet
2022-07-06 05:44:00 【啊Q老师】
servlet
概述
Servlet(Server Applet)是Java Servlet的简称,称为服务器小程序或服务连接器。它是在服务器端运行的Java小程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据(即实现前后端的交互),生成动态Web内容。
工作原理图
其中,Tomcat可以通过HTTP提供HTML页面等静态内容的请求访问;也实现了Servlet规范,可以运行Servlet程序;同时可以通过Servlet容器调用Servlet处理动态请求,所以Tomcat可以是Web服务器或Servlet容器或Web轻量级应用服务器。
工作流程
1)客户端(通常都是浏览器)访问Web服务器,发送HTTP请求。
2)Web服务器接收到请求后,将请求传递给Servlet容器。
3)Servlet容器解析请求,加载Servlet,同时Servlet容器分别创建一个HttpRequest对象和一个HttpResponse对象。HttpRequest对象将传递的请求信息封装起来。
4)Servlet容器调用HttpServlet对象的service()方法,把HttpRequest对象与HttpResponse对象作为参数传给HttpServlet对象。HttpServlet调用HttpRequest对象的有关方法,获取Http请求信息;调用HttpResponse对象的有关方法,生成响应数据。
5)Servlet容器把HttpServlet的响应结果返回给Web服务器。
Servlet的生命周期
Servlet的生命周期是Servlet从启动到关闭的过程,如下:
- 加载和实例化:如果Servlet容器还没实例化一个Servlet对象,此时容器装载和实例化一个 Servlet。如果已经存在一个Servlet对象,此时不再创建新实例。
- 初始化:在产生 Servlet 实例后,容器负责调用该 Servlet 实例的 init() 方法,对Servlet 进行初始化。
- 响应请求:当 Servlet 容器接收到一个 Servlet 请求时,便运行与之对应的 Servlet 实例的 service() 方法,service() 方法根据用户的请求调用相对应的doGet或doPost 方法来处理用户请求。然后再进入对应的方法中调用逻辑层的方法,实现对客户的响应。
- 销毁:当Servlet在Web应用被卸载前执行,释放Servlet占用的计算机资源。
注意:(1)(2)(4) 在Servlet的整个生命周期中只会被执行一次。
代码如下,ServletLifeCycle.java:
package com.edu.ServletStudy;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ServletLifeCycle implements Servlet {
public ServletLifeCycle() {
//构造方法被调用,创建一个实例对象
System.out.println("第一步:实例对象");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
//对servlet进行初始化,只执行一次
System.out.println("第二步:初始化");
}
@Override
public ServletConfig getServletConfig() {
//返回一个ServletConfig对象用来返回初始化参数和ServletContext
return null;
}
@Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
System.out.println("第三步:提供服务");
//中文乱码解决
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
//响应请求的信息
HttpServletResponse res = (HttpServletResponse)response ;
res.getWriter().write("Hello Servlet,我是啊Q老师");
}
@Override
public String getServletInfo() {
//提供有关servlet的信息
return null;
}
@Override
public void destroy() {
System.out.println("销毁");
}
}
web.xml:
<?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">
<!--配置servlet-->
<servlet>
<!--servlet内部名称-->
<servlet-name>ServletLifeCycle</servlet-name>
<!--servlet类的全名-->
<servlet-class>com.edu.ServletStudy.ServletLifeCycle</servlet-class>
</servlet>
<!--servlet映射配置-->
<servlet-mapping>
<!--servlet的内部名称,与上面的保持一致-->
<servlet-name>ServletLifeCycle</servlet-name>
<!--servlet的映射路径(地址一般是action里面的内容,获取数据请求)-->
<url-pattern>/ServletLifeCycle</url-pattern>
</servlet-mapping>
</web-app>
运行如图:控制台
页面
当点击停止时,Servlet便会执行destroy()方法
ServletConfig对象
ServletConfig对象的作用主要是配置servlet的初始化参数。具体的实现由Servlet容器开发商决定的。我们以Tomcat为例。
代码如下,web.xml:
<?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">
<servlet>
<servlet-name>ServletLifeCycle</servlet-name>
<servlet-class>com.edu.ServletStudy.ServletLifeCycle</servlet-class>
<!--可以用一个或多个<init-param>标签配置本Servlet的初始化参数-->
<init-param>
<!--键-->
<param-name>username</param-name>
<!--值-->
<param-value>啊Q老师</param-value>
</init-param>
<init-param>
<param-name>pwd</param-name>
<param-value>123</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ServletLifeCycle</servlet-name>
<url-pattern>/ServletLifeCycle</url-pattern>
</servlet-mapping>
</web-app>
ServletLifeCycle.java:
package com.edu.ServletStudy;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
public class ServletLifeCycle implements Servlet {
@Override
//当Servlet容器初始化Servlet时,Servlet容器会给Servlet的init( )方式传入一个 ServletConfig对象
public void init(ServletConfig servletConfig) throws ServletException {
//获取配置servlet所有初始化参数的键
Enumeration<String> enumeration = servletConfig.getInitParameterNames();
//遍历输出键与值
while (enumeration.hasMoreElements()){
String names = (String)enumeration.nextElement();
String values = servletConfig.getInitParameter(names); //获取servlet配置的初始化参数
System.out.println("ParamName = " + names + "ParamValue = " + values);
}
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
控制台如图:
ServletContext对象
ServletContext是在Web容器启动时,每个Web应用程序会创建一个对应的ServletContext对象(也称为Context对象)。一个Web应用中的所有Servlet共享同一个ServletContext对象,所以Servlet对象之间可以通过ServletContext对象来实现通讯。
ServletContext对象中,配置Servlet参数时使用 context-param标签可以实现共享获取;而上述的ServletConfig对象中,配置Servlet参数只能在 servlet 内的 init-param标签,只能是本Servlet获取参数。
代码如下,web.xml:
<?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">
<!--共享Servlet的初始化参数-->
<context-param>
<param-name>username</param-name>
<param-value>啊Q老师</param-value>
</context-param>
<context-param>
<param-name>pwd</param-name>
<param-value>123</param-value>
</context-param>
<servlet>
<servlet-name>ServletConextTest</servlet-name>
<servlet-class>com.edu.ServletStudy.ServletConextTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletConextTest</servlet-name>
<url-pattern>/ServletConextTest</url-pattern>
</servlet-mapping>
</web-app>
ServletConextTest.java:
package com.edu.ServletStudy;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
public class ServletConextTest implements Servlet {
public void init(ServletConfig servletConfig) throws ServletException {
//访问ServletContext
ServletContext context = servletConfig.getServletContext();
//获取配置servlet所有初始化参数的键
Enumeration<String> paramNames = context.getInitParameterNames();
//遍历输出键与值
while (paramNames.hasMoreElements()) {
String name = paramNames.nextElement();
String value = context.getInitParameter(name);
System.out.println(name + " = " + value);
}
}
public ServletConfig getServletConfig() {
return null;
}
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
public String getServletInfo() {
return null;
}
public void destroy() {
}
}
HttpServlet
HttpServlet的作用是获取HTTP请求,响应HTTP结果。在IDEA中选中HttpServlet,“ctrl + 鼠标左键单击” 会跳转到HttpServlet类中,这时会发现HttpServlet是抽象类GenericServlet的子类。同时,HttpServlet类中写入了doGet()、doPost()、doOptions()、doDelete()等方法,他们是对应给HTTP中的Get、Post、Options、Delete等请求提供服务的。
下面简单介绍常用的doGet()、doPost()方法: 表单提交数据到服务器中有两种方式,即 < form action = “***” method= " get / post " >属性method中的get或post。它们分别对应HttpServlet的doGet()、doPost()方法。
doGet():该方式传递的数据会按照< key , value >的方式在URL中显示出来,安全性不高。
doPost():该方式传递的数据存放在HTTP协议的消息体中,通过实体的方式传送到服务器。即将数据封装发出去,安全性高。
Servlet的实现
接下来,我们进一步对Servlet的实现,获取Register.html页面表单提交的参数。
在web文件目录下创建Register.html,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Servlet学习</title>
<link rel="stylesheet" type="text/css" href="CSS/Register.css">
</head>
<body>
<form action="http://localhost:8080/MSW/Register" method="post">
<h1>Welcome</h1>
<label>账号:</label>
<input type="text" name="username"/><br>
<label>密码:</label>
<input type="password" name="pwd"/><br>
<label>性别:</label>
<input type="radio" name="sex" value="男"/>男
<input type="radio" name="sex" value="女"/>女<br>
<label>生日:</label>
<select name="birthday">
<optgroup label="请选择年份">请选择年份</optgroup>
<option value="2000">2000</option>
<option value="2001">2001</option>
<option value="2002">2002</option>
</select><br>
<input type="submit" value="注 册">
<input type="reset" value="重 置">
</form>
</body>
</html>
在web/CSS目录下创建Register.css,代码如下:
body{
text-align:center;
background-color: antiquewhite;
}
在src创建com.edu.ServletStudy包,再创建RegisterServlet.java,代码如下:
package com.edu.ServletStudy;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RegisterServlet extends HttpServlet {
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解决响应结果中文显示乱码
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
//数据获取
String username = request.getParameter("username");
String pwd = request.getParameter("pwd");
String sex = request.getParameter("sex");
String birthdayStr = request.getParameter("birthday"); //获取字符串类型的数据
Integer birthday = Integer.parseInt(birthdayStr); //字符串转整型
//控制台上打印
System.out.println("username = " + username);
System.out.println("pwd = " + pwd);
System.out.println("sex = " + sex);
System.out.println("birthday = " + birthday);
//跳转在新网页上打印
response.getWriter().println(request.getParameter("username"));
response.getWriter().println(request.getParameter("pwd"));
response.getWriter().println(request.getParameter("sex"));
response.getWriter().println(Integer.parseInt(birthdayStr));
}
}
在web/WEB-INF目录下的web.xml,添加如下代码:
<?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">
<!-- 首先,用户发起请求,action=Register; 然后Tomcat中的web.xml先寻找url-pattern = /Register,到servlet-mapping中的servlet-name = RegisterServlet; 再到servlet寻找对应servlet-mapping的servlet-name的servlet; 再找到servlet-class的com.edu.ServletStudy.RegisterServlet; 最后由于用户发送的是post请求(method = post),所以Tomcat执行doPost方法。 -->
<servlet>
<servlet-name>RegisterServlet</servlet-name>
<servlet-class>com.edu.ServletStudy.RegisterServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RegisterServlet</servlet-name>
<url-pattern>/Register</url-pattern>
</servlet-mapping>
</web-app>
在RegisterServlet.java点击运行,效果如图:
控制台结果:
网页结果:
实现过程遇到的问题解决
解决Address localhost:1099 is already in use的问题
在Intellij idea运行中端口出现Address localhost:1099 is already in use的问题(即端口被占用)。 解决办法是:
1.win+R, 输入cmd命令,打开dos命令行,输入netstat -ano | find “1099”,得到PID (即最后一列数字)
2.通过PID找到进程,输入:tasklist | find “那一列数字”
3.最后输入命令关闭进程:taskkill /f /t /im java.exe
如图:
解决Servlet获取radio的值为on的问题
如图:
导致这个问题的主要原因可能是代码有错误的地方,无法识别获取到值。
正确的代码:
<input type="radio" name="sex" value="男"/>男
<input type="radio" name="sex" value="女"/>女<br>
IDEA中的clean工程
clean功能清除项目中缓存重新加载校验。
步骤如图:
1.点击File—>Invalidate Caches / Restart…
2.点击Invalidate and Restart,缓存将在下一次启动时失效并重新构建,当地历史也将被清除。
3.IDEA重启
边栏推荐
- [experience] when ultralso makes a startup disk, there is an error: the disk / image capacity is too small
- (column 22) typical column questions of C language: delete the specified letters in the string.
- 03. 开发博客项目之登录
- How to get list length
- Vulhub vulnerability recurrence 68_ ThinkPHP
- Yygh-11-timing statistics
- Redis message queue
- Graduation design game mall
- Pytorch代码注意的细节,容易敲错的地方
- Solution of QT TCP packet sticking
猜你喜欢
Redis message queue
数字经济破浪而来 ,LTD是权益独立的Web3.0网站?
B站刘二大人-反向传播
26file filter anonymous inner class and lambda optimization
Application Security Series 37: log injection
Report on market depth analysis and future trend prediction of China's arsenic trioxide industry from 2022 to 2028
05. Security of blog project
The ECU of 21 Audi q5l 45tfsi brushes is upgraded to master special adjustment, and the horsepower is safely and stably increased to 305 horsepower
华为路由器如何配置静态路由
- [email protected] raspberry pie"/>
[email protected] raspberry pie
随机推荐
算法-- 爬楼梯(Kotlin)
Note the various data set acquisition methods of jvxetable
Promotion hung up! The leader said it wasn't my poor skills
How to get list length
Li Chuang EDA learning notes 12: common PCB board layout constraint principles
Processes and threads
01. 开发博客项目之项目介绍
局域网同一个网段通信过程
[QNX Hypervisor 2.2用户手册]6.3.3 使用共享内存(shmem)虚拟设备
改善Jpopup以实现动态控制disable
Remember an error in MySQL: the user specified as a definer ('mysql.infoschema '@' localhost ') does not exist
28io stream, byte output stream writes multiple bytes
华为BFD的配置规范
Redis message queue
YYGH-11-定时统计
B站刘二大人-数据集及数据加载 Lecture 8
Installation de la Bibliothèque de processus PDK - csmc
Yygh-11-timing statistics
Sequoiadb Lake warehouse integrated distributed database, June 2022 issue
PDK process library installation -csmc