Servlet 是 Java 编程语言的一种特殊类型的类,通常用于在服务器端处理Web请求和生成Web响应。Servlet 在Java企业环境中广泛用于开发Web应用程序。
服务器端处理:Servlet 主要在服务器端运行,用于处理客户端发送的HTTP请求并生成响应。这使得Servlet成为构建Web应用程序的重要组件。
Java平台:Servlet 是基于Java平台的,因此它可以在几乎所有支持Java的服务器上运行,例如Apache Tomcat、Jetty、IBM WebSphere等。
生命周期:Servlet 有一个生命周期,它包括初始化、请求处理和销毁等阶段。在初始化阶段,Servlet可以执行一些初始化任务。在请求处理阶段,Servlet会响应来自客户端的HTTP请求。最后,在销毁阶段,Servlet可以执行一些清理工作。
HTTP请求和响应:Servlet 主要用于处理HTTP请求和生成HTTP响应。它可以接收来自浏览器的请求,读取请求参数,执行业务逻辑,然后生成HTML、XML或其他格式的响应发送回客户端。
灵活性:Servlet是灵活的,可以用于构建各种Web应用程序,包括动态网页、Web服务、RESTful API等。
Java EE(现在称为Jakarta EE):在Java企业版(Java EE)规范中,Servlet是一个重要的组成部分。Java EE定义了一整套标准API,用于构建企业级Web应用程序,Servlet就是其中之一。
Servlet的使用通常需要Java编程知识,但它是构建强大和可扩展Web应用程序的重要工具。Servlet容器(例如Tomcat)负责管理Servlet的生命周期,并确保它们可以响应来自客户端的请求。这使得Java在服务器端开发Web应用程序变得非常流行。
创建Web项目及包,创建 FirstServlet.java 。
#包名
package com.hong.Servlet.HttpServlet;
package com.hong.Servlet.HttpServlet;
import jakarta.servlet.GenericServlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author WangYH
* @version 2021.1.3
* @date 2023/10/4 16:55
*/
public class FirstServlet extends GenericServlet {
@Override
public void init() throws ServletException {
System.out.println("init 开始运行");
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("solution Request");
//获得输出流PrintWriter对象
PrintWriter printWriter = servletResponse.getWriter();
//Servlet调用输出流对象向客户发送字符信息
printWriter.println("FirstServlet,hello
");
}
@Override
public void destroy() {
System.out.println("destroy start");
}
}
第二步还要配置虚拟路径才能在浏览器访问,可以使用XML文件或者注解。
<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> FirstServlet servlet-name>
<servlet-class>com.hong.Servlet.HttpServlet.FirstServletservlet-class>
<load-on-startup> 1 load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>SecondServletservlet-name>
<url-pattern>/SecondServleturl-pattern>
servlet-mapping>
web-app>
第三步就是发布到Tomcat,输入虚拟路径访问资源。
通常是一个名为 “web.xml” 的XML文件。在这个XML文件中,您可以定义和配置Servlet,以便在Web应用程序中使用。
<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>HelloServletservlet-name>
<servlet-class>com.example.HelloServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>HelloServletservlet-name>
<url-pattern>/hellourl-pattern>
servlet-mapping>
web-app>
在 web.xml 文件中为Servlet设置两个虚拟路径,示例代码
<servlet-mapping>
<servlet-name>HelloServletservlet-name>
<url-pattern>/HelloServleturl-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>HelloServletservlet-name>
<url-pattern>/hellourl-pattern>
servlet-mapping>
访问 /HelloServlet
和 /hello
是一样的效果。
或者是更加简短
<servlet-mapping>
<servlet-name>HelloServletservlet-name>
<url-pattern>/HelloServleturl-pattern>
<url-pattern>/hellourl-pattern>
servlet-mapping>
Servlet可以通过多重映射来处理多个不同的URL路径,这样可以将不同的请求分派到同一个Servlet或不同的Servlet上,以实现不同的处理逻辑。多重映射可以在一个Servlet应用中更灵活地处理各种请求。
以下是一些关于Servlet多重映射的示例:
精确匹配:您可以使用精确匹配来指定Servlet处理特定的URL路径。例如:
<servlet-mapping>
<servlet-name>MyServletservlet-name>
<url-pattern>/specific-pathurl-pattern>
servlet-mapping>
在这种情况下,Servlet “MyServlet” 仅会处理 “/specific-path” 路径的请求。
通配符匹配:您可以使用通配符来匹配一组URL。例如:
<servlet-mapping>
<servlet-name>MyServletservlet-name>
<url-pattern>/products/*url-pattern>
servlet-mapping>
在这种情况下,Servlet “MyServlet” 将处理以 “/products/” 开头的所有路径,例如 “/products/item1”、“/products/item2” 等。
扩展名匹配:您可以使用扩展名匹配来匹配特定文件扩展名的URL。例如:
<servlet-mapping>
<servlet-name>ImageServletservlet-name>
<url-pattern>*.jpgurl-pattern>
servlet-mapping>
在这种情况下,Servlet “ImageServlet” 将处理以 “.jpg” 结尾的所有URL,例如 “/images/pic1.jpg”、“/photos/photo.jpg” 等。
默认Servlet:在一些Servlet容器中,还有一个称为默认Servlet的特殊Servlet,它可以处理所有未匹配到其他Servlet的请求。这通常用于提供静态资源,如HTML文件、图像和CSS。
使用多重映射,您可以根据具体的需求将不同的URL请求映射到不同的Servlet上,以实现不同的处理逻辑。这允许您构建更复杂的Web应用程序,可以处理多种不同类型的请求。配置多重映射通常是在Web应用程序的"web.xml"文件中完成的。优先级原则是 精确高于模糊,路径名高于扩展名,相似度高优先。
一般使用 "@WebServlet(name = " ", urlPatterns = {" /url "})"
,
例如上一个还可以简写成 " @WebServlet("/FirstServlet")"
这里特别注意一下,以下每一个示例,我都没有贴上相应的配置文件,即web.xml 是缺失的,需要自己写或者看我上面那个如何配置的那个小点,当然如果是用注解配置的话,会一并附在代码之中,就无需单独配置文件了
HttpServlet类的主要方法可以查看具体源码,主要是满足不同请求方式,当然还有 service 方法。
package com.hong.Servlet.HttpServlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author WangYH
* @version 2021.1.3
* @date 2023/10/4 17:36
*/
public class SecondServlet extends HttpServlet {
/**
* 构造方法直接调用父类的方法
*/
public SecondServlet() {
super();
}
/**
*
* @param request 接收一个HttpServletRequest对象(用于获取请求信息)
* @param response 一个HttpServletResponse对象(用于生成响应)
* @throws ServletException
* @throws IOException
*
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=GB18030");
//这一行设置响应的内容类型为"text/html;charset=GB18030",表示响应的内容将以HTML格式和GB18030字符编码发送给客户端。
response.getWriter().write("少年强则国强:A strong youth makes a strong country");
//这一行将文本消息,写入响应的输出流,以便将其发送给客户端浏览器。
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=GB18030");
response.getWriter().write("大众创业,万众创新:Mass entrepreneurship and innovation");
}
}
<servlet>
<servlet-name> FourthServlet servlet-name>
<servlet-class>com.hong.Servlet.HttpServlet.FourthServletservlet-class>
<init-param>
<param-name>encodingparam-name>
<param-value>GB18030param-value>
init-param>
servlet>
<servlet-mapping>
<servlet-name>FourthServletservlet-name>
<url-pattern>/testurl-pattern>
servlet-mapping>
重写 doGet() 方法
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决中文乱码 req指的是请求
req.setCharacterEncoding("UTF-8");
//resp指的是响应
resp.setContentType("text/html");
resp.setCharacterEncoding("UTF-8");
PrintWriter writer = resp.getWriter();
//获取ServletConfig对象
ServletConfig servletConfig = this.getServletConfig();
//读取初始化参数encoding的值
String encoding = servletConfig.getInitParameter("encoding");
writer.print("参数encoding:"+encoding);
}
web.xml文件
<context-param>
<param-name> username param-name>
<param-value> admin param-value>
context-param>
<context-param>
<param-name>passwdparam-name>
<param-value>1234param-value>
context-param>
还是重写 doGet 方法
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html; charset=GB18030");
PrintWriter writer = resp.getWriter();
ServletContext context = this.getServletContext();
Enumeration<String> paramNames = context.getInitParameterNames();
while (paramNames.hasMoreElements()){
String name = paramNames.nextElement();
String value = context.getInitParameter(name);
writer.println(name + " : "+value);
writer.println("
");
}
}
创建三个Java文件,重写1的 doGet 方法如下
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html; charset=GB18030");
PrintWriter writer = resp.getWriter();
ServletContext context = this.getServletContext();
context.setAttribute("name", "陆亦凡");
context.setAttribute("sex","男");
String name = (String) context.getAttribute("name");
String sex = (String) context.getAttribute("sex");
writer.println("获取的上下文的name:"+name + ";\n获取的上下文的sex:"+sex);
}
重写2的 doGet 方法如下
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html; charset=GB18030");
PrintWriter writer = resp.getWriter();
ServletContext context = this.getServletContext();
context.setAttribute("name", "李萌萌");
context.setAttribute("sex","女");
String name = (String) context.getAttribute("name");
String sex = (String) context.getAttribute("sex");
writer.println("获取的上下文的name:"+name + ";\n获取的上下文的sex:"+sex);
}
重写3的 doGet 方法如下
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html; charset=GB18030");
PrintWriter writer = resp.getWriter();
ServletContext context = this.getServletContext();
String name = (String) context.getAttribute("name");
String sex = (String) context.getAttribute("sex");
writer.println("获取的上下文的name:"+name + ";\n获取的上下文的sex:"+sex);
}
访问对应的虚拟路径可看到,3会和1或者2保持一致(这里取决谁把数据存入了),这是因为name和sex属性被多个对象共享了。
这里创建好properties,随便填入一些信息
username = admin;
password = 123456;
重写 doGet 方法如下
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html; charset=GB18030");
ServletContext context = this.getServletContext();
PrintWriter writer = resp.getWriter();
InputStream in = context.getResourceAsStream("/WEB-INF/classes/servuser.properties");
Properties properties = new Properties();
properties.load(in);
writer.println("获取的上下文的username:"+properties.getProperty("username"));
writer.println("
");
writer.println("获取的上下文的password:"+properties.getProperty("password"));
}