Servlet
介绍
Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。
Java Servlet 通常情况下与使用 CGI(Common Gateway Interface,公共网关接口)实现的程序可以达到异曲同工的效果。但是相比于 CGI,Servlet 有以下几点优势:
- 性能明显更好。
- Servlet 在 Web 服务器的地址空间内执行。这样它就没有必要再创建一个单独的进程来处理每个客户端请求。
- Servlet 是独立于平台的,因为它们是用 Java 编写的。
- 服务器上的 Java 安全管理器执行了一系列限制,以保护服务器计算机上的资源。因此,Servlet 是可信的。
- Java 类库的全部功能对 Servlet 来说都是可用的。它可以通过 sockets 和 RMI 机制与 applets、数据库或其他软件进行交互。
Servlet在Web应用程序中的地位
环境配置
在市场上有许多 Web 应用服务器支持 Servlet。有些 Web 应用服务器是免费下载的,Tomcat 就是其中的一个。
所以这里我们使用Tomcat
在官网下载完Tomcat后在bin文件夹中找到startup.bat文件并启动,之后可以在浏览器地址栏输入http://localhost:8080/,如果配置正常可以看到下面的页面(在运行之前要先配好Java软件开发包(即SDK)的配置,有需要请自行搜索)
生命周期
Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:
- Servlet 初始化后调用 init () 方法
- Servlet 调用 service() 方法来处理客户端的请求
- Servlet 销毁前调用 destroy() 方法
- 最后,Servlet 由 JVM 的垃圾回收器进行垃圾回收
接下来讨论生命周期的方法
1.init()方法
init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用,是一次性初始化
Servlet 创建于用户第一次调用对应于该 Servlet 的 URL 时,但是也可以指定 Servlet 在服务器第一次启动时被加载。
当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期。
init 方法的定义如下:
public void init() throws ServletException{
//初始化代码
}
2.service()方法
service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。
每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。
- doGet() 处理GET请求,用于向服务器获取数据
- doPost() 处理POST请求,用于向服务器发送数据
- doPut() 发送文件
- doDelete() 向服务器请求删除数据
下面是该方法的特征
public void service(ServletRequest request,ServletResponse response) throws ServletException, IOException {
}
这个方法通常由容器调用,也就是说一般并不需要对这个方法做什么操作,你只需要根据需求重写doGet、doPost方法即可
3.destory()方法
destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。destroy() 方法可以让您的 Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。
在调用 destroy() 方法之后,servlet 对象被标记为垃圾回收。destroy 方法定义如下
public void destroy() {
// 终止化代码
}
这里有一个很典型的架构图
可以看下面的文章学习如何用IDEA搭建Servlet基本构架(亲测有效,而且易懂
IDEA(2022.2)搭建Servlet基本框架详细步骤_servlet框架搭建_loginweb的博客-CSDN博客
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>helloServlet</servlet-name>
<servlet-class>HelloServlet</servlet-class>
<load-on-startup>0</load-on-startup>
<!-- 加载顺序,设置为负数时与未设置没有区别-->
<init-param>
<param-name>first</param-name>
<param-value>这是第一个参数</param-value>
</init-param>
<init-param>
<param-name>second</param-name>
<param-value>这是第二个参数</param-value>
</init-param>
<!--<init-param>配置的param-name和param-value作用是在servlet初始化执行init方法时,通过getInitParameter获取web.xml中的param-value-->
<!--<init-param>与<load-on-startup>不能同时存在-->
</servlet>
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/helloServlet</url-pattern>
</servlet-mapping>
</web-app>
Servlet表单数据
很多情况下,需要传递一些信息,从浏览器到 Web 服务器,最终到后台程序。浏览器使用两种方法可将这些信息传递到 Web 服务器,分别为 GET 方法和 POST 方法。
Get()方法
GET 方法向页面请求发送已编码的用户信息。页面和已编码的信息中间用 ? 字符分隔,GET 方法是默认的从浏览器向 Web 服务器传递信息的方法,它会产生一个很长的字符串,出现在浏览器的地址栏中。如果您要向服务器传递的是密码或其他的敏感信息,请不要使用 GET 方法。GET 方法有大小限制:请求字符串中最多只能有 1024 个字符。
这些信息使用 QUERY_STRING 头传递,并可以通过 QUERY_STRING 环境变量访问,Servlet 使用 doGet() 方法处理这种类型的请求。
Post()方法
另一个向后台程序传递信息的比较可靠的方法是 POST 方法。POST 方法打包信息的方式与 GET 方法基本相同,但是 POST 方法不是把信息作为 URL 中 ? 字符后的文本字符串进行发送,而是把这些信息作为一个单独的消息。消息以标准输出的形式传到后台程序,您可以解析和使用这些标准输出。Servlet 使用 doPost() 方法处理这种类型的请求。
具体代码不贴了,目前还没调出来
哈哈哈哈哈,成了!
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.*;
import javax.servlet.*;
@WebServlet("/HelloForm")
public class HelloForm extends HttpServlet {
private static final long serialVersionUID = 11233411L;
public HelloForm(){
super();
}
protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String title = "使用Get方法处理数据ing";
String name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "UTF-8");
String docType = "<!DOCTYPE html> \n";
out.println(docType +
"<html>\n" +
"<head><title>" + title + "</title></head>\n" +
"<body bgcolor=\"#f0f0f0\">\n" +
"<h1 align=\"center\">" + title + "</h1>\n" +
"<ul>\n" +
" <li><b>站点名</b>:"
+ name + "\n" +
" <li><b>网址</b>:"
+ request.getParameter("url") + "\n" +
"</ul>\n" +
"</body></html>");
//这里就是用Java输出方式打印HTML内容
}
public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{
doGet(request,response);
}
//处理Post方法请求的方法
}
HelloForm.java文件
<?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>HelloForm</servlet-name>
<servlet-class>HelloForm</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloForm</servlet-name>
<url-pattern>/HelloForm</url-pattern>
</servlet-mapping>
</web-app>
web.xml文件
在浏览器地址栏输入http://localhost:8080/test/HelloForm?name=Aspas&url=www.IGetIt.com,页面显示为
name和url里的内容可以随便改,但目前这份代码不支持中文站点名,之后再找找怎么改
后面的比如在表单中输入数据弄不出来了,故没有代码,只有理论
哈哈哈哈哈,又成了!
先上展示
之前搞不出来的原因是手欠在html里的method方法里的post和get的首字母大写了,所以下次一定要好好看看单词拼写......
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>导航页面</h1>
<br>
<a href="/test/helloServlet">进入Servlet</a>
<br>
<a href="/test/HelloForm">进入表单</a>
<br>
<form action="HelloForm" method="get">
网址名:<input type="text" name="name" />
<br />
网址:<input type="text" name="url" />
<input type="submit" value="提交" />
</form>
</body>
</html>
html文件内容
编译部署Servlet,并使用带有 POST 方法创建表单的 html文件,就可以通过在表单里输入数据提交后出现如上图的页面
<form action="HelloForm" method="get">
<!--表单起始部分写法,sction为当提交表单时,发送表单数据到这个url-->
<!--method 为处理方法-->
<!--若用get方法会在地址栏展示你刚才输入的内容,这对碰到输入密码之类的东西的情境绝对是不友好的-->
<!--所以我们可以使用method="post"这样的方法来避免掉这种情况-->
MVC
M:model 模型
模型是用于处理数据逻辑的部分。所谓数据逻辑,也就是数据的映射以及对数据的增删改查,Bean、DAO(data access object,数据访问对象)等都属于模型部分。
V:view 视图
视图负责数据与其它信息的显示,也就是给用户看到的页面。
C:controller 控制器
控制器是模型与视图之间的桥梁,控制着数据与用户的交互。控制器通常负责从视图读取数据,处理用户输入,并向模型发送数据,也可以从模型中读取数据,再发送给视图,由视图显示。前面学到的 Servlet 便可以用作控制器。
这种模式用于应用程序的分层开发,是一种“高内聚 低耦合”的模式
MVC 可以在一个时间内专门关注一个方面,从而让应用程序的测试与迭代更加方便。所以,复杂的应用程序大都会选择使用 MVC 模式。
下面用Java来模拟一下MVC模型
public class Student {
private String UID;
private String name;
public void setName(String name) {
this.name = name;
}
public String getName (){
return name;
}
public String getUID() {
return UID;
}
public void setUID(String UID) {
this.UID = UID;
}
}
//模型部分
public class StudentView {
public void printStudentDetails (String studentName,String studentUID){
System.out.println("Student :");
System.out.println("Name :"+studentName);
System.out.println("UID :"+studentUID);
}
}
//视图部分
public class StudentController {
private Student model;
private StudentView view;
public StudentController(Student student,StudentView studentView) {
this.model=student;
this.view=studentView;
}
public String getStudentName (){
return model.getName();
}
public void setStudentName (String name){
model.setName(name);
}
public String getStudentUID (){
return model.getUID();
}
public void setStudentUID (String UID){
model.setUID(UID);
}
public void updateView(){
view.printStudentDetails(model.getName(), model.getUID());
}
}
//控制器部分
public class MVCPatternDemo {
public static void main(String[] args) {
Student model = retrieveStudentFromDatabase();
StudentView view = new StudentView();
StudentController controller = new StudentController(model,view);
controller.updateView();
controller.setStudentName("jch");
controller.setStudentUID("220002");
controller.updateView();
}
private static Student retrieveStudentFromDatabase(){
Student zjh = new Student();
zjh.setUID("220001");
zjh.setName("zjh");
return zjh;
}
}
//模拟用法
/*
输出:
Student :
Name :zjh
UID :220001
Student :
Name :jch
UID :220002
*/
JAR包的导入使用
JAR包
jar包就是 Java Archive File,顾名思义,它的应用是与 Java 息息相关的,是 Java 的一种文档格式,是一种与平台无关的文件格式,可将多个文件合成一个文件。jar 包与 zip 包非常相似——准确地说,它就是 zip 包,所以叫它文件包。jar 与 zip 唯一的区别就是在 jar 文件的内容中,包含了一个 META-INF/MANIFEST.MF 文件,该文件是在生成 jar 文件的时候自动创建的,作为jar里面的"详情单",包含了该Jar包的版本、创建人和类搜索路径Class-Path等信息,当然如果是可执行Jar包,会包含Main-Class属性,表明Main方法入口,尤其是较为重要的Class-Path和Main-Class
JAR包的导出
导入之前先学学导出不是很正常的嘛~
之后选择你之前选好的模块就行,构建完工件后该jar包就出现在out中
JAR包的导入与使用
先新建一个项目,在项目目录下建立lib文件夹,之后把生成的jar包移入lib中
之后可以将你刚建立的jar包添加进库中
最后我们随意的敲一些代码,发现这个代码可以自然的使用在新建的项目中未设立的类
public class WHY {
public static void main(String[] args) {
Student student = new Student();
student.setName("Bocci");
System.out.println(student.getName());
}
}
//导入的jar包就是上面MSC测试用的Java文件
/*
输出:
Bocci
*/
参考文章
太多了就不列出了,浏览器搜出来的在前几页的基本都有看
课后总结
在课上了解了Javax与Jakarta间的区别,(只要我不更新Tomcat版本就不会出问题
好奇看了一下,发现引用的包仍是Javax.servlet(不知道是不是和自己的JDK版本有关
想了一下如果之后要用高版本的Tomcat又要改这玩意不如现在看一看解决方法
???
嗯,不改版本了!
看到有的解决方法就是在pom.xml里面添加jakarta.servlet-api依赖,去掉javax.servlet-api依赖。
姑且贴一下带有解决方法的文章
Tomcat10版本避坑_NeverOW的博客-CSDN博客
maven tomcat10 servlet api 不兼容 包名javax变成jakarta 实例化Servlet类 异常_jakarta和javax_Yuan-fei的博客-CSDN博客
感谢观看