Web技术基础教程 9_第1页
Web技术基础教程 9_第2页
Web技术基础教程 9_第3页
Web技术基础教程 9_第4页
Web技术基础教程 9_第5页
已阅读5页,还剩58页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

JavaWeb开发技术与案例教程第7章JavaServlet技术第7章知识结构7.1Servlet概述7.2Servlet的创建与配置•7.2.1Servlet的创建方式•7.2.2Servlet的配置方法7.3案例学习:Servlet的应用7.4JSP与Servlet•7.4.1JSP编译过程分析•7.4.2JSP编译为Servlet7.5数据库与Servlet•7.5.1使用连接池访问数据库•7.5.2使用PreparedStatement语句•7.5.3实例:PreparedStatement的应用7.6本章小结1第7章课程导入

Servlet是ServerApplet的缩写,是用Java编写的服务器端程序。它主要用于接收客户端(通常是Web浏览器)的请求,并生成相应的响应内容返回给客户端。其核心为继承HttpServlet并重写doGet/doPost方法,生命周期涵盖初始化、服务、销毁三阶段,支持GET/POST请求处理。配置采用@WebServlet注解或web.xml映射URL,如@WebServlet("/login")。本章将学习创建与配置Servlet的方法,并且以表单登录为案例,掌握如何通过Servlet实现客户端和服务器数据交互。◆本章要点•理解Servlet的生命周期,包括init()、service()和destroy()方法。•掌握创建Servlet的两种配置方式:web.xml文件配置和@WebServlet注解配置。•掌握在Servlet中使用doGet()或doPost()方法处理客户端请求。•理解JSP与Servlet的关系,即JSP本质上会被编译成Servlet。•掌握在Servlet中使用数据库连接池(DBCP)和PreparedStatement进行安全高效的数据库访问。2第7章课程导入◆素养目标•深化生命周期认知,践行资源节约:通过Servlet初始化与销毁方法学习,倡导“按需初始化、及时释放”的资源管理意识。•强化配置规范,保障系统稳定性:在@WebServlet注解与web.xml配置对比中,强调URL映射唯一性原则。•培养责任意识,守护系统入口:结合登录案例中doPost()方法凭证验证逻辑,理解Servlet作为后端入口的安全职责。•推动前后端分离,提升协作效率:通过Servlet与JSP协同案例,理解“控制层-视图层”分离的价值。37.1Servlet概述(1)

JavaServlet是JakartaEE平台下的技术标准,是JavaWeb开发中的重要组成部分。JavaServletAPI是Servlet容器和Servlet之间的接口,它定义了Servlet的各种方法,还定义了Servlet容器传送给Servlet的对象类,其中最重要的就是ServletRequest和ServletResponse。◆Servlet主要功能◆请求处理

Servlet可以接收来自客户端(如HTTP请求)的数据,并根据请求的内容执行相应的业务逻辑。处理请求的过程中,Servlet可以访问数据库、调用其他Java类或对象、执行计算等。◆生成响应根据处理的结果,Servlet可以生成响应并将其发送回客户端,响应可以是HTML页面、JSON数据、XML文档、图像和文件下载等。47.1Servlet概述(2)

Servlet可以设置响应的内容类型(如text/html、application/json等),以及状态码(如200OK、404NotFound等)。◆会话管理

Servlet支持HTTP会话(Session),允许在多个请求和响应之间保持用户数据。会话数据可以存储在服务器端,并且与特定的客户端(通过会话ID标识)关联。◆请求过滤通过实现jakarta.servlet.Filter接口,Servlet可以拦截并处理客户端请求和服务器响应。过滤器可以用于身份验证、日志记录、数据压缩和字符编码转换等。◆与资源交互

Servlet可以访问Web应用程序中的资源,如JSP文件、Servlet上下文参数、初始化参数等。Servlet还可以访问Web应用程序的上下文(ServletContext),用于存储全局数据。57.1Servlet概述(3)◆错误处理

Servlet可以处理在请求处理过程中发生的异常和错误,并向客户端返回适当的错误响应。通过定义错误页面,Servlet可以优雅地处理未捕获的异常,提高应用程序的健壮性和用户体验。◆多线程处理

Servlet容器会为每个请求创建一个新的线程,因此Servlet需要能够处理并发请求。这意味着Servlet应该是线程安全的,即多个线程同时访问Servlet时不会引发数据竞争或不一致。◆框架集成

Servlet是许多JavaWeb应用程序框架(如SpringMVC、Struts等)的基础,框架通常提供了更高级别的抽象和工具,用于简化Servlet编程和Web应用程序开发。67.1Servlet概述(4)◆Servlet的生命周期Servlet的生命周期由Servlet容器(如Tomcat)管理,主要包括以下几个阶段:◆加载和实例化:当Servlet第一次被请求时,Servlet容器会加载并实例化Servlet类。◆初始化:在Servlet实例化后,Servlet容器会调用Servlet的init()方法进行初始化。这个方法只会被调用一次。在初始化阶段,Servlet对自身进行必要的初始化操作。◆请求处理:每次请求Servlet时,Servlet容器都会调用service()方法处理请求。这个方法会根据请求的类型(如GET、POST)调用相应的doGet()、doPost()等方法。◆销毁:当Servlet容器关闭或需要被卸载时,Servlet容器会调用destroy()方法进行销毁。这个方法也只会被调用一次。在这个方法中,Servlet可以释放资源、停止后台线程和执行清理工作等。【注意】实际上,客户端对Servlet发送一个请求时,服务器会开启一个新的线程,该线程会调用service()方法,然后根据客户端请求的类型调用doGet()或者doPost()方法。在一般情况下,不需要覆盖service()方法,直接实现doGet()或者doPost()方法就可以达到目的。77.2.1Servlet的创建方式(1)在JavaWeb开发中,Servlet是处理客户端请求并生成动态响应的核心组件。根据不同的需求和场景,Servlet的创建方式主要有以下三种,每种方式都有其特点和适用情况:◆实现Servlet接口这是最基础、最直接的Servlet创建方式。因为Servlet本质上是一个实现了jakarta.servlet.Servlet接口的Java类。开发者需要实现该接口中定义的所有方法,包括init()、service()、destroy()、getServletConfig()和getServletInfo()。尽管这种方式提供了最大的灵活性,但由于需要手动实现所有方法,代码量较大,通常在实际开发中较少使用,除非有特殊的定制需求。87.2.1Servlet的创建方式(2)◆继承GenericServlet抽象类为了简化Servlet的开发,JakartaEE提供了GenericServlet抽象类。该类实现了Servlet接口,并提供了其中大部分方法的默认实现,仅将service()方法声明为抽象方法,要求子类必须重写。通过继承GenericServlet,开发者可以专注于业务逻辑的实现,而无需关心Servlet生命周期的其他细节。这种方式适用于不依赖于特定协议(如HTTP)的Servlet开发。97.2.1Servlet的创建方式(3)◆继承HttpServlet抽象类

HttpServlet是GenericServlet的子类,专门用于处理HTTP请求,是实际开发中最常用的Servlet创建方式。它进一步简化了Servlet的创建过程,提供了针对HTTP协议的便捷支持。HttpServlet类实现了service()方法,并根据HTTP请求的类型(如GET、POST、PUT、DELETE等)自动调用相应的doXxx()方法(如doGet()、doPost())。开发者只需根据需求重写这些方法,即可实现具体的业务逻辑。这种方式大大提高了开发效率,并降低了代码的复杂性,因此成为JavaWeb开发中的标准做法。综上所述,选择哪种Servlet创建方式取决于具体需求。对于一般的Web应用开发,推荐使用继承HttpServlet的方式,因为它提供了最简洁和高效的开发模式。107.2.2Servlet的配置方法

Servlet的配置可以通过web.xml文件和@WebServlet注解两种方式实现。◆XML配置在JavaEE的早期版本中,一般使用XML配置文件定义Servlet。通常在web.xml文件中配置Servlet的映射关系,定义Servlet的名称、类名和初始化参数等。然后,在Java代码中继承HttpServlet类,并覆盖其中的doGet()或doPost()方法处理请求。清单7-1所示的代码是一个Servlet的XML配置文件。117.2.2Servlet的配置方法(清单7-1web.xml)<?xmlversion="1.0"encoding="UTF-8"?><web-appxmlns="https://jakarta.ee/xml/ns/jakartaee"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaeehttps://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"version="6.0"><display-name>java-servlet-demo</display-name><!--servlet配置--><servlet><!--Servlet名称--><servlet-name>WebXmlServlet</servlet-name><!--servlet全称类名--><servlet-class>com.example.ch07.WebXmlServlet</servlet-class></servlet><!--映射配置--><servlet-mapping><!--对应名称--><servlet-name>WebXmlServlet</servlet-name><!--资源匹配规则:精确匹配--><url-pattern>/webxml</url-pattern></servlet-mapping></web-app>127.2.2Servlet的配置方法上述配置文件中,使用<servlet>和<servlet-mapping>元素配置Servlet。首先在<servlet>元素中指定Servlet的名称为WebXmlServlet,Servlet类的完整路径为com.example.ch07.WebXmlServlet。在<servlet-mapping>元素中指定Servlet的URL映射,<servlet-name>指定了之前配置的Servlet名称,实例中为WebXmlServlet。<url-pattern>指定了Servlet的URL映射,即客户端请求中的URL必须结尾为/webxml才会被该Servlet处理。关于<url-pattern>的匹配规则如表7-1所示。137.2.2Servlet的配置方法表7-1<url-pattern>的匹配规则匹配规则值取值说明精确匹配/具体的名称只有url路径是具体的名称的时候才会触发Servlet后缀匹配*.xxx只要是以xxx结尾的就匹配触发Servlet通配符匹配/*匹配所有请求,包含服务器的所有资源通配符匹配/匹配所有请求,包含服务器的所有资源,不包括.jsp147.2.2Servlet的配置方法(清单7-2WebXmlServlet.java)1/2对应的Servlet类的代码如清单7-2所示。packagecom.example.ch07;importjakarta.servlet.ServletException;importjakarta.servlet.http.HttpServlet;importjakarta.servlet.http.HttpServletRequest;importjakarta.servlet.http.HttpServletResponse;importjava.io.IOException;publicclassWebXmlServletextendsHttpServlet{/***核心服务方法,处理所有HTTP请求*@paramreqHTTP请求对象,包含客户端请求信息*@paramrespHTTP响应对象,用于向客户端返回响应*@throwsServletException服务异常*@throwsIOException输入输出异常*/@Overrideprotectedvoidservice(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{157.2.2Servlet的配置方法(清单7-2WebXmlServlet.java)2/2//设置响应体的字符编码为UTF-8(解决中文乱码问题),注意:需在获取Writer之前设置编码。resp.setCharacterEncoding("UTF-8");//设置Content-Type:1.响应内容类型为HTML格式,2.强制客户端使用UTF-8解码。resp.setHeader("content-type","text/html;charset=UTF-8");//获取PrintWriter对象并向客户端输出响应内容,最终显示效果:浏览器将渲染字符串为HTML内容resp.getWriter().write("基于web.xml方式配置的Servlet");}}167.2.2Servlet的配置方法上述代码运行结果如图7-1所示。http://localhost:8080/ch07/webxml图7-1基于XML方式配置的Servlet运行结果177.2.2Servlet的配置方法◆注解配置从JavaEE5开始(包括现在的JakartaEE),可以使用注解创建Servlet。通过在Servlet类中添加@WebServlet注解。所有的Servlet注解定义在jakarta.servlet.annotation.*包中,因此需要引入该包。在注解中,可以指定Servlet的名称、URL映射等。这种方式简单方便,不需要修改web.xml文件。这种配置方法逐步取代了上述传统的XML配置方式,在开发中推荐使用。【注意】从Tomcat10开始支持JakartaEE9规范,它的命名空间使用的是Jakarta,而不再是之前的javax,且与之前的API不兼容,因此使用旧版本ServletAPI开发的程序,需要迁移修改才能运行于Tomcat10及以后的版本。

Servlet的注解配置实例代码如清单7-3所示。187.2.2Servlet的配置方法(清单7-3AnnotationServlet.java)1/2packagecom.example.ch07;importjakarta.servlet.ServletException;importjakarta.servlet.annotation.WebServlet;importjakarta.servlet.http.HttpServlet;importjakarta.servlet.http.HttpServletRequest;importjakarta.servlet.http.HttpServletResponse;importjava.io.IOException;/***基于注解方式配置的Servlet示例*使用@WebServlet注解替代web.xml中的配置*/@WebServlet("/annotation")//定义Servlet的访问URL路径publicclassAnnotationServletextendsHttpServlet{/***处理所有HTTP请求的方法(GET、POST等)*@paramrequestHttpServletRequest对象,包含客户端请求信息*@paramresponseHttpServletResponse对象,用于构造响应*@throwsServletException如果Servlet遇到困难*@throwsIOException如果发生输入/输出错误*/@Overrideprotectedvoidservice(HttpServletRequestrequest,HttpServletResponseresponse)197.2.2Servlet的配置方法(清单7-3AnnotationServlet.java)2/2throwsServletException,IOException{//设置响应内容的字符编码为UTF-8,防止中文乱码response.setCharacterEncoding("UTF-8");//设置响应头中的Content-Type,指定响应类型和字符编码response.setHeader("content-type","text/html;charset=UTF-8");//获取PrintWriter对象,向客户端输出HTML内容response.getWriter().write("基于注解方式配置的Servlet");}}207.2.2Servlet的配置方法上述代码中,使用了注解的方式配置Servlet,配置过程中需要注意以下几点:◆@WebServlet属于类级别的注解,标注在继承了HttpServlet的类之上。常用的写法是将Servlet的相对请求路径(即value)直接写在注解内。◆@WebServlet(urlPatterns="/annotation"),也可以简写成@WebServlet("/annotation"),省略urlPatterns属性名。但是URL模式必须以“/”开头(除特定扩展名匹配外)。◆如果@WebServlet中需要设置多个属性,则属性之间必须使用逗号隔开。217.2.2Servlet的配置方法表7-2注解常用属性属性名类名属性描述nameString指定servlet的name属性,若未指定,默认是类的全限定名valueString[]等价于urlPatterns,两者不能共存urlPatternsString[]指定一组servlet的url的匹配模式,等价于<url-pattern>loadOnStartupint指定servlet的加载顺序,等价于<load-on-startup>initParamsWebinitParams[]指定一组初始化参数,等价于<init-params>asyncSupportedboolean声明servlet是否支持异步操作模式,等价于<async-supported>displayNameStringservlet的显示名称,等价于<display-name>descriptionStringservlet的描述信息,等价于<description>227.2.2Servlet的配置方法上述代码运行结果如图7-2所示。http://localhost:8080/ch07/annotation图7-2基于注解方式配置的Servlet运行结果【注意】如果web.xml中设置了metadata-complete="true",容器将忽略所有注解配置。这是初学者常遇到的“注解不生效”的原因之一。237.3案例学习:Servlet的应用在JavaWeb开发中,使用Servlet实现用户登录是一个常见的任务。下面实例演示如何使用Servlet处理用户登录请求。◆创建登录表单首先,需要一个包含登录表单的login.jsp文件,用户可以在其中输入用户名和密码。这个表单将提交到Servlet进行处理。代码如清单7-4所示。247.3案例学习:Servlet的应用(清单7-4login.jsp)<%@pagelanguage="java"contentType="text/html;charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPEhtml><html><head><title>Login</title></head><body><h2>LoginForm</h2><formaction="login"method="post"><labelfor="username">Username:</label><inputtype="text"id="username"name="username"required><br><br><labelfor="password">Password:</label><inputtype="password"id="password"name="password"required><br><br><inputtype="submit"value="Login"></form></body></html>257.3案例学习:Servlet的应用回忆前面所学的表单处理技术,之前是将表单提交到JSP页面处理。而上述代码表明,可以将表单改为由Servlet处理,再由Servlet处理并返回结果到JSP页面显示,这种实现方式,能够保持视图层和业务逻辑的分离,提高代码的可维护性和可扩展性。上述代码运行结果如图7-3所示。http://localhost:8080/ch07/login.jsp图7-3登录表单267.3案例学习:Servlet的应用◆处理登录请求接下来,创建一个名称为LoginServlet.java的Servlet处理登录表单提交的数据。在这个Servlet中将验证用户名和密码,并根据验证结果重定向到不同的页面。代码如清单7-5所示。277.3案例学习:Servlet的应用(清单7-5LoginServlet.java)1/2packagecom.example.ch07;importjava.io.IOException;importjakarta.servlet.ServletException;importjakarta.servlet.annotation.WebServlet;importjakarta.servlet.http.HttpServlet;importjakarta.servlet.http.HttpServletRequest;importjakarta.servlet.http.HttpServletResponse;/***登录处理Servlet*使用@WebServlet注解配置访问路径为"/login"*注意:实际生产环境应使用数据库存储凭证信息*/@WebServlet("/login")publicclassLoginServletextendsHttpServlet{//序列化ID,用于保证序列化/反序列化的兼容性privatestaticfinallongserialVersionUID=1L;//硬编码的凭证信息(用于演示),注意:实际开发应使用前面所学的数据库存储,并且密码加密存储。privatestaticfinalStringUSERNAME="admin";privatestaticfinalStringPASSWORD="password";/***处理POST请求(登录表单提交)*@paramrequest包含客户端请求信息的HttpServletRequest对象287.3案例学习:Servlet的应用(清单7-5LoginServlet.java)2/2*@paramresponse用于构建服务器响应的HttpServletResponse对象*/protectedvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{//从请求参数中获取用户输入的凭证(注意:参数可能为null)Stringusername=request.getParameter("username");Stringpassword=request.getParameter("password");System.out.println("doPost()");//控制台日志(实际项目建议使用日志框架)//凭证验证逻辑if(USERNAME.equals(username)&&PASSWORD.equals(password)){//验证成功:重定向到success.jsp(客户端跳转,地址栏变化)response.sendRedirect("success.jsp");}else{//验证失败处理://1.设置错误信息到请求属性(仅在当前请求有效)request.setAttribute("error","Invalidusernameorpassword");//2.转发到error.jsp(服务器端跳转,地址栏不变)//注意:error.jsp需要通过${error}获取错误信息request.getRequestDispatcher("error.jsp").forward(request,response);}}}297.3案例学习:Servlet的应用上述Servlet重写了doPost方法,专门处理来自login.jsp表单的method="post"请求。代码的核心是if...else逻辑:1)验证成功:调用response.sendRedirect("success.jsp")。这是一个浏览器跳转(客户端重定向),浏览器的地址栏会变为success.jsp,并且request对象中的数据会丢失。2)验证失败:调用request.getRequestDispatcher("error.jsp").forward()。这是一个服务端跳转(请求转发),浏览器的地址栏保持不变(仍然是/login),但服务器内部会将request和response对象转发给error.jsp处理。另外,通过request.setAttribute()传递的错误消息也因此得以保留。◆创建成功和错误页面需要创建两个JSP页面:其中success.jsp页面用于显示登录成功的消息,另外error.jsp页面用于显示登录错误的消息。success.jsp页面代码如清单7-6所示。307.3案例学习:Servlet的应用(清单7-6success.jsp)<%@pagelanguage="java"contentType="text/html;charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPEhtml><html><head><title>Success</title></head><body><h2>登录成功</h2><p>Welcome,user!</p></body></html>317.3案例学习:Servlet的应用上述代码运行后,凭证验证通过后,Servlet重定向至success.jsp,页面显示欢迎信息,显示结果如图7-4所示。图7-4登录成功页面327.3案例学习:Servlet的应用(清单7-7error.jsp)

error.jsp页面代码如清单7-7所示。<%@pagecontentType="text/html;charset=UTF-8"language="java"%><html><head><title>Error</title></head><body><h2>登录失败</h2><p><%=request.getAttribute("error")%></p><ahref="login.jsp">TryAgain</a></body></html>337.3案例学习:Servlet的应用上述代码运行结果如图7-5所示。图7-5登录失败页面347.3案例学习:Servlet的应用◆部署和测试最后,将Web应用程序部署到Tomcat中,并通过浏览器访问登录表单页面。输入用户名和密码,然后提交表单以测试登录功能。【注意】上述代码中的用户名和密码是硬编码的,仅用于演示。在实际应用中,应该使用数据库存储用户凭据,并使用加密技术保护密码。读者可以根据前面所学的数据库连接技术,将表单改进为与数据库连接的形式进行密码验证。此外,还应该考虑添加其他安全措施,如防止暴力破解攻击(例如,通过限制登录尝试次数、添加验证码和记录登录IP等)。357.4JSP与Servlet前面所学的JSP,实际上是Servlet的一种高级抽象或特殊形式。在JSP页面首次请求时,Tomcat会将JSP页面编译为一个Servlet类,然后执行该Servlet类生成页面内容。因此,JSP页面在本质上是一个Servlet实例。

JSP和Servlet在JavaWeb开发中经常一起使用,协同工作实现动态网页的生成和交互。通常,Servlet用于处理请求、执行业务逻辑和数据访问,而JSP用于呈现最终的HTML页面,实现了前后端分离。367.4.1JSP编译过程分析当通过浏览器访问某个JSP页面时,容器将基于Java环境,编译JSP文件生成对应的class文件,如图7-6所示。图7-6

JSP编译过程377.4.1JSP编译过程分析本章实例中的login.jsp,经过转译生成login_jsp.java,然后编译成login_jsp.class文件,存储在Tomcat主目录下的work子目录下。通过执行Java的class文件,动态生成html文本,最后利用HTTP协议返回至浏览器,如图7-7所示。图7-7JSP编译生成的文件【注意】如果使用的是IntelliJIDEA,这个work目录通常位于IDEA的项目缓存区(.../system/tomcat/...),而不是Tomcat的安装目录。387.4.2JSP编译为Servlet经过部署和访问后,打开转译login.jsp后得到的login_jsp.java(Tomcat主目录\work\Catalina\localhost\_\org\apache\jsp\login_jsp.java),如图7-8所示,可以发现它继承了org.apache.jasper.runtime.HttpJspBase,而HttpJspBase继承类jakarta.servlet.http.HttpServlet。所以,hello_jsp.java是一个Servlet。图7-8login_jsp-java代码内容【注意】在IntelliJIDEA开发环境中,Tomcat主目录通过是指IntelliJIDEA工作空间中,一个名称为“tomcat”的子目录,而非Tomcat实际解压的主目录。397.5.1使用连接池访问数据库在实际应用中,为了提高数据库连接的效率和性能,通常会使用数据库连接池管理数据库连接。连接池能够复用数据库连接,避免每次操作都创建和销毁连接所带来的开销。HikariCP、ApacheDBCP和C3P0都是流行的Java数据库连接池库,可以根据项目需求选择合适的库并进行配置。下面将演示如何在Java中使用连接池连接MySQL数据库。◆引入依赖首先,需要确保项目中包含必要的依赖。对于Maven项目,需要在pom.xml中引入MySQLJDBC驱动和连接池库(如ApacheDBCP、HikariCP或C3P0)的依赖。使用ApacheDBCP的依赖信息如清单7-8所示。407.5.1使用连接池访问数据库(清单7-8pom.xml)...<dependencies>...<!--MySQLJDBCDriver--><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.0.33</version></dependency><!--ApacheDBCP--><dependency><groupId>mons</groupId><artifactId>commons-dbcp2</artifactId><version>2.9.0</version></dependency>...</dependencies>...417.5.1使用连接池访问数据库(清单7-9MySQLPoolServlet.java)1/4◆配置连接池清单7-9所示的代码是使用ApacheDBCP连接池配置的Servlet实例。packagecom.example.ch07;importjakarta.servlet.ServletException;importjakarta.servlet.annotation.WebServlet;importjakarta.servlet.http.HttpServlet;importjakarta.servlet.http.HttpServletRequest;importjakarta.servlet.http.HttpServletResponse;importmons.dbcp2.BasicDataSource;importjava.io.IOException;importjava.sql.Connection;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;/***使用数据库连接池的MySQL查询Servlet示例*功能说明:*1.通过DBCP2连接池管理数据库连接*2.处理GET请求查询students表数据*3.演示连接池配置参数*4.返回纯文本格式的查询结果*/@WebServlet("/mysqlpool")publicclassMySQLPoolServletextendsHttpServlet{427.5.1使用连接池访问数据库(清单7-9MySQLPoolServlet.java)2/4//使用DBCP2连接池privatestaticBasicDataSourcedataSource;@OverrideprotectedvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{try{//显式加载MySQL驱动(JDBC4.0+可自动加载,此处为兼容旧版本)Class.forName("com.mysql.cj.jdbc.Driver");}catch(ClassNotFoundExceptione){thrownewServletException("MySQLJDBCDrivernotfound",e);}//使用try-with-resources自动关闭资源try(Connectionconn=getConnection();Statementstmt=conn.createStatement();ResultSetrs=stmt.executeQuery("SELECT*FROMstudents")){//设置响应格式(建议移到循环外以提高效率)resp.setCharacterEncoding("UTF-8");resp.setContentType("text/plain");//遍历结果集while(rs.next()){//获取学生姓名列Stringname=rs.getString("name");437.5.1使用连接池访问数据库(清单7-9MySQLPoolServlet.java)3/4resp.getWriter().println("Column1:"+name);//可扩展处理其他列...}}catch(SQLExceptione){//生产环境应记录日志并返回友好错误提示thrownewServletException("Databaseerror",e);}}//静态初始化块配置连接池static{dataSource=newBasicDataSource();//数据库连接配置dataSource.setUrl("jdbc:mysql://localhost:3306/university");dataSource.setUsername("root");dataSource.setPassword("root");//连接池参数配置dataSource.setInitialSize(2);//初始连接数dataSource.setMaxTotal(10);//最大活动连接数dataSource.setMinIdle(2);//最小空闲连接dataSource.setMaxIdle(10);//最大空闲连接dataSource.setMaxWaitMillis(30000);//获取连接最大等待时间(30秒)}447.5.1使用连接池访问数据库(清单7-9MySQLPoolServlet.java)4/4/***从连接池获取数据库连接*@return可用的数据库连接*@throwsSQLException当连接池耗尽或数据库不可用时*/publicstaticConnectiongetConnection()throwsSQLException{returndataSource.getConnection();}}457.5.1使用连接池访问数据库上述代码是一个基于DBCP2连接池技术的高效MySQL数据库查询Servlet,通过注解配置为“/mysqlpool”访问端点,在初始化时建立具备连接复用能力的数据库连接池,当处理GET请求时会自动从连接池获取连接并执行students表的查询操作,将学生姓名以纯文本格式流式输出到客户端,同时通过完善的异常处理机制确保数据库操作的稳定性和资源管理的可靠性。467.5.1使用连接池访问数据库◆运行代码确保MySQL数据库正在运行,并且数据库、用户名和密码等信息正确无误。然后运行上述代码,它将连接到MySQL数据库并查询数据。运行结果如图7-9所示。http://localhost:8080/ch07/mysqlpool图7-9使用连接池查询结果477.5.2使用PreparedStatement语句在JDBC中使用PreparedStatement进行查询是一种推荐的做法,因为它不仅可以提高性能(通过预编译SQL语句和缓存实现),还可以防止SQL注入攻击。下面将演示如何使用PreparedStatement进行查询。◆获取数据库连接首先,需要获取一个数据库连接。通常是通过数据源(如连接池)或DriverManager完成的。这个步骤和前面的Statement语句是一样的,目的都是获得一个Connection对象。例如:487.5.2使用PreparedStatement语句(代码示例)//设置驱动Class.forName("com.mysql.cj.jdbc.Driver");//连接数据库Stringurl="jdbc:mysql://:3306/university";//数据库URL,数据库名为universityStringusername="root";//数据库用户名Stringpassword="root";//数据库密码Connectionconnection=DriverManager.getConnection(url,username,password);497.5.2使用PreparedStatement语句◆创建PreparedStatement对象使用连接对象的prepareStatement()方法,并传入一个带有占位符(通常是半角问号“?”)的SQL查询语句。例如:Stringsql="SELECT*FROMyour_tableWHEREcolumn1=?";PreparedStatementpreparedStatement=connection.prepareStatement(sql);507.5.2使用PreparedStatement语句◆设置参数通过PreparedStatement的setXxx方法(其中Xxx代表数据类型,如setInt、setString等)为SQL语句中的占位符设置值。例如://设置参数preparedStatement.setString(1,"some_value");517.5.2使用PreparedStatement语句◆执行查询调用PreparedStatement的executeQuery()方法执行查询,并返回一个ResultSet对象。例如://执行查询ResultSetresultSet=preparedStatement.executeQuery();527.5.2使用PreparedStatement语句(代码示例)◆处理结果集遍历ResultSet对象以获取查询结果。例如:while(resultSet.next()){//假设有一列名为"column2",其数据类型为VARCHARStringcolumn2Value=resultSet.getString("column2");System.out.println("Column2Value:"+column2Value);}537.5.2使用PreparedStatement语句(代码示例)◆关闭资源最后,确保关闭ResultSet、PreparedStatement和Connection对象以释放数据库资源。例如:if(resultSet!=null)resultSet.close();if(preparedStatement!=null)preparedStatement.close();if(connection!=null)connection.close();【注意】如果使用try-with-resources,即可省略关闭资源这一步骤。547.5.3实例:PreparedStatement的应用清单7-10所示的代码通过结合Servlet和PreparedStatement对象从MySQL数据库中的students表查询student_id为“00002”的记录,并将查询结果中的name列值输出到HTTP响应中,同时打印到控制台。557.5.3实例:PreparedStatement的应用(清单7-10PreparedStatementServlet.java)1/3packagecom.example.ch07;importjakarta.servlet.ServletException;importjakarta.servlet.annotation.WebServlet;importjakarta.servlet.http.HttpServlet;importjakarta.servlet.http.HttpServletRequest;importjakarta.servlet.http.HttpServletResponse;importjava.io.IOException;importjava.sql.*;/***使用PreparedStatement防止SQL注入的Servlet示例*功能说明:*1.处理GET请求,演示参数化查询*2.连接MySQL数据库查询学生信息*3.展示结果集处理和资源安全释放*/@WebServlet("/preparedStatement")publicclassPreparedStatementServletextendsHttpServlet{@OverrideprotectedvoiddoGet(HttpServletRequestreq,HttpServletResponseresp)throwsServletException,IOException{//声明数据库资源(JDBC规范要求在finally中关闭)Connectionconnection=null;567.5.3实例:PreparedStatement的应用(清单7-10PreparedStatementServlet.java)2/3PreparedStatementpreparedStatement=null;ResultSetresultSet=null;try{//1.加载数据库驱动(JDBC4.0+可自动加载,此处显式声明保证兼容性)Class.forName("com.mysql.cj.jdbc.Driver");//2.配置数据库连接参数StringjdbcUrl="jdbc:mysql://localhost:3306/university";Stringusername="root";Stringpassword="root";//3.建立数据库连接connection=DriverManager.getConnection(jdbcUrl,username,password);//4.创建参数化查询语句(使用问号?作为占位符)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论