JavaWeb---Servlet 学习笔记
1、Servlet
1.1、Servlet概述
Servlet主要用于处理客户端传来的HTTP请求,并返回一个响应。Servlet由Servlet容器提供,Servlet容器将Servlet动态的加载到服务器上。与HTTP协议相关的Servlet使用HTTP请求和HTTP响应与客户端进行交互。因此,Servlet容器支持所有HTTP协议的请求响应。
在上图中,Servlet的请求首先会被HTTP服务器(如Apache)接收,HTTP服务器值负责静态HTML页面的解析,对于SErvlet的请求转交给Servlet容器,Servlet容器会根据web.xml文件中的映射关系,调用相应的Servlet,Servlet将处理的结果返回给Servlet容器,并通过HTTP服务器响应给客户端。
1.2、Sercvlet开发入门
1.从原型中创建maven工程,然后删除src文件夹
2.在刚才创建的工程中创建子module,
3.将web.xml中的文件替换为webapp4.0版本,和Tomcat保持一致。
<?xml version="1.0" encoding="UTF-8"?>
<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">
</web-app>
4.编写自己的类继承HttpServlet,重写方法
package com.nty.servlet;
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 HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入了doGet方法");
PrintWriter writer = resp.getWriter();//响应流
writer.print("Hello servlet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
5.在web.xml文件中注册Servlet,编写Servlet的映射
<!--注册Servlet-->
<servlet>
<!--Servlet名称-->
<servlet-name>hello</servlet-name>
<!--Servlet类所在的位置-->
<servlet-class>com.nty.servlet.HelloServlet</servlet-class>
</servlet>
<!--请求的路径:虚拟路径-->
<servlet-mapping>
<!--Servlet名称-->
<servlet-name>hello</servlet-name>
<!--虚拟路径-->
<url-pattern>/hello</url-pattern>
<url-pattern>/test</url-pattern>
</servlet-mapping>
6.配置Tomcat,
7.启动测试
1.3、Servlet原理
1.4、Mapping问题
1.一个Servlet可以指定一个映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
2.一个Servlet可以指定多个映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello3</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello4</url-pattern>
</servlet-mapping>
</servlet-mapping>
3.一个Servlet可以指定通用映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
4.默认请求路径
<servlet-mapping>
<url-pattern>/hello</url-pattern>
<url-pattern>/*</url-pattern>
</servlet-mapping>
5.指定一些后缀或前缀等等...
<!--可以自定义后缀实现请求映射
注意点,*前面不能加项目映射的路径
abc.do
-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
6.优先级问题
指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;
<!--404-->
<servlet>
<servlet-name>error</servlet-name>
<servlet-class>com.kuang.servlet.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>error</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
1.5、ServletConfig接口
1、什么是ServletConfig对象?
Servlet/Jsp容器创建一个Servlet类型的对象时,会为这个Servlet对象创建一个唯一的ServletConfig对象。在ServletConfig对象中包含了Servlet的初始化参数信息。在Servlet的配置文件中,可以用一个或多个init-param标签为Servlet配置一些初始化参数。当Servlet配置了初始化参数之后,Web容器在创建Servlet实例对象时,会自动将这些初始化参数封装到这个Servlet对象对应的ServletConfig对象中,并在调用Servlet的init()方法时,将ServletConfig对象传递给Servlet。进而,程序员通过ServletConfig对象得到当前Servlet的初始化参数信息。
2、ServletConfig的常用方法
方法说明 | 功能描述 |
---|---|
String getInitParameter(String name) | 根据参数名取得参数值 |
Enumeration getInitParameterNames() | 取得标签中配置的所有参数的参数名 |
ServletContext getServletContext() | 返回一个代表当前web应用的Servletontext对象 |
String getServletName() | 取得当前Servlet的名称 |
3、ServletConfig获取web.xml文件中为Servlet配置的初始化参数案例
web.xml定义
<?xml version="1.0" encoding="UTF-8"?>
<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>
<servlet-name>test01</servlet-name>
<servlet-class>com.nty.servlet.TestServlet01</servlet-class>
<!--要设置的参数-->
<init-param>
<!-- 参数名称-->
<param-name>encoding</param-name>
<!--参数的值-->
<param-value>UTF-8</param-value>
</init-param>
</servlet>
<!--虚拟路径-->
<servlet-mapping>
<servlet-name>test01</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
</web-app>
Java类文件
package com.nty.servlet;
import javax.servlet.ServletConfig;
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 TestServlet01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
//获得ServletConfig对象
ServletConfig servletConfig = this.getServletConfig();
//获得参数名为encoding对应的参数值
String encoding = servletConfig.getInitParameter("encoding");
writer.println("encoding=" + encoding);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
}
1.6、ServletContent接口
1、什么是ServletContent对象?
当Web容器(Tomcat)启动,且Web应用加载完成后,Web容器立即为该Web应用创建一个的ServletContext对象代表当前Web应用。每一个Web应用都有且仅有一个ServletContext对象,又称Application对象。该对象不仅封装了当前web应用的所有信息,而且实现了多个Servlet之间数据的共享。
2、ServletContext案例
web.xml
<!-- 添加下述代码-->
<context-param>
<param-name>companyName</param-name>
<param-value>test</param-value>
</context-param>
<context-param>
<param-name>address</param-name>
<param-value>beijing</param-value>
</context-param>
类文件
package com.nty.servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
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;
import java.util.Enumeration;
public class TestServlet01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter writer = resp.getWriter();
//得到ServletContext对象
ServletContext servletContext = this.getServletContext();
//得到包含所有初始化参数名的Enumeration对象
Enumeration<String> parameterNames = servletContext.getInitParameterNames();
writer.println("all the paramName and paramValue are following:");
//遍历所有初始化参数名,得到相应的参数并打印
while (parameterNames.hasMoreElements()) {
String name = parameterNames.nextElement();
String value = servletContext.getInitParameter(name);
writer.println(name + ": " + value);
writer.println("<br />");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
}
2、实现多个Serlvet对象共享数据
TestServlet01
package com.nty.servlet;
import javax.servlet.ServletContext;
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 TestServlet01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter writer = resp.getWriter();
//得到ServletContext对象
ServletContext servletContext = this.getServletContext();
//通过getAttribute()方法获取属性值
String data = (String) servletContext.getAttribute("data");
writer.println(data);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
TestServlet02
package com.nty.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class TestServlet02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
//通过setAttribute()方法设置属性值
context.setAttribute("data", "this servlet save data");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>
<servlet-name>test01</servlet-name>
<servlet-class>com.nty.servlet.TestServlet01</servlet-class>
</servlet>
<servlet>
<servlet-name>test02</servlet-name>
<servlet-class>com.nty.servlet.TestServlet02</servlet-class>
</servlet>
<!--虚拟路径-->
<servlet-mapping>
<servlet-name>test01</servlet-name>
<url-pattern>/test01</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>test02</servlet-name>
<url-pattern>/test02</url-pattern>
</servlet-mapping>
</web-app>
浏览器中先访问test02,再访问test01,然后将会出现结果
3、读取web应用下的资源文件
1.resources文件夹下建立properties文件
Company = nty
Address = BeiJin
2.编写servlet类文件
package com.nty.servlet;
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.InputStream;
import java.io.PrintWriter;
import java.util.Properties;
public class TestServlet01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/test.properties");
Properties prop = new Properties();
prop.load(is);
String company = prop.getProperty("Company");
String address = prop.getProperty("Address");
resp.getWriter().print(company + ":" + address);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
2、请求和响应
2.1、HttpServletRespose对象
HttpServletRespose继承自ServletRespose接口,专门用来封装HTTP响应消息。HTTP响应消息分为状态行,响应消息头,消息体三部分。
1、发送状态码
- setStatus(int status)方法
- sendError(int sc)方法
void sendError(int var1, String var2) throws IOException;
void sendError(int var1) throws IOException;
2、发送响应消息头
void sendRedirect(String var1) throws IOException;
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void setHeader(String var1, String var2);
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
void addIntHeader(String var1, int var2);
void setStatus(int var1);
3、发送响应消息体相关的方法
- getOutputStream()方法
- getWriter()方法
下面是两个发送响应消息体的案例:
package com.nty.response;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class PrintServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String data = "nty";
//获取字节流输出对象啊
ServletOutputStream outputStream = resp.getOutputStream();
//输出信息
outputStream.write(data.getBytes());
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}
package com.nty.response;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
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 PrintServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String data = "ntyxhx";
//获取字节流输出对象啊
PrintWriter printWriter = resp.getWriter();
//输出信息
printWriter.write(data);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}
2.1.1、HttpServletRespose应用
1、解决中文输出乱码
//在自己编写的servlet类中加入下列三种方法其中之一
resp.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setHeader("Content-Type", "text/html;charset=utf-8");
resp.setHeader("text/html;charset=utf-8");
2、重定向
2.2、HttpServletRequest对象
1、获取请求信息的相关方法
2、获取请求消息头的相关方法
方法声明 | 功能描述 |
---|---|
String getMethod() | 该方法用于获取 HTTP 请求消息中的请求方式(如 GET、POST 等) |
String getRequestURI() | 该方法用于获取请求行中的资源名称部分即位于 URL 的主机和端门之后、参数部分之前的部分 |
String getQueryString() | 该方法用于获取请求行中的参数部分,也就是资源路径后问号(?)以后的所有内容 |
String getContextPath() | 该方法用于获取请求 URL 中属于 Web 应用程序的路径,这个路径以 / 开头,表示相对于整个 Web 站点的根目录,路径结尾不含 /。如果请求 URL 属于 Web 站点的根目录,那么返回结果为空字符串("") |
String getServletPath() | 该方法用于获取 Servlet 的名称或 Servlet 所映射的路径 |
String getRemoteAddr() | 该方法用于获取请求客户端的 IP 地址,其格式类似于 192.168.0.3 |
String getRemoteHost() | 该方法用于获取请求客户端的完整主机名,其格式类似于 pcl.mengma.com。需要注意的是,如果无法解析出客户机的完整主机名,那么该方法将会返回客户端的 IP 地址 |
int getRemotePort() | 该方法用于获取请求客户端网络连接的端口号 |
String getLocaIAddr() | 该方法用于获取 Web 服务器上接收当前请求网络连接的 IP 地址 |
String getLocalName() | 该方法用于获取 Web 服务器上接收当前网络连接 IP 所对应的主机名 |
int getLocalPort() | 该方法用于获取 Web 服务器上接收当前网络连接的端口号 |
String getServerName() | 该方法用于获取当前请求所指向的主机名,即 HTTP 请求消息中 Host 头字段所对应的主机名部分 |
int gctServcrPort() | 该方法用于获取当前请求所连接的服务器端口号,即 HTTP 请求消息中 Host 头字段所对应的端口号部分 |
StringBuffcr getRequestURL() | 该方法用于获取客户端发出请求时的完整 URL,包括协议、服务器名、端口号、 资源路径等信息,但不包括后面的査询参数部分。注意,getRequcstURL() 方法返冋的结果是 StringBuffer 类型,而不是 String 类型,这样更便于对结果进行修改 |
案例:
package com.nty.request;
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;
import java.util.Enumeration;
public class RequestHeaderServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter writer = resp.getWriter();
//获取请求消息中的所有头字段
Enumeration headerNames = req.getHeaderNames();
//循环遍历所有请求头,并通过getHeader()方法获取一个指定名称的头字段
while (headerNames.hasMoreElements()) {
String hn = (String) headerNames.nextElement();
writer.println(hn + ":" + req.getHeader(hn) + "<br/>");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
host:localhost:8080
connection:keep-alive
upgrade-insecure-requests:1
user-agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36
accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
sec-fetch-site:none
sec-fetch-mode:navigate
sec-fetch-user:?1
sec-fetch-dest:document
accept-encoding:gzip, deflate, br
accept-language:zh-CN,zh;q=0.9
cookie:JSESSIONID=5BA1E7B8E0A058EF3BAFE4BCBE0AB5AC
2.2.1、HttpServletRequest应用
3、剩余内容
本文来自博客园,作者:NotYourferry,转载请注明原文链接:https://www.cnblogs.com/pinghuimolu/p/15223117.html