public class UserServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//super.service(req, resp);
String username = req.getParameter("username");
String info = "YES
";
if("Shelly".equals(username)){
info = "NO";
}
resp.getWriter().println(info);
}
}
<servlet>
<servlet-name>userServletservlet-name>
<servlet-class>servlet.UserServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>userServletservlet-name>
<url-pattern>/userServleturl-pattern>
servlet-mapping>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<form method="get" action="userServlet">
用户名:<input type="text" name="username"><br>
<input type="submit" value="校验">
form>
body>
html>
元素中的action
属性指定了表单数据提交的目标URL。具体来说,action="userServlet"
表示当用户提交表单时,表单数据将被发送到名为userServlet
的URL路径。/user
路径,那么action="userServlet"
将与这个Servlet映射关系有关。当用户提交表单时,数据将被发送到/user
路径,容器会将请求交给该Servlet来处理。resp.setHeader("Content-Type","text/html");
//或者这样设置:
resp.setContentType("text/html");
<servlet>
<servlet-name>kkservlet-name>
<servlet-class>servlet.UserServletservlet-class>
servlet>
: 这是Servlet配置的开始标签,表示要定义一个Servlet。
: 这个标签定义了Servlet的名称,这里是kk
。
: 这个标签定义了Servlet类的完整路径,这里是servlet.UserServlet
,表示UserServlet
类在servlet
包下。kk
的Servlet,它的类是servlet.UserServlet
。当这个Servlet被请求时,容器将会实例化UserServlet
类的一个对象来处理请求。<servlet>
<servlet-name>kkservlet-name>
<servlet-class>servlet.UserServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>kkservlet-name>
<url-pattern>/userurl-pattern>
servlet-mapping>
元素用于将名为kk
的Servlet与URL路径/user
进行映射。解释如下:
: 这是Servlet映射配置的开始标签。
: 指定要映射的Servlet的名称,这里是kk
,与之前定义的
一致。
: 指定了要映射到Servlet的URL路径,这里是/user
。当用户请求路径为/user
时,容器会将请求交给名为kk
的Servlet处理。/user
时,容器会调用UserServlet
类来处理该请求。这样就实现了Servlet与URL路径之间的映射关系,使得用户请求能够正确地被分发到相应的Servlet进行处理。@WebServlet("/userServlet")
public class UserServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//super.service(req, resp);
String username = req.getParameter("username");
String info = "YES";
if("Shelly".equals(username)){
info = "NO";
}
resp.setHeader("Content-Type","text/html");
resp.getWriter().println(info);
}
}
UserServlet
类的映射路径。在@WebServlet
注解中,你需要指定UserServlet
类在Web应用中的访问路径。这个路径将与HTML表单中form标签的action
属性相对应。@WebServlet
中的路径应该与HTML表单中action
属性的值相匹配,以确保表单数据将被发送到正确的Servlet。因此,你应该在@WebServlet
中指定一个与HTML表单中action
属性相匹配的路径,例如@WebServlet("/userServlet")
。@WebServlet(
name = "userServlet",
//value = "/user",
urlPatterns = {"/userServlet1","/userServlet2","/userServlet"},
initParams = {"@WebInitParam(name = "encoding",value = "UTF-8")},
loadOnStartup = 6
)
@WebServlet(urlPatterns = "/s",loadOnStartup = 6)
public class UserServlet extends HttpServlet {
public UserServlet(){
System.out.println("构造器");
}
@Override
public void init() throws ServletException {
System.out.println("初始化方法");
}
@Override
protected void service(HttpServletRequest reS, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("service方法");
}
@Override
public void destroy() {
System.out.println("销毁方法");
}
}
loadOnStartup = 6
这部分。这个参数指定了Servlet在应用程序启动时加载的顺序。当一个Servlet的loadOnStartup
值大于0时,容器会在应用程序启动时立即加载这个Servlet,而不是等到第一次请求到达时再加载。值较小的Servlet将先加载,值相同的情况下按照Servlet在web.xml中的顺序加载。这个参数对于那些需要在应用程序启动时进行初始化的Servlet非常有用,例如加载一些配置信息或者预先进行一些计算。
DefaultServlet
是 Apache Tomcat 中的一个内置 Servlet,用于处理静态资源的请求。当 Tomcat 收到一个请求时,如果没有匹配到其他 Servlet 处理该请求,就会交给 DefaultServlet
处理。DefaultServlet
负责返回 Web 应用程序中的静态资源,比如 HTML、CSS、JavaScript、图片等文件。接口及方法说明
源码解释
解释
abstract class HttpServlet extends GenericServlet HttpServlet抽象类,除了基本的实现以外,增加了更多的基础功能
private static final String METHOD_DELETE = “DELETE”;
private static final String METHOD_HEAD = “HEAD”;
private static final String METHOD_GET = “GET”;
private static final String METHOD_OPTIONS = “OPTIONS”;
private static final String METHOD_POST = “POST”;
private static final String METHOD_PUT = “PUT”;
private static final String METHOD_TRACE = “TRACE”;
public HttpServlet() {}
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
对服务方法的实现
调用重载的service方法
public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
protected void doTrace(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
ServletConfig是什么
为Servlet提供初始配置参数的一种对象,每个Servlet都有自己独立唯一的ServletConfig对象
容器会为每个Servlet实例化一个ServletConfig对象,并通过Servlet生命周期的init方法传入给Servlet作为属性
public class ServletA extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletConfig servletConfig = this.getServletConfig();
// 根据参数名获取单个参数
String value = servletConfig.getInitParameter("param1");
System.out.println("param1:"+value);
// 获取所有参数名
Enumeration<String> parameterNames = servletConfig.getInitParameterNames();
// 迭代并获取参数名
while (parameterNames.hasMoreElements()) {
String paramaterName = parameterNames.nextElement();
System.out.println(paramaterName+":"+servletConfig.getInitParameter(paramaterName));
}
}
}
public class ServletB extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletConfig servletConfig = this.getServletConfig();
// 根据参数名获取单个参数
String value = servletConfig.getInitParameter("param1");
System.out.println("param1:"+value);
// 获取所有参数名
Enumeration<String> parameterNames = servletConfig.getInitParameterNames();
// 迭代并获取参数名
while (parameterNames.hasMoreElements()) {
String paramaterName = parameterNames.nextElement();
System.out.println(paramaterName+":"+servletConfig.getInitParameter(paramaterName));
}
}
}
<servlet>
<servlet-name>ServletAservlet-name>
<servlet-class>com.atguigu.servlet.ServletAservlet-class>
<init-param>
<param-name>param1param-name>
<param-value>value1param-value>
init-param>
<init-param>
<param-name>param2param-name>
<param-value>value2param-value>
init-param>
servlet>
<servlet>
<servlet-name>ServletBservlet-name>
<servlet-class>com.atguigu.servlet.ServletBservlet-class>
<init-param>
<param-name>param3param-name>
<param-value>value3param-value>
init-param>
<init-param>
<param-name>param4param-name>
<param-value>value4param-value>
init-param>
servlet>
<servlet-mapping>
<servlet-name>ServletAservlet-name>
<url-pattern>/servletAurl-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>ServletBservlet-name>
<url-pattern>/servletBurl-pattern>
servlet-mapping>
ServletContext是什么
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0">
<context-param>
<param-name>paramAparam-name>
<param-value>valueAparam-value>
context-param>
<context-param>
<param-name>paramBparam-name>
<param-value>valueBparam-value>
context-param>
web-app>
package com.atguigu.servlet;
import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
public class ServletA extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 从ServletContext中获取为所有的Servlet准备的参数
ServletContext servletContext = this.getServletContext();
String valueA = servletContext.getInitParameter("paramA");
System.out.println("paramA:"+valueA);
// 获取所有参数名
Enumeration<String> initParameterNames = servletContext.getInitParameterNames();
// 迭代并获取参数名
while (initParameterNames.hasMoreElements()) {
String paramaterName = initParameterNames.nextElement();
System.out.println(paramaterName+":"+servletContext.getInitParameter(paramaterName));
}
}
}
获取资源的真实路径
String realPath = servletContext.getRealPath(资源在web目录中的路径);
获取项目的上下文路径
String contextPath = servletContext.getContextPath();
域对象的相关API
后续我们会将三大域对象统一进行讲解和演示
,三大域对象都具有的API如下API | 功能解释 |
---|---|
void setAttribute(String key,Object value); | 向域中存储/修改数据 |
Object getAttribute(String key); | 获得域中的数据 |
void removeAttribute(String key); | 移除域中的数据 |
HttpServletRequest是什么
HttpServletRequest怎么用
API | 功能解释 |
---|---|
StringBuffer getRequestURL(); | 获取客户端请求的url |
String getRequestURI(); | 获取客户端请求项目中的具体资源 |
int getServerPort(); | 获取客户端发送请求时的端口 |
int getLocalPort(); | 获取本应用在所在容器的端口 |
int getRemotePort(); | 获取客户端程序的端口 |
String getScheme(); | 获取请求协议 |
String getProtocol(); | 获取请求协议及版本号 |
String getMethod(); | 获取请求方式 |
API | 功能解释 |
---|---|
String getHeader(String headerName); | 根据头名称获取请求头 |
Enumeration< String> getHeaderNames(); | 获取所有的请求头名字 |
String getContentType(); | 获取content-type请求头 |
API | 功能解释 |
---|---|
String getParameter(String parameterName); | 根据请求参数名获取请求单个参数值 |
String[] getParameterValues(String parameterName); | 根据请求参数名获取请求多个参数值数组 |
Enumeration getParameterNames(); | 获取所有请求参数名 |
Map | 获取所有请求参数的键值对集合 |
BufferedReader getReader() throws IOException; | 获取读取请求体的字符输入流 |
ServletInputStream getInputStream() throws IOException; | 获取读取请求体的字节输入流 |
int getContentLength(); | 获得请求体长度的字节数 |
API | 功能解释 |
---|---|
String getServletPath(); | 获取请求的Servlet的映射路径 |
ServletContext getServletContext(); | 获取ServletContext对象 |
Cookie[] getCookies(); | 获取请求中的所有cookie |
HttpSession getSession(); | 获取Session对象 |
void setCharacterEncoding(String encoding); | 设置请求体字符集 |
https://www.example.com/image.jpg
是一个URL,它指定了资源的位置(www.example.com服务器上的image.jpg文件)和访问方式(使用HTTPS协议)。(https)-z00rx9ct00awpeg86ci8w2za685sbf4e4jav19q./)urn:isbn:0451450523
是一个URN,它唯一标识了一个ISBN号为0451450523的资源,但没有指定如何访问该资源。getServerPort()
:
getServerPort()
返回的是客户端发送请求时使用的端口号,即客户端请求的URL中的端口号。这个端口号通常是客户端浏览器发送请求时使用的端口号,可以是标准的HTTP端口80或HTTPS端口443,也可以是其他自定义端口号。http://www.example.com:8080/index.html
,那么getServerPort()
返回的值就是8080。getLocalPort()
:
getLocalPort()
返回的是本应用程序在所在容器中监听的端口号,即应用程序所使用的端口号。这个端口号是服务器端应用程序监听的端口号,用于接收客户端的请求。getLocalPort()
返回的值就是8080。getRemotePort()
:
getRemotePort()
返回的是客户端程序的端口号,即客户端程序所使用的端口号。这个端口号是客户端程序(如浏览器)连接服务器时所使用的本地端口号。getRemotePort()
返回的就是这个本地端口号。总结:
getServerPort()
返回客户端请求URL中的端口号。getLocalPort()
返回服务器端应用程序所监听的端口号。getRemotePort()
返回客户端程序(如浏览器)的本地端口号。这些方法提供了不同层面的端口信息,用于在Java应用程序中获取和处理与客户端通信的相关端口信息。
HttpServletResponse是什么
HttpServletRequest怎么用
API | 功能解释 |
---|---|
void setStatus(int code); | 设置响应状态码 |
API | 功能解释 |
---|---|
void setHeader(String headerName, String headerValue); | 设置/修改响应头键值对 |
void setContentType(String contentType); | 设置content-type响应头及响应字符集(设置MIME类型) |
API | 功能解释 |
---|---|
PrintWriter getWriter() throws IOException; | 获得向响应体放入信息的字符输出流 |
ServletOutputStream getOutputStream() throws IOException; | 获得向响应体放入信息的字节输出流 |
void setContentLength(int length); | 设置响应体的字节长度,其实就是在设置content-length响应头 |
API | 功能解释 |
---|---|
void sendError(int code, String message) throws IOException; | 向客户端响应错误信息的方法,需要指定响应码和响应信息 |
void addCookie(Cookie cookie); | 向响应体中增加cookie |
void setCharacterEncoding(String encoding); | 设置响应体字符集 |
MIME类型
文件拓展名 | MIME类型 |
---|---|
.html | text/html |
.css | text/css |
.js | application/javascript |
.png /.jpeg/.jpg/… … | image/jpeg |
.mp3/.mpe/.mpeg/ … … | audio/mpeg |
.mp4 | video/mp4 |
.m1v/.m1v/.m2v/.mpe/… … | video/mpeg |
什么是请求转发和响应重定向
请求转发特点(背诵)
@WebServlet("/servletA")
public class ServletA extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求转发器
// 转发给servlet ok
RequestDispatcher requestDispatcher = req.getRequestDispatcher("servletB");
// 转发给一个视图资源 ok
//RequestDispatcher requestDispatcher = req.getRequestDispatcher("welcome.html");
// 转发给WEB-INF下的资源 ok
//RequestDispatcher requestDispatcher = req.getRequestDispatcher("WEB-INF/views/view1.html");
// 转发给外部资源 no
//RequestDispatcher requestDispatcher = req.getRequestDispatcher("http://www.atguigu.com");
// 获取请求参数
String username = req.getParameter("username");
System.out.println(username);
// 向请求域中添加数据
req.setAttribute("reqKey","requestMessage");
// 做出转发动作
requestDispatcher.forward(req,resp);
}
}
@WebServlet("/servletB")
public class ServletB extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求参数
String username = req.getParameter("username");
System.out.println(username);
// 获取请求域中的数据
String reqMessage = (String)req.getAttribute("reqKey");
System.out.println(reqMessage);
// 做出响应
resp.getWriter().write("servletB response");
}
}
响应重定向特点(背诵)
@WebServlet("/servletA")
public class ServletA extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求参数
String username = req.getParameter("username");
System.out.println(username);
// 向请求域中添加数据
req.setAttribute("reqKey","requestMessage");
// 响应重定向
// 重定向到servlet动态资源 OK
resp.sendRedirect("servletB");
// 重定向到视图静态资源 OK
//resp.sendRedirect("welcome.html");
// 重定向到WEB-INF下的资源 NO
//resp.sendRedirect("WEB-INF/views/view1");
// 重定向到外部资源
//resp.sendRedirect("http://www.atguigu.com");
}
}
@WebServlet("/servletB")
public class ServletB extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取请求参数
String username = req.getParameter("username");
System.out.println(username);
// 获取请求域中的数据
String reqMessage = (String)req.getAttribute("reqKey");
System.out.println(reqMessage);
// 做出响应
resp.getWriter().write("servletB response");
}
}
乱码问题产生的根本原因是什么
相对路径情况1:web/index.html中引入web/static/img/logo.png
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<img src="static/img/logo.png">
body>
html>
相对路径情况2:web/a/b/c/test.html中引入web/static/img/logo.png
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<img src="../../../static/img/logo.png">
body>
html>
相对路径情况3:web/WEB-INF/views/view1.html中引入web/static/img/logo.png
@WebServlet("/view1Servlet")
public class View1Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
RequestDispatcher requestDispatcher = req.getRequestDispatcher("WEB-INF/views/view1.html");
requestDispatcher.forward(req,resp);
}
}
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<img src="static/img/logo.png">
body>
html>
绝对路径情况1:web/index.html中引入web/static/img/logo.png
base标签定义页面相对路径公共前缀
index.html 和a/b/c/test.html 以及view1Servlet 中的路径处理
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<base href="/web03_war_exploded/">
head>
<body>
<img src="static/img/logo.png">
body>
html>
//绝对路径中,要写项目上下文路径
//resp.sendRedirect("/web03_war_exploded/a/b/c/test.html");
// 通过ServletContext对象动态获取项目上下文路径
//resp.sendRedirect(getServletContext().getContextPath()+"/a/b/c/test.html");
// 缺省项目上下文路径时,直接以/开头即可
resp.sendRedirect("/a/b/c/test.html");
请求转发只能转发到项目内部的资源,其绝对路径无需添加项目上下文路径
请求转发绝对路径的基准路径相当于http://localhost:8080/web03_war_exploded
在项目上下文路径为缺省值时,也无需改变,直接以/开头即可
@WebServlet("/x/y/servletB")
public class ServletB extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/a/b/c/test.html");
requestDispatcher.forward(req,resp);
}
}
项目上下文路径变化问题
解决方案
MVC(Model-View-Controller)是一种软件架构模式,用于将应用程序分为三个主要部分:模型(Model)、视图(View)和控制器(Controller)。这种架构模式有助于实现代码的分离,提高应用程序的可维护性和可扩展性。
模型(Model):
模型代表应用程序的数据结构和业务逻辑。它负责处理数据的存储、检索、更新和删除,以及定义应用程序的行为。模型通常不直接与用户界面交互,而是通过控制器来调用。
视图(View):
视图是用户界面的表示,负责展示数据给用户。视图通常是通过模型来获取数据,并将数据以用户友好的方式呈现出来。视图不包含业务逻辑,只负责展示数据。
控制器(Controller):
控制器是模型和视图之间的桥梁,负责处理用户的输入并作出相应的响应。控制器接收用户的请求,调用模型来处理数据,然后选择合适的视图来展示结果。控制器将用户的操作转化为对模型和视图的操作。
MVC架构模式的优点包括:
总之,MVC架构模式是一种有助于组织和管理应用程序代码的有效方式,被广泛应用于各种软件开发项目中。