三.ServletContext
1.概述
- Servlet容器启动时会为每个Web应用创建一个唯一的ServletContext对象代表当前Web应用,ServletContext对象封装了当前Web应用的所有信息
- ServletContext可以配置和获得应用的全局初始化参数,可以实现多个Servlet之间的数据共享
- 生命周期:应用加载则创建,应用停止则销毁
2.ServletContext配置
- 在web.xml文件的
标签中,通过
标签来配置,其中他有两个子标签
- 子标签
表示全局初始化参数的key
- 子标签
表示全局初始化参数的value
- 范例
globalEncoding UTF-8 globaleDesc This is SevletContext
3.ServletContext的三个作用
- 获取Web应用程序的初始化参数
Enumeration getInitParameterName()
方法用于返回包含所有参数名的Enumeration对象String getInitParameter(String name)
方法用于根据参数名获取参数值
- 实现多个Servlet之间的数据共享
注意:域属性指的就是可以共享的数据,即可以被多个Servlet访问到
方法名 |
说明 |
Enumeration getAttributeNames() |
返回包含所有域属性名的Enumeration对象 |
Object getAttribute(String name) |
根据域属性名返回域属性值 |
void removeAttribute(String name) |
根据域属性名从ServletContext中删除对应的域属性 |
void setAttribute(String name,Object obj) |
设置ServletContext的域属性,其中name是域属性名,obj是域属性值 |
- 读取Web应用下的资源文件
- 实际开发中有时会需要读取Web应用中的一些资源文件,为此ServletContext接口定义了一些读取Web资源的方法,这些方法由依靠Servlet容器实现,可以根据资源文件相对Web应用的路径,返回关联资源文件的IO流、资源文件的绝对路径等
- 相关方法
总结:这四个方法中的path其实就是相对于Web应用的路径,以斜杠/开头
方法名 |
说明 |
Set getResourcePaths(String path) |
返回一个Set集合,集合包含path指定路径下的子目录名称和文件名称但是不包含子目录下的文件名称,path以斜杠/开头表示Web应用的根目录 |
String getRealPath(String path) |
返回资源文件在服务器文件系统上的真实路径,参数path表示资源文件相对Web应用的路径,以斜杠/开头表示Web应用的根目录,如果不能将虚拟路径转为真实路径则返回null |
URL getResource(String path) |
返回映射到某个资源文件的URL对象,参数必须以斜杠/开头表示Web应用的根目录 |
InputStream getResourceAsStream(String path) |
返回映射到某个资源文件的InputStream输入流对象,参数path的传递规则与getResource()一致 |
四.HttpServletRequest
1.概述
- HttpServletRequest接口继承自ServletRequest接口
- HttpServletRequest专门用于封装HTTP请求消息
- HttpServletRequest提供了一些用于访问请求消息的方法,如获取请求行、获取请求头等
2.相关方法
- 获取请求行信息
String getMethod()
,该方法用于获取HTTP请求消息中的请求方式,如GET或PostString getRequestURI()
,该方法用于获取请求行中资源名称部分,即URL中主机名端口号之后和参数部分之前的部分String getQueryString()
,该方法用于获取请求行中的参数部分,即资源路径?号后边的全部内容String getProtocol()
,该方法用于获取请求行中的协议名和版本,如HTTP/1.0或HTTP/1.1String getContextPath()
,该方法用于获取URL中Web应用程序的路径,以/开头,结尾没有斜杠String getServletPath()
,该方法用于获取Servlet映射的路径或者Servlet的名称String getRemoteAddr()
,该方法用于获取发送请求的客户端的IP地址String getRemoteHost()
,该方法用于获取发送请求的客户端的完整主机名,如果解析不到则返回IP地址int getRemotePort()
,该方法用于获取发送请求的客户端的端口号String getLocalAddr()
,该方法用于获取Web服务器上接收当前请求的网络的IP地址String getLocalName()
,该方法用于获取Web服务器上接收当前请求的网络的IP地址对应的主机名int getLocalPort()
,该方法用于获取web服务器上接收当前网络连接的端口号String getServerName()
,该方法用于获取当前请求所指向的主机名,即HTTP请求消息中Host字段所对应的主机名部分String getServerPort()
,该方法用于获取当前请求所连接的服务器端口号,即HTTP请求消息中Host字段所对应的端口号部分String getSchema()
,该方法用于获取请求的协议名,如HTTP或HTTPSStringBuffer getRequestURL()
,该方法用于获取客户端发出请求时的完整URL,包括协议、服务器名、端口号、资源路径等,但不包括后面的查询参数部分,StringBuffer类型方便修改
范例:
@WebServlet("/HttpServletRequestDemo") public class HttpServletRequestDemo extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String method = req.getMethod(); System.out.println(method); String requestURI = req.getRequestURI(); System.out.println(requestURI); String queryString = req.getQueryString(); System.out.println(queryString); String protocol = req.getProtocol(); System.out.println(protocol); String contextPath = req.getContextPath(); System.out.println(contextPath); String servletPath = req.getServletPath(); System.out.println(servletPath); String remoteAddr = req.getRemoteAddr(); System.out.println(remoteAddr); String remoteHost = req.getRemoteHost(); System.out.println(remoteHost); int remotePort = req.getRemotePort(); System.out.println(remotePort); String localAddr = req.getLocalAddr(); System.out.println(localAddr); String localName = req.getLocalName(); System.out.println(localName); int localPort = req.getLocalPort(); System.out.println(localPort); String serverName = req.getServerName(); System.out.println(serverName); int serverPort = req.getServerPort(); System.out.println(serverPort); String scheme = req.getScheme(); System.out.println(scheme); StringBuffer requestURL = req.getRequestURL(); System.out.println(requestURL); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
输出结果:
- 获取请求头信息相关方法
String getHeader(String name)
,该方法作用是获取请求头中指定名称字段的值,如果没有该字段则返回null,如果有多个该指定名称的字段,则返回第一个字段的值Enumeration getHeaders(String name)
,返回一个Enumeration对象,该对象包含所有请求头中指定名称字段的值Enumeration getHeaderName()
,返回一个包含所有请求头字段的Enumeration对象int getIntHeader(String name)
,该方法获取一个指定请求头字段的值,并将该字段的值转为int类型再返回,如果该字段不存在则返回-1,如果该字段的值不能转为int类型则抛出NumberFormatException异常long getDateHeaders(String name)
,该方法获取一个指定请求头字段的值,并将其转为一个代表日期/时间的长整数,这个长整数是1970年1月1日0时0分0秒算起到现在的毫秒值String getContentType()
,获取Content-Type字段的值int getContentLength()
,获取Content-Length字段的值String getCharacterEncoding()
,获取请求消息的实体部分的字符集编码,通常从Content-Type字段中截取
范例:
@WebServlet("/HttpServletRequestDemo") public class HttpServletRequestDemo extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Enumeration headerNames = req.getHeaderNames(); while(headerNames.hasMoreElements()){ String s = headerNames.nextElement(); System.out.println(s+":"+req.getHeader(s)); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
输出结果:
- 获取请求参数相关方法
String getParameter(String name)
,该方法获取指定名称参数的参数值,如果没有该参数则返回null,如果该参数没有设置值则返回空串,如果该参数有多个值则返回第一个String getParameterValues(String name)
,该方法用于获取同一个参数名称的所有值Enumeration getParameterNames()
,该方法用于返回包含所有参数名的Enumeration对象Map getParameterMap()
,将参数名和参数值装入一个Map对象中返回
范例:
@WebServlet("/HttpServletRequestDemo") public class HttpServletRequestDemo extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Enumeration parameterNames = req.getParameterNames(); while (parameterNames.hasMoreElements()) { String s = parameterNames.nextElement(); String[] parameterValues = req.getParameterValues(s); System.out.println(s+":"+Arrays.toString(parameterValues)); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
输出结果:
3.HttpServletRequest共享数据
- HttpServletRequest不仅可以获取一些列数据,还能通过属性共享、传递一些数据,比如运用在请求转发和请求包含中
- 相关方法
void setAttribute(String name,Object obj)
,用于定义一个属性,其中name是属性的名称,obj是属性值,如果原先已经存在相同名称的属性,则会将原来的属性删除再添加该属性,如果obj为null则会删除删除指定名称的属性Object getAttribute(String name)
,根据属性名获取属性值void removeAttribute(String name)
,删除指定名称的属性Enumeration getAttributeNames()
,返回一个包含所有属性名的Enumeration对象
- 需要注意同一个请求中的数据才能共享、传递
4.请求转发和请求包含
- 请求转发
- Servlet之间可以相互跳转,如果某个Servlet的功能不能处理客户端的请求则可以使用跳转的方式将请求传递给另一个Servlet,由另一个Servlet完成并响应给客户端
- 相关方法
RequestDispatcher getRequestDispatcher(String path)
,该方法由HttpServletRequest提供,用于获取一个封装了某条路径所指定资源的RequestDispatcher对象,路径必须以斜杠/开头,即该路径就是需要转发到的某个Servlet的路径void forward(ServletRequest req,ServletResponse resp)
,该方法由RequestDispatcher提供,用于将请求转发给另一个Web资源,如某个Servlet
- 请求包含
- 某个Servlet不能完全处理一个请求时可以将另一个Servlet“包含”进来,实现功能合并然后响应给客户端,这时浏览器的地址栏不会发送改变,被包含的Servlet的响应头会丢失,因为是由第一个Servlet做出响应的
- 相关方法
RequestDispatcher getRequestDispatcher(String path)
,该方法根请求转发的相同,路径是需要包含的哪个Servlet的路径void include(ServletRequest req,ServletResponse resp)
,该方法由RequestDispatcher提供,用于实现包含另一个Servlet的功能
5.流对象获取数据
BufferedReader getReader()
,该方法获取一个字符输入缓冲流ServletInputStream getInputStream()
,该方法获取一个字节输入流- 注意这两个方法读取的数据来自请求体,所以使用GET方式获取不到数据,而POST方法可以
6.中文乱码问题
- 在网页的表单中如果需要提交的数据存在中文时可能会出现乱码的情况
- HttpServletRequest提供了
void setCharacterEncoding(String name)
方法用于设置Request对象的解码方式 - GET方式提交的请求不会出现乱码的问题,但是POST方式存在乱码问题
五.HttpServletResponse
1.概述
- HttpServletResponse接口继承自ServletResponse接口
- 用于封装HTTP响应消息
- HTTP响应消息分为响应行,响应头,响应体三部分,所以HttpServletResponse中定义了向客户端发送响应状态码、响应消息头、响应消息体等方法
2.常见状态码
状态码 |
说明 |
200 |
成功 |
302 |
重定向 |
304 |
请求资源未改变,使用缓存 |
400 |
请求错误,常见于请求参数错误 |
404 |
请求资源未找到 |
405 |
请求方式不支持 |
500 |
服务器错误 |
3.发送状态码的方法
void setStatus(int status)
,设置响应消息的状态码,并生成响应状态行void sendError(int sc)
,发送表示错误信息的状态码void sendError(int sc,String message)
,设置表示错误的状态码外还向客户端发送一条错误信息,其中包含message的内容
4.发送响应消息头的方法
void addHeader(String name,String value)
,设置响应头指定名称字段的值,会覆盖掉原来该名称字段的值void setHeader(String name,String value)
,与addHeader()方法功能相同,但是不会覆盖原来的值而是添加一个值void setContentLength(int len)
,设置响应头的实体内容的大小,单位是字节void setContentType(String type)
,设置响应内容的类型,即Content-Type的值,并且响应内容为文本类型时还能指定字符集编码,如text/html;charset=UTF-8
5.发送响应消息体的方法
ServletOutputStream getOutputStream()
,用于获取字节输出流对象PrintWriter getWriter()
,用于获取输出流对象- 注意:在使用这些输出流时可能会出现乱码的情况,所以在使用输出流时可以使用
resp.setContentType("text/html;UTF-8");
来设置字符集编码,用来解决乱码问题