[Java Web]Java Servlet基础 - 指南
一、Servlet对象到底是啥?
Servlet对象其实就是一个“处理用户请求的小帮手”。当你用浏览器访问一个网站时,背后其实是有一个服务器在处理你发的请求,这个服务器通过Servlet对象来“理解”你的请求,然后给你一个合适的回复。
二、Servlet对象的作用:
接收请求:比如你填了一个表单,点击提交,表单里的数据就通过HTTP请求发到服务器。这时,Servlet对象就会接收到这些请求内容。
生成响应:它会根据你发过来的请求生成响应内容。比如,显示一个页面,或者返回一些数据(比如JSON格式的返回),然后再发送给你。
与用户交互:Servlet可以根据用户的输入做很多事情,比如查询数据库、处理登录信息、判断你是不是登录了,等等。
管理会话:比如你登录了一个网站,接下来的每次请求,服务器都要知道你已经登录了。Servlet对象可以通过Session来记住这些信息,让你不需要每次都重新登录。
三、Servlet对象是怎么工作的?
初始化:第一次访问这个Servlet时,容器(比如Tomcat)会帮你创建这个Servlet对象,并调用它的
init()方法来做一些准备工作。处理请求:当你发送请求时,Servlet会处理它。它根据请求的类型(比如你是用GET请求还是POST请求)来调用不同的方法(比如
doGet()或者doPost())。销毁:当服务器不需要再用这个Servlet时,Servlet对象会被销毁,调用它的
destroy()方法来释放资源。举个简单的例子:
假设你访问一个叫做/greeting的页面,URL是/greeting?name=John,Servlet对象就会:
获取你传来的
name参数(比如你传了John),然后根据这个信息给你返回一段话:“Hello, John!”
四、doGet() 和 doPost()
1. 什么是 doGet() 和 doPost()?
doGet() 和 doPost() 是 HttpServlet 类的两个方法,它们用来处理 HTTP请求。HTTP请求有很多类型,其中最常见的就是 GET请求 和 POST请求。
GET请求:用于获取数据,通常是从服务器获取信息。
POST请求:用于提交数据,通常是向服务器发送数据,比如提交表单、上传文件等。
2. 这两个方法分别干什么?
doGet():用于处理 GET请求。通常用于获取数据。比如,访问网页、获取某些信息等。doPost():用于处理 POST请求。通常用于提交数据,比如提交表单信息、上传文件等。
3. 代码
我们来看看这个例子:
@WebServlet("/example")
public class ExampleServlet extends HttpServlet {
// 处理GET请求
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("GET request received");
}
// 处理POST请求
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("POST request received");
}
}
3.1 代码解析:
@WebServlet("/example"):这个注解是用来配置Servlet的,告诉服务器,当访问/example这个路径时,应该调用ExampleServlet类来处理请求。doGet()方法:这个方法会处理所有到
/example路径的 GET请求。response.getWriter().println("GET request received");这行代码告诉服务器,返回“GET request received”给客户端(浏览器)。也就是浏览器发起 GET 请求后,页面会显示 "GET request received"。
doPost()方法:这个方法会处理所有到
/example路径的 POST请求。response.getWriter().println("POST request received");这行代码告诉服务器,返回“POST request received”给客户端。
3.2 举个例子:
假设你有一个网页,这个网页可以发送两种类型的请求:
GET请求:浏览器打开这个网页时,发送的是 GET请求,通常是获取网页内容。
POST请求:当用户提交表单时,通常会发送 POST请求,用于提交表单数据到服务器。
3.2.1 GET请求的情况:
用户在浏览器中访问:http://localhost:8080/example
浏览器会发送一个 GET请求 到
/example路径。服务器接收到 GET请求 后,会调用
doGet()方法,并返回“GET request received”。浏览器页面显示:
GET request received
3.2.2 POST请求的情况:
用户提交了一个表单(例如,一个名字字段)到服务器:
当用户点击提交按钮时,表单数据通过 POST请求 发送到
/example。服务器接收到 POST请求 后,会调用
doPost()方法,并返回“POST request received”。浏览器页面显示:
POST request received
4. 关键区别:
GET请求:常用于获取数据,如在浏览器中访问网页。
POST请求:常用于提交数据,如提交表单、上传文件等。
5. 为什么要区分 doGet() 和 doPost()?
因为这两种请求处理的逻辑通常不同:
GET请求通常用于获取内容,不会改变服务器的数据。
POST请求通常用于提交数据,可能会改变服务器的数据(比如存储用户提交的信息)。
6. 综上:
doGet():处理从浏览器发送的 GET请求(获取数据)。doPost():处理从浏览器发送的 POST请求(提交数据)。
五、如何使用Servlet对象?
点击链接跳转到Servlet对象的使用https://blog.csdn.net/2302_80281315/article/details/156022906?fromshare=blogdetail&sharetype=blogdetail&sharerId=156022906&sharerefer=PC&sharesource=2302_80281315&sharefrom=from_linkhttps://blog.csdn.net/2302_80281315/article/details/156022906?fromshare=blogdetail&sharetype=blogdetail&sharerId=156022906&sharerefer=PC&sharesource=2302_80281315&sharefrom=from_linkhttps://blog.csdn.net/2302_80281315/article/details/156022906?fromshare=blogdetail&sharetype=blogdetail&sharerId=156022906&sharerefer=PC&sharesource=2302_80281315&sharefrom=from_link
1、写Servlet类
首先,你要写一个Servlet类,这个类需要继承自HttpServlet(或者实现Servlet接口)。这是你实现逻辑的地方。
我们从简单的Servlet类开始。比如说,创建一个简单的Servlet,它会处理一个/greeting的请求,输出一段欢迎文字。
@WebServlet("/greeting") // 这行注解说明这个Servlet会处理/greeting这个路径的请求
public class GreetingServlet extends HttpServlet {
// 处理GET请求
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取用户请求的参数,这里假设用户访问的URL是/greeting?name=John
String name = request.getParameter("name");
// 设置响应内容类型
response.setContentType("text/html");
// 返回欢迎消息,假设用户传入的参数是John
response.getWriter().println("Hello, " + name + "!
");
}
}
这个代码的意思是:
name = request.getParameter("name");:这一行会从用户的请求中获取name参数的值,比如如果用户访问/greeting?name=John,那么name的值就是John。如果用户没有提供name参数,name的值会是null。response.setContentType("text/html");:这行代码设置响应的内容类型为text/html,表示服务器将返回HTML格式的响应。response.getWriter().println("<h1>Hello, " + name + "!</h1>");:这行代码会根据获取到的name值生成HTML内容。如果用户提供了name=John,它就会显示“Hello, John!”。
2、配置Servlet
你可以通过两种方式配置Servlet,让服务器知道它是什么、怎么处理请求。
2.1 步骤 2:配置Servlet
2.1.1 什么是配置Servlet?
配置Servlet指的是告诉Web服务器(如Tomcat)如何找到和使用你的Servlet,并指定该Servlet处理哪些URL请求。Servlet本身是一个Java类,它需要通过配置来告诉服务器在何时、如何调用它。
Servlet配置的目的就是让服务器知道:
这个Servlet类是什么?
当访问某个URL时,应该调用哪个Servlet类来处理请求?
2.1.2 配置Servlet的方式
在Java Web应用中,配置Servlet有两种常见的方式:
1. 使用注解配置Servlet(推荐方式)
从Servlet 3.0版本开始,Java引入了注解,可以通过注解直接在Servlet类中配置Servlet,这种方式简单且不需要修改web.xml配置文件。
例如:
@WebServlet("/greeting")
public class GreetingServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("name");
response.setContentType("text/html");
response.getWriter().println("Hello, " + name + "!
");
}
}
在这个例子中,@WebServlet("/greeting")是注解,它的作用是告诉Servlet容器,当访问URL路径/greeting时,就调用GreetingServlet这个Servlet类来处理请求。
优点:不需要修改web.xml文件,配置更加简洁。
2. 使用web.xml配置(传统方式)
在没有注解时,配置Servlet是通过在web.xml文件中进行配置的。web.xml是Web应用的配置文件,位于WEB-INF文件夹下。
例如,配置Servlet时,可以在web.xml文件中指定Servlet类及其对应的URL模式:
GreetingServlet
com.example.GreetingServlet
GreetingServlet
/greeting
这段配置的意思是:
<servlet-name>:指定Servlet的名字,GreetingServlet是名字。<servlet-class>:指定Servlet的类名,即com.example.GreetingServlet。<url-pattern>:指定访问该Servlet的URL路径,这里是/greeting。
优点:这种方式更加灵活,适合需要更复杂配置的场景。
2.1.3 什么时候用配置Servlet?
你需要配置Servlet的时候通常是:
处理特定请求:例如你想处理
/login、/register等路径的请求,Servlet可以指定这些路径,Servlet就会处理这些路径的请求。定义Servlet行为:你可以通过配置不同的Servlet,来让它们处理不同的功能模块,比如一个Servlet处理用户登录,另一个处理数据查询等。
总的来说,配置Servlet就是告诉服务器如何找到并使用Servlet类来处理特定的请求,可以通过注解(简单方便)或者在web.xml文件中进行配置(更加灵活)。
2.2.3 步骤 3:访问Servlet
启动服务器:启动你的Web服务器(比如Tomcat)。
访问Servlet:在浏览器中输入:
http://localhost:8080/your-web-app/greeting?name=John这时,你就能看到“Hello, John!”的欢迎信息。
3、处理请求
在Servlet类里,你要定义方法,来处理用户发来的不同请求(如GET请求、POST请求)。
3.1 步骤 4:处理不同请求
在Java Servlet中,当浏览器发起不同类型的请求时,Servlet需要根据请求的类型(比如GET或POST)来做出响应。doGet()方法处理的是GET请求,doPost()方法处理的是POST请求。
具体的代码解析:
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取POST请求的数据
String message = request.getParameter("message");
// 处理这个消息
response.getWriter().println("Message received: " + message);
}
@Override:这个注解是告诉Java编译器,我们重写了父类(HttpServlet)的doPost()方法。也就是说,我们告诉服务器:如果收到POST请求,应该执行这个方法。protected void doPost(HttpServletRequest request, HttpServletResponse response):这是一个方法定义。doPost()方法专门用来处理客户端(比如浏览器)发来的POST请求。HttpServletRequest request:request是一个对象,它包含了客户端发来的请求数据,包括表单数据、URL参数等。HttpServletResponse response:response是一个对象,我们用它来设置服务器要返回给客户端的数据。
String message = request.getParameter("message");:这里我们从客户端的请求中获取message这个参数。假设浏览器通过POST请求发送了一个表单,表单中有一个字段叫message,这行代码就把message字段的值提取出来并存储在message变量中。response.getWriter().println("Message received: " + message);:这一行代码将message的值返回给客户端。在浏览器中,服务器会显示“Message received: [你提交的消息]”。
3.2 举个更详细的例子
假设我们现在有一个简单的Web应用,用户可以在页面上输入一个消息,点击提交按钮,服务器处理这个消息后,再将处理结果显示给用户。
3.2.1 步骤 1:HTML页面(前端)
我们创建一个HTML表单,让用户输入消息并提交给服务器。
Message Form
Enter your message
<form action="/myServlet" method="POST">:这个表单将会通过POST方法提交数据到/myServlet路径(也就是你的Servlet的路径)。<input type="text" name="message" />:这个输入框让用户填写消息,name="message"会将这个字段的数据作为message参数提交。<input type="submit" value="Submit" />:点击这个按钮会提交表单。
3.2.2 步骤 2:Servlet(后端)
服务器端处理用户的请求并返回响应。我们在Servlet中处理POST请求,获取用户填写的消息,然后将处理后的内容返回给用户。
@WebServlet("/myServlet")
public class MyServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取用户通过POST提交的消息
String message = request.getParameter("message");
// 设置响应内容类型
response.setContentType("text/html");
// 将接收到的消息返回给客户端
response.getWriter().println("Message received: " + message + "
");
}
}
request.getParameter("message"):这行代码从用户提交的表单中获取message字段的内容(就是用户输入的消息)。response.getWriter().println("<h1>Message received: " + message + "</h1>");:这行代码将用户输入的消息显示出来,response.getWriter()是用来将响应数据写回客户端的。
3.2.3 步骤 3:整个流程
用户打开表单页面(HTML页面),看到一个输入框,提示他们输入消息。
用户在输入框里输入一些文字(比如
Hello, Servlet!),然后点击“Submit”按钮。用户提交表单后,浏览器会通过POST请求将
message=Hello, Servlet!发送到服务器上的/myServlet路径。服务器接收到请求后,调用
doPost()方法,获取请求中的message参数(就是用户输入的内容)。Servlet将内容处理后,返回一个包含消息的HTML页面:
<h1>Message received: Hello, Servlet!</h1>,并显示给用户。
3.3 以上的流程可总结为:
用户填写表单并点击提交按钮,浏览器将数据通过POST请求发送给服务器。
服务器接收到请求后,通过
request.getParameter("message")获取用户输入的数据。服务器返回一段HTML内容给浏览器,告诉用户他们的消息已被接收。
3.4 最终效果:
当用户提交表单后,浏览器页面显示:
Message received: Hello, Servlet!
这个过程就是POST请求和Servlet处理过程的一个完整示例,通过这种方式,浏览器和服务器就可以进行交互,用户输入的内容被传递到服务器并返回处理后的结果。
4. 使用Servlet类的总的流程:
写Servlet类:继承
HttpServlet并重写doGet()或doPost()来处理请求。配置Servlet:你可以通过注解(推荐)或者
web.xml来配置。访问Servlet:通过浏览器或者其他HTTP客户端访问Servlet,服务器会调用相应的方法来处理。
Servlet对象基本就这些,核心是:它就是用来接收请求、处理逻辑并生成响应的。
六、Servlet的生命周期
Servlet的生命周期由Servlet容器管理,主要包括以下几个阶段:
初始化阶段:当Servlet被第一次加载时,容器调用Servlet的
init()方法进行初始化。这个方法只会执行一次。服务阶段:每次收到请求时,容器调用Servlet的
service()方法,该方法根据请求类型(GET或POST)调用对应的doGet()或doPost()方法。销毁阶段:当Servlet被卸载或容器关闭时,容器调用Servlet的
destroy()方法。这个方法通常用于释放资源。
七、重定向和转发
1. 重定向(Redirect)
重定向是当你想要让用户浏览器去访问一个新的地址时,用来实现的操作。就像你对浏览器说:“去这个新地址看看吧!”
工作原理:当你调用
response.sendRedirect()时,服务器会告诉浏览器,“重新发一个请求,去访问另一个页面。”浏览器会重新向新地址发起请求。结果:浏览器的地址栏会显示新的URL,并且浏览器会重新发送一个请求。
1.1 举个例子:
假设你有一个在线商店,当用户点击“结账”按钮时,你需要确保用户已经登录。如果用户没有登录,你会将他们重定向到登录页面。
1.1.1 场景:
用户点击了“结账”按钮。
服务器需要检查用户是否已登录。
如果用户未登录,服务器会执行
response.sendRedirect("login.jsp");,将用户重定向到登录页面。浏览器的地址栏会显示新的URL——
login.jsp,然后浏览器会向服务器发出新的请求加载登录页面。
1.1.2 代码示例:
@WebServlet("/checkout")
public class CheckoutServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 假设用户未登录
boolean isLoggedIn = false; // 模拟未登录的状态
if (!isLoggedIn) {
// 重定向到登录页面
response.sendRedirect("login.jsp");
} else {
// 如果用户已登录,继续结账流程
response.getWriter().println("Proceed to checkout...");
}
}
}
1.1.3 过程:
用户访问
/checkout页面。服务器检查用户是否登录,如果没有登录,执行
response.sendRedirect("login.jsp");。浏览器重新发送请求到
login.jsp,并加载登录页面。浏览器的地址栏变为
login.jsp,用户看到的是登录页面。
注意:response.sendRedirect() 会导致浏览器发出新的请求,地址栏会发生变化,浏览器重新加载新的页面。它适合用来跳转到完全不同的页面。
2. 转发(Forward)
转发则与重定向不同,它是完全在服务器端处理的,浏览器的地址栏并不会发生变化。也就是说,浏览器并没有重新发请求,而是服务器告诉浏览器,“继续处理这个请求,但是交给别的资源来做。”
工作原理:当你调用
RequestDispatcher.forward()时,服务器会把请求转交给另一个资源(可能是另一个Servlet或JSP页面),但浏览器并不会感知到这个过程。浏览器的URL依旧不变。结果:浏览器的地址栏不变,仍然显示最初的请求URL。
2.1 举个例子:
假设你有一个用户个人信息页面,用户访问 /userInfo 页面时,服务器需要检查用户是否登录。如果没有登录,服务器会转发请求到一个错误页面(errorPage.jsp)。用户仍然会看到原来访问的 /userInfo 页面,浏览器的URL不变。
2.1.1 场景:
用户访问
/userInfo页面。服务器检查用户是否已登录。
如果未登录,服务器执行
RequestDispatcher.forward(request, response);,将请求转发到errorPage.jsp页面。浏览器的地址栏仍然是
/userInfo,但显示的是errorPage.jsp页面。
2.1.2 代码示例:
@WebServlet("/userInfo")
public class UserInfoServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 假设用户未登录
boolean isLoggedIn = false; // 模拟未登录的状态
if (!isLoggedIn) {
// 转发到错误页面
RequestDispatcher dispatcher = request.getRequestDispatcher("errorPage.jsp");
dispatcher.forward(request, response);
} else {
// 如果用户已登录,显示用户信息
response.getWriter().println("Welcome to your profile!");
}
}
}
2.1.3 过程:
用户访问
/userInfo页面。服务器检查用户是否登录,如果没有登录,执行
RequestDispatcher.forward(request, response);,将请求转发到errorPage.jsp。浏览器的地址栏不会变化,依然是
/userInfo,但是用户看到的是errorPage.jsp页面,告诉他们需要登录才能查看个人信息。
注意:RequestDispatcher.forward() 会让服务器内部将请求转发到另一个页面,而不会更改浏览器的地址栏。适用于需要在服务器内部处理多个资源的场景,比如验证、处理、显示等。
3. 重定向与转发的区别对比
| 特点 | 重定向 (sendRedirect) | 转发 (forward) |
|---|---|---|
| 发生位置 | 客户端(浏览器)发起新的请求 | 服务器内部操作 |
| 浏览器地址栏变化 | 是,浏览器会重新加载新的URL | 否,浏览器地址栏不变 |
| 请求是否重新发送 | 是,浏览器会发送一个新的请求 | 否,服务器直接处理请求 |
| 用途 | 适用于需要改变URL或者引导用户到其他页面的场景,比如登录验证后跳转到主页。 | 适用于服务器内部的处理,不需要改变URL的跳转,比如从一个Servlet转发到另一个JSP页面。 |
八、登录验证实践
在很多Web应用中,用户需要登录才能访问某些页面。登录验证通常需要使用重定向和转发来控制页面的跳转。
场景设定
假设你正在开发一个在线商店网站,在这个网站上,只有登录的用户才能访问“结账页面”和“用户主页”。如果用户未登录,访问这些页面时需要转到登录页面;如果已经登录,用户应该被重定向到他们的主页。
1. 用户未登录:转发到登录页面
当用户访问需要登录才能访问的页面(比如结账页面或用户主页),如果他们没有登录,你需要将他们转发到登录页面。
使用转发的原因:当用户没有登录时,你可以将他们转发到登录页面,告诉他们需要登录。这个过程不改变浏览器的地址栏,用户看到的还是原始的请求URL。
1.1 具体步骤:
用户尝试访问结账页面(比如
/checkout)。服务器检查用户是否已经登录。
如果用户未登录,服务器将请求转发到
login.jsp页面。
1.2 代码示例:
@WebServlet("/checkout")
public class CheckoutServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 假设这里检查用户是否登录
boolean isLoggedIn = false; // 模拟用户未登录的情况
if (!isLoggedIn) {
// 用户未登录,转发到登录页面
RequestDispatcher dispatcher = request.getRequestDispatcher("login.jsp");
dispatcher.forward(request, response);
} else {
// 用户已登录,继续处理结账逻辑
response.getWriter().println("Proceed to checkout...");
}
}
}
1.3 过程:
用户访问
/checkout路径。服务器发现用户未登录,执行
request.getRequestDispatcher("login.jsp").forward(request, response)。服务器将请求转发到
login.jsp页面。浏览器的地址栏不变,仍然是
/checkout,但显示的是login.jsp页面。
1.4 何时使用转发:
用户未登录时,通过转发引导用户去登录页面,而浏览器地址栏仍然显示原始的请求地址。
转发是服务器内部操作,因此用户不知道跳转的过程。
2. 用户已登录:重定向到用户主页
当用户登录成功后,应该引导他们访问个人主页或者其他页面,重定向是此时的合适选择。重定向会告诉浏览器去访问一个新的URL,浏览器地址栏的URL会改变。
2.1 具体步骤:
用户成功登录。
服务器通过
response.sendRedirect()将用户重定向到用户主页(比如userHome.jsp)。浏览器的地址栏会显示
userHome.jsp,然后浏览器会发起一个新的请求加载用户主页。
2.2 代码示例:
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取用户登录信息
String username = request.getParameter("username");
String password = request.getParameter("password");
// 假设用户登录验证通过
boolean isValidUser = true; // 模拟登录验证成功
if (isValidUser) {
// 登录成功,重定向到用户主页
response.sendRedirect("userHome.jsp");
} else {
// 登录失败,转发到错误页面或显示错误信息
request.setAttribute("errorMessage", "Invalid credentials!");
RequestDispatcher dispatcher = request.getRequestDispatcher("login.jsp");
dispatcher.forward(request, response);
}
}
}
2.3 过程:
用户通过POST请求提交登录信息。
如果登录成功,
response.sendRedirect("userHome.jsp");会让浏览器发起新的请求到userHome.jsp。浏览器的地址栏会变成
userHome.jsp,并加载用户主页。
2.4 何时使用重定向:
用户登录成功后,你想让浏览器跳转到另一个页面(比如用户主页),并且浏览器的地址栏需要更新。
重定向是客户端操作,因此浏览器会重新发起请求,地址栏的URL会改变。
3. 综合示例:一个完整的登录验证和页面跳转
让我们来看一个综合的例子,这个例子结合了转发和重定向。
3.1 登录流程:
用户访问结账页面
/checkout。如果用户没有登录,服务器会将请求转发到登录页面
login.jsp。用户填写用户名和密码,点击登录按钮。
服务器检查登录信息,如果正确,重定向到用户主页
userHome.jsp。
3.2 代码实现:
@WebServlet("/checkout")
public class CheckoutServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 假设检查用户登录状态
boolean isLoggedIn = false; // 用户未登录
if (!isLoggedIn) {
// 如果用户未登录,转发到登录页面
RequestDispatcher dispatcher = request.getRequestDispatcher("login.jsp");
dispatcher.forward(request, response);
} else {
// 如果用户已登录,继续处理结账
response.getWriter().println("Proceed to checkout...");
}
}
}
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
// 假设这里进行登录验证
boolean isValidUser = true; // 用户验证通过
if (isValidUser) {
// 登录成功,重定向到用户主页
response.sendRedirect("userHome.jsp");
} else {
// 登录失败,转发回登录页面并显示错误
request.setAttribute("errorMessage", "Invalid credentials!");
RequestDispatcher dispatcher = request.getRequestDispatcher("login.jsp");
dispatcher.forward(request, response);
}
}
}
3.3 说明:
未登录用户:访问
/checkout时会被转发到login.jsp,浏览器的地址栏不变。登录用户:登录成功后,通过
response.sendRedirect("userHome.jsp")重定向到用户主页,浏览器的地址栏变为userHome.jsp。
4. 总结:
转发:用于将请求从一个资源(如Servlet)转交到另一个资源(如JSP),地址栏不变,通常用于用户未登录时跳转到登录页面。
重定向:用于让浏览器重新发起请求,地址栏会发生变化,通常用于用户登录后跳转到主页。
九、Session(会话)
Session 是用来保存用户的会话数据的,像是“记录”用户的状态(比如登录状态)。它能让你在多个请求之间存储数据。
获取Session:每次请求都会生成一个Session,可以通过
request.getSession()获取。存储数据:比如你想保存一个用户对象,可以用
session.setAttribute("user", userObject);将它存到Session中。获取数据:你可以通过
session.getAttribute("user")获取存储的用户数据。
1. 具体场景:
我们将实现一个简单的登录系统,用户输入用户名和密码后,系统会检查用户的登录状态并进行相应的跳转。
用户未登录:如果用户没有登录,我们通过 Session 保存登录状态,并跳转到欢迎页面。
用户已登录:如果用户已经登录,我们通过 Session 获取存储的用户信息,跳转到用户主页。
2. 实现步骤:
用户登录:用户提交登录表单,Servlet会验证用户名和密码。
使用Session:如果登录成功,用户信息会存储到Session中。
访问受保护页面:如果用户未登录,访问受保护页面时会被重定向到登录页面。
3. 完整代码示例
3.1 登录页面 (login.jsp)
这是一个简单的登录表单,用户在此页面输入用户名和密码。
Login
Login
${errorMessage}
3.2 登录验证 Servlet (LoginServlet.java)
这个Servlet处理用户的登录请求,它会验证用户的用户名和密码,并在验证成功后将用户信息保存到Session中。
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
// 假设用户名是admin,密码是1234
if ("admin".equals(username) && "1234".equals(password)) {
// 登录成功,将用户信息保存到Session
HttpSession session = request.getSession();
session.setAttribute("user", username); // 保存用户名到Session中
// 登录成功后,重定向到用户主页
response.sendRedirect("userHome.jsp");
} else {
// 登录失败,设置错误信息并转发回登录页面
request.setAttribute("errorMessage", "Invalid username or password!");
RequestDispatcher dispatcher = request.getRequestDispatcher("login.jsp");
dispatcher.forward(request, response);
}
}
}
3.3 用户主页 (userHome.jsp)
这是一个简单的用户主页,当用户登录成功后会被重定向到这里。主页会显示欢迎信息。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
User Home
Welcome, ${user}!
This is your home page.
Logout
3.4 检查登录状态 Servlet (CheckLoginServlet.java)
这个Servlet用于在每个受保护的页面访问时检查用户是否已登录。如果用户没有登录,它会重定向到登录页面。
@WebServlet("/checkLogin")
public class CheckLoginServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取Session
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("user") == null) {
// 用户未登录,重定向到登录页面
response.sendRedirect("login.jsp");
} else {
// 用户已登录,继续处理
response.getWriter().println("Welcome to the protected page!");
}
}
}
3.5 登出页面 (logout.jsp)
当用户点击“Logout”链接时,我们会销毁Session,退出登录。
@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取Session并销毁
HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate(); // 销毁Session
}
// 重定向回登录页面
response.sendRedirect("login.jsp");
}
}
4. 完整流程说明:
用户访问登录页面:
用户打开login.jsp页面,输入用户名和密码提交表单。用户登录验证:
LoginServlet接收提交的用户名和密码,如果正确,将用户名保存到 Session 中,重定向到userHome.jsp。检查用户是否已登录:
访问受保护的页面(比如结账页面或用户主页)时,CheckLoginServlet会检查 Session 是否包含有效的用户信息。如果没有,重定向到登录页面。如果已登录,允许访问。用户登出:
用户点击登出按钮,LogoutServlet会销毁当前 Session 并重定向到登录页面。
5. 会话(Session)使用总结:
获取 Session:每个 HTTP 请求都会有一个
HttpSession对象,可以通过request.getSession()获取。存储数据:通过
session.setAttribute("key", value)将数据保存到 Session 中(如保存用户名)。获取数据:通过
session.getAttribute("key")获取存储在 Session 中的数据(如获取用户名)。销毁 Session:通过
session.invalidate()销毁 Session,用户登出时常用。
这样通过 Session 可以实现对用户登录状态的管理,在多次请求之间保持状态,确保只有已登录的用户能够访问某些受保护的页面。
十、MVC模式
MVC(Model-View-Controller)是一种设计模式,用来组织Web应用程序的代码,使其更清晰、易于维护。它把代码分成了三个部分:
Model:处理数据和业务逻辑(比如数据库操作)。
View:负责显示数据(比如网页的界面)。
Controller:接收请求,并决定如何处理这些请求(通常是调用Model和View)。
示例:
假设有一个用户信息的应用:
Model:
User类,封装用户数据。View:一个JSP页面,显示用户的信息。
Controller:一个Servlet,负责处理用户请求,获取用户数据,然后转发到JSP页面显示。
public class UserServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 假设这里是从数据库获取用户数据 User user = new User("John", "Doe"); // 将用户数据存入请求中 request.setAttribute("user", user); // 转发请求到JSP页面 RequestDispatcher dispatcher = request.getRequestDispatcher("user.jsp"); dispatcher.forward(request, response); } }
在 user.jsp 页面,你可以显示用户的信息:
User: ${user.firstName} ${user.lastName}
十一、四则运算实践
假设你想做一个计算器,通过网页来接收两个数字和操作符(加、减、乘、除),然后返回结果。
场景说明
我们需要实现一个可以进行加、减、乘、除运算的计算器,用户输入两个数字和一个运算符(如加、减、乘、除),计算器根据用户的输入进行运算,并返回结果。
步骤:
创建一个 HTML 表单,用户可以在其中输入两个数字和选择运算符。
创建一个 Servlet 来处理用户输入的数据,进行计算,并返回结果。
显示结果到用户的浏览器页面。
1. HTML 表单(calculator.html)
这是一个简单的表单页面,用户可以输入两个数字并选择运算符。
Simple Calculator
Simple Calculator
解释:
num1 和 num2 是用户输入的两个数字。
operation 是一个下拉框,用户可以选择加、减、乘、除。
表单提交时,数据会通过 POST 请求 发送到
/calculate,由我们接下来的 Servlet 来处理。
2. Servlet(CalculatorServlet.java)
这个Servlet负责接收用户提交的数据,根据选择的操作符进行计算,并返回结果。
@WebServlet("/calculate")
public class CalculatorServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取表单数据
int num1 = Integer.parseInt(request.getParameter("num1")); // 获取第一个数字
int num2 = Integer.parseInt(request.getParameter("num2")); // 获取第二个数字
String operation = request.getParameter("operation"); // 获取操作符
int result = 0; // 存储计算结果
// 根据操作符进行不同的计算
switch(operation) {
case "add": // 加法
result = num1 + num2;
break;
case "subtract": // 减法
result = num1 - num2;
break;
case "multiply": // 乘法
result = num1 * num2;
break;
case "divide": // 除法
if(num2 != 0) { // 防止除以0的错误
result = num1 / num2;
} else {
response.getWriter().println("Error: Cannot divide by zero.");
return;
}
break;
default:
response.getWriter().println("Invalid operation.");
return;
}
// 返回计算结果给客户端
response.setContentType("text/html"); // 设置响应类型为HTML
response.getWriter().println("Result: " + result + "
");
}
}
解释:
获取数据:
request.getParameter("num1")和request.getParameter("num2")获取用户输入的两个数字。request.getParameter("operation")获取用户选择的运算符。
计算结果:
我们使用 switch-case 语句来判断用户选择的运算符。
根据选择的操作符,执行相应的四则运算。
返回结果:
response.getWriter().println("<h2>Result: " + result + "</h2>");用来将结果打印在页面上。如果除法操作中 除数为零,我们会返回一个错误信息:“Error: Cannot divide by zero.”
3. 如何工作:
用户访问
calculator.html页面,填写两个数字并选择运算符(如加法)。用户点击“Calculate”按钮,表单提交会发送 POST 请求 到
/calculate。CalculatorServlet会接收到请求,解析出两个数字和操作符。根据用户选择的操作符,执行相应的四则运算。
计算结果通过
response.getWriter()返回到浏览器页面,显示出来。
4. 完整的文件结构:
假设我们有一个简单的项目结构,如下所示:
WebApp/
│
├── WEB-INF/
│ └── web.xml // 这里可以配置Servlet(也可以通过注解配置)
│
├── calculator.html // 前端HTML表单
├── CalculatorServlet.java // 处理计算逻辑的Servlet
└── userHome.jsp // 如果需要一个主页可以放在这里
5.结合总结:Web应用中的处理流程
HTML 表单与用户输入:
用户通过HTML表单输入数据并提交给服务器。这些数据可能包括用户的操作(如四则运算的数字和运算符)或者需要登录验证的用户信息。
比如,一个计算器应用中,用户输入两个数字和选择一个操作符(加、减、乘、除)。这种数据会通过POST请求发送给服务器,供后台逻辑处理。
Servlet:处理用户输入与逻辑:
Servlet 是Web应用中用来处理客户端请求的Java类。它接收来自用户的输入,执行相应的逻辑,然后将结果返回给浏览器。
在四则运算的例子中,Servlet会从请求中获取用户输入的数字和运算符,使用 switch-case 语句进行运算,最后通过
response.getWriter()返回运算结果给用户。
例如,用户输入
num1 = 10,num2 = 5,operation = "add",Servlet会计算出num1 + num2,并返回结果15。四则运算:使用逻辑进行处理:
处理用户输入的数字和操作符,通常使用
switch-case语句来根据用户选择的操作(加法、减法、乘法、除法)执行相应的运算。在Servlet中,通过读取用户输入的参数(如
num1、num2和operation),然后根据operation的值来执行不同的运算(加、减、乘、除)。
重定向与转发:
重定向:如果用户需要被引导到一个新的页面(比如登录验证后跳转到用户主页),可以使用 重定向。这种方式会让浏览器重新发送请求,并且地址栏的URL会发生变化。例如,用户登录成功后,通过
response.sendRedirect("userHome.jsp");重定向到用户主页。转发:当你希望在服务器内部处理请求时,使用 转发。这通常用于数据的传递和页面间的跳转,且浏览器的地址栏不会变化。例如,在用户未登录的情况下,服务器通过
request.getRequestDispatcher("login.jsp").forward(request, response);将请求转发到登录页面,但浏览器的地址栏依旧显示最初的请求URL。
Session:保存和管理用户数据:
Session 用来在多次请求之间存储和管理用户的数据。例如,在一个Web应用中,登录后的用户信息(如用户名)可以通过 Session 保持,确保用户在访问其他页面时仍然处于登录状态。
在登录验证的场景中,用户登录后,登录信息(如用户名)会通过
session.setAttribute("user", username);存储在Session中,然后用户访问其他需要登录的页面时,服务器通过request.getSession().getAttribute("user")获取这个信息来判断用户是否已登录。
MVC模式:
MVC(Model-View-Controller) 是一种设计模式,用于将Web应用的逻辑分为三个主要部分:
Model(模型):负责处理数据和业务逻辑(比如四则运算的计算逻辑,或者从数据库读取用户数据)。
View(视图):负责显示数据给用户(比如HTML页面、JSP页面等)。
Controller(控制器):负责处理请求,协调Model和View(例如Servlet)。
MVC模式可以帮助你将代码的不同部分分离,使得应用更清晰、易于维护。比如,在一个计算器应用中:
Model 是进行四则运算的计算逻辑。
View 是HTML表单,显示用户输入和结果。
Controller 是Servlet,处理请求,执行计算并返回结果。
6. 如何在实际应用中结合这些技术:
假设你正在开发一个Web应用,需要实现如下功能:
用户通过HTML表单输入数字和选择运算符。
当用户点击“提交”时,表单数据会通过POST请求发送到一个Servlet。
Servlet接收数据,进行四则运算(加、减、乘、除),并返回计算结果。
如果用户未登录,访问某些页面时,可以使用 转发 将他们引导到登录页面;如果用户登录后,通过 重定向 跳转到用户主页。
使用 Session 来保持用户登录状态,确保用户登录后访问受保护的页面。

浙公网安备 33010602011771号