- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
Servlet是Java Web开发中的重要组件,它运行在服务器端,用于处理客户端的请求并返回响应。其工作原理涉及多个组件和步骤,从客户端发起请求到服务器端的处理和响应,整个过程有条不紊地进行.
Servlet容器是Servlet运行的环境,负责管理Servlet的生命周期、资源分配和请求处理等工作。Tomcat是常用的Servlet容器之一,它具有强大的功能和良好的性能。在Tomcat中,Context容器直接管理Servlet的包装类Wrapper,一个Context对应一个Web工程。例如,在Tomcat的配置文件中,可以通过<Context>标签来配置Web应用的相关参数,如路径、文档库等.
public void init(ServletConfig config) throws ServletException {
super.init(config);
// 在这里进行初始化操作,如获取初始化参数
String paramValue = config.getInitParameter("paramName");
// 其他初始化逻辑
}
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
// 进行登录验证等业务逻辑处理
if (isValidUser(username, password)) {
response.getWriter().println("登录成功");
} else {
response.getWriter().println("登录失败");
}
}
public void destroy() {
// 释放资源的逻辑,如关闭数据库连接
if (connection!= null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
super.destroy();
}
Servlet规范基于几个关键类运转,其中ServletConfig、ServletRequest和ServletResponse与Servlet主动关联。ServletConfig在初始化时传递给Servlet,用于获取Servlet的配置属性;ServletRequest和ServletResponse在请求处理时传递给Servlet,分别用于获取请求信息和设置响应信息.
在Tomcat容器中,存在门面设计模式的应用。例如,StandardWrapper和StandardWrapperFacade实现了ServletConfig接口,传给Servlet的是StandardWrapperFacade对象,它能保证Servlet获取到所需数据而不暴露无关数据。同样,ServletContext也有类似结构,Servlet中获取的实际对象是ApplicationContextFacade,用于获取应用的相关信息.
创建Servlet类需要继承HttpServlet类并重写相应方法。例如,创建一个简单的HelloWorldServlet:
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class HelloWorldServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置响应内容类型为HTML
response.setContentType("text/html");
// 获取输出流对象
PrintWriter out = response.getWriter();
// 输出HTML内容
out.println("<html><body>");
out.println("<h1>Hello, World!</h1>");
out.println("</body></html>");
}
}
在web.xml文件中,需要配置Servlet的相关信息,包括名称、类名、初始化参数和映射路径等。以下是上述HelloWorldServlet的配置示例:
<servlet>
<servlet-name>HelloWorldServlet</servlet-name>
<servlet-class>com.example.HelloWorldServlet</servlet-class>
<init-param>
<param-name>greeting</param-name>
<param-value>Hello!</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorldServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
JSP本质上是Servlet的扩展,JSP页面在第一次被访问时会被翻译成Servlet并执行。在Tomcat中,通过JspServlet来处理JSP页面的翻译工作,其在conf/web.xml中有相应的配置,会拦截所有以.jsp或.jspx为后缀的请求并进行翻译。例如,一个简单的JSP页面:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>JSP Example</title>
</head>
<body>
<%
// 这里可以嵌入Java代码
String message = "This is a JSP page.";
%>
<h1><%=message%></h1>
</body>
</html>
当访问该JSP页面时,Tomcat会将其翻译成对应的Servlet类并执行,最终将生成的HTML内容返回给客户端.
@WebServlet(urlPatterns = "/asyncDemo", asyncSupported = true)
public class AsyncDemoServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
out.println("进入Servlet的时间:" + new Date() + ".");
out.flush();
// 启动异步处理
AsyncContext ctx = req.startAsync();
// 执行异步业务逻辑
new Thread(new AsyncTask(ctx)).start();
out.println("结束Servlet的时间:" + new Date() + ".");
out.flush();
}
}
class AsyncTask implements Runnable {
private AsyncContext ctx;
public AsyncTask(AsyncContext ctx) {
this.ctx = ctx;
}
@Override
public void run() {
try {
// 模拟耗时业务操作,这里等待5秒
Thread.sleep(5000);
PrintWriter out = ctx.getResponse().getWriter();
out.println("业务处理完毕的时间:" + new Date() + ".");
out.flush();
ctx.complete();
} catch (Exception e) {
e.printStackTrace();
}
}
}
<servlet>
标签中添加<async-supported>true</async-supported>
子标签。使用注解配置时,在@WebServlet
或@WebFilter
注解中设置asyncSupported = true
。@WebServlet(urlPatterns = {"/demoServlet"}, asyncSupported = true, loadOnStartup = 1, name = "DemoServlet", displayName = "DS", initParams = {@WebInitParam(name = "param1", value = "value1")})
public class DemoServlet extends HttpServlet {...}
@WebFilter(servletNames = {"DemoServlet"}, filterName = "DemoFilter")
public class DemoFilter implements Filter {...}
@WebListener("This is a demo listener")
public class SimpleListener implements ServletContextListener {...}
multipart/form-data
,并可配置文件大小阈值、存放地址、允许上传的最大值等属性。例如:@MultipartConfig(fileSizeThreshold = 1024 * 1024, location = "/tmp/uploads", maxFileSize = 1024 * 1024 * 5, maxRequestSize = 1024 * 1024 * 10)
@WebServlet("/uploadServlet")
public class UploadServlet extends HttpServlet {...}
<?xml version="1.0" encoding="UTF-8"?>
<web-fragment xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-fragment_3.0.xsd"
metadata-complete="true">
<servlet>
<servlet-name>FragmentServlet</servlet-name>
<servlet-class>com.example.FragmentServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>FragmentServlet</servlet-name>
<url-pattern>/fragment</url-pattern>
</servlet-mapping>
</web-fragment>
<name>
和<ordering>
两个可选顶层标签,用于指定加载顺序。<name>
标识文件,<ordering>
通过<after>
和<before>
子标签指定与其他文件的相对位置关系,还可使用<others/>
表示除自身外的其他文件,其优先级低于明确指定的相对位置关系。ServletContext context = getServletContext();
ServletRegistration.Dynamic dynamicServlet = context.addServlet("DynamicServlet", DynamicServlet.class);
dynamicServlet.addMapping("/dynamic");
dynamicServlet.setLoadOnStartup(2);
contextInitialized
方法或ServletContainerInitializer的onStartup()
方法中调用。ServletContainerInitializer是Servlet 3.0新增接口,容器启动时使用JAR服务API发现其实现类,并将WEB-INF/lib目录下JAR包中的类交给onStartup()
方法处理,通常需使用@HandlesTypes
注解指定处理的类。getPart()
和getParts()
方法用于从请求中解析上传文件,每个文件用javax.servlet.http.Part
对象表示,该接口提供了处理文件的简易方法,如write()
、delete()
等。例如:@WebServlet("/upload")
@MultipartConfig
public class FileUploadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Part filePart = request.getPart("file");
if (filePart!= null) {
filePart.write("/tmp/uploadedFile.txt");
response.getWriter().println("文件上传成功");
} else {
response.getWriter().println("没有选择文件上传");
}
}
}
@MultipartConfig
注解对上传操作进行自定义配置,如限制文件大小和保存路径等。注意,如果请求的MIME类型不是multipart/form-data
,使用上述方法会抛出异常。<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>Login Page</title>
</head>
<body>
<h1>Login</h1>
<form action="login" method="post">
<label for="username">Username:</label><input type="text" id="username" name="username"><br>
<label for="password">Password:</label><input type="password" id="password" name="password"><br>
<input type="submit" value="Login">
</form>
</body>
</html>
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置响应内容类型为HTML
response.setContentType("text/html");
// 获取输出流对象
PrintWriter out = response.getWriter();
// 获取用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
// 假设这里进行简单的用户名和密码验证,实际应用中应与数据库比对
if ("admin".equals(username) && "123456".equals(password)) {
// 登录成功,跳转到欢迎页面
response.sendRedirect("welcome.jsp");
} else {
// 登录失败,返回错误提示
out.println("<html><body>");
out.println("<h1>Login Failed</h1>");
out.println("<p>Invalid username or password.</p>");
out.println("</body></html>");
}
}
}
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.example.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>Welcome</title>
</head>
<body>
<h1>Welcome, <%= request.getParameter("username") %>!</h1>
</body>
</html>
通过这个案例,可以看到Servlet在处理用户请求、验证用户身份以及控制页面跳转等方面的实际应用,它是构建Java Web应用的重要基础组件,在实际开发中还有更多复杂和高级的应用场景等待开发者去探索和实践.
Servlet作为Java Web开发的核心技术之一,在服务器端处理请求和生成响应方面有着不可替代的作用。从其基本的工作原理、生命周期到配置使用,再到Servlet 3.0带来的一系列新特性,都为Java Web开发提供了更强大、更灵活的工具。在实际应用中,它广泛应用于各种Web系统的构建,从简单的网站到复杂的企业级应用。随着技术的不断发展,Servlet也在不断演进,未来可能会在性能优化、与新兴技术的融合等方面有更多的突破,开发者需要持续关注其发展动态,以便更好地利用Servlet构建高效、稳定的Web应用。 作者:代老师的编程课 出处:https://zthinker.com/ 如果你喜欢本文,请长按二维码,关注 Java码界探秘 . 。
最后此篇关于深入理解Servlet:从基础概念到高级特性与实战应用的文章就讲到这里了,如果你想了解更多关于深入理解Servlet:从基础概念到高级特性与实战应用的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
对于相当简单的表结构,即。人员、标准和 PersonCriteria(组合表),我现在设置了一个查询,选择所有符合所有选定条件的人。 此时查询本身看起来像这样: SELECT p.PersonID
我在使用高级 SQL 查询时遇到了一些问题,而且我已经有很长时间没有使用 SQL 数据库了。我们使用 MySQL。 背景: 我们将使用两个表: “交易表” 表:expire_history +----
我找不到错误。也许你可以帮助我:我的代码如下: var data = {"product":[{"config":[{"id":"1","price":"100","sku":"1054879634
我有一个列表列表的列表(最后一个列表并不重要) data = [[[['f', 0], 'C'], [['X', 0], 'X']], [[['s', 1], 'X'], [['X', 0], 'X'
我想准备将使用表格的 session ,并在另一个网站上将新项目添加到 session 中。 默认.cs string[] tab = new string[100];
我知道有一些像: Bubble sort Insertion sort Shell sort Merge sort Heapsort Quicksort Bucket sort Radix sort
像https://softwareengineering.stackexchange.com/questions/150616/return-random-list-item-by-its-weigh
我正在开发一个 posix 脚本 (Linux),它获取一个网页,将内容存储在一个变量中并查找字符串“SUCCESS”。如果找到字符串,则不执行循环内容,如果没有找到字符串,则反复执行循环,直到找到为
我不确定这个问题是否已在其他地方得到解答,而且我似乎无法通过谷歌找到任何不是“Hello World”示例的内容...我正在使用 C# .NET 4.0 进行编码。 我正在尝试开发一个控制台应用程序,
我创建了一个房地产网站,我希望按照列表的最后更新和完整性对列表进行排序。所以我一直想弄清楚如何结合最近更新的列表按mysql中的字段(completion_score)进行排序。完成分数将采用 1
只所以称为“高级”用法,是因为我连switch的最基础的用法都还没有掌握,so,接下来讲的其实还是它的基础用法! switch 语句和具有同样表达式的一系列的 IF 语句相似。很多场合下需要把同一
之前的章节中,我们学习了 XML DOM,并使用了 XML DOM 的 getElementsByTagName() 方法从 XML 文档中取回数据 本章节我们将继续学习其它重要的 XML DOM
我对我尝试编写的 SQL 查询有疑问。 我需要从数据库中查询数据。该数据库除其他外,还包括以下 3 个字段: Account_ID #, Date_Created, Time_Created 我需要编
我正在使用非常激进的视频压缩,例如 -crf 51 .我将其用于“艺术”效果,因此从普通视频压缩的角度来看,我所做的可能没有意义。 到目前为止,我只使用了非常基本的压缩控制,只使用了 -crf。或 -
我真的在学习 lucene 和 ravendb 上的绳索 - 我在 Raven 中有以下文档 - { "InternalEvent": { "Desec": "MachineInfo: 1
通常 grep 命令用于显示包含指定模式的行。有没有办法在包含指定模式的行之前和之后显示 n 行? 这可以使用awk来实现吗? 最佳答案 是的,使用 grep -B num1 -A num2 在匹配之
我搜索了高低,并尝试了几个小时来操纵似乎适合的各种其他查询,但我没有快乐。 我试图加入 Microsoft SQL Server 2005 中的几个表,其中一个示例是: Company Table (
我有一个如下所示的 XML 文件: teacher1Name
我将如何在 CF 中创建此语句? 显然括号不起作用,但说明了我想要完成的工作。这是什么语法? 编辑: 好的,我了解如何使用 EQ 等等。我有点匆忙地发布了这个。我的问题是关于括号。以这种方式使用它们
主要问题:我需要使用具体对象结构对任何对象结构进行类型扩展。 我在 VS Code 中测试的默认值。 我的解决方案: /** @template A @typedef {{[Ki in keyof A
我是一名优秀的程序员,十分优秀!