5.2 ServletContext接口
注意:
- 一个web项目只有一个ServletContext对象,代表当前Web应用
- 所有的Servlet共享同一个ServletContext对象,所以ServletContext对象也被称为 application 对象(Web应用程序对象)
- ServletContext对象是由服务器启动的时候,Tomcat去创建,在项目卸载时(服务器关机时)销毁。
如何获得到ServletContext对象?
- 通过ServletConfig去获得
//使用servletConfig获取全局上下文ServletContext对象 ServletContext servletContext = servletConfig.getServletContext(); System.out.println("servletContext:"+servletContext);
- 通过request去获得
//使用servletRequest获取servletcontext对象(全局上下文对象) ServletContext servletContext = servletRequest.getServletContext(); System.out.println("servletContext:"+servletContext);
主要功能:
- 获取项目的上下文路径(带"/"的项目名)
//1.获取项目的上下文路径(带/的项目名) String contextPath = servletContext.getContextPath(); System.out.println("contextPath:"+contextPath);
- 获取虚拟路径所映射的本地真实路径
用途:上传或下载文件时需要使用
//2.获取虚拟路径所映射的本地真实路径(根据相对路径获得绝对路径) String realPath = servletContext.getRealPath("/upload"); System.out.println("realPath:"+realPath);
- 获取WEB应用程序的全局初始化参数
获取全局初始化参数的前提是你得有全局初始化参数,没有的话就得设置
- 如何设置全局初始化参数?
位置:web.xml 的根节点上
web.xml上的相应代码如下所示:
<context-param> <param-name>context-key</param-name> <param-value>context-value</param-value> </context-param> <context-param> <param-name>ccc</param-name> <param-value>ddd</param-value> </context-param>
//3.获取WEB应用程序的全局初始化参数 //获取全局初始化参数中<param-name>【 key】为ccc的value值 String ccc = servletContext.getInitParameter("ccc"); System.out.println("ccc="+ccc); //获取全局初始化参数中<param-name>【 context-key】为ccc的value值 String context_key = servletContext.getInitParameter("context-key"); System.out.println("context_key="+context_key); //获取全局初始化参数中所有的<param-name>【 key】值 Enumeration<String> initParameterNames = servletContext.getInitParameterNames(); while (initParameterNames.hasMoreElements()){ System.out.println("nextElement:"+initParameterNames.nextElement()); }
- 作为域对象共享数据 ★
域对象:在一定的作用域范围内共享数据的对象
ServletContext所用域范围是整个web项目
- 测试:
1.在一个Servlet内,往ServletContext对象中设置共享数据
2.在另外一个Servlet内获取到共享的数据
方法:
servletcontext.setAttribute(string key,object obj); object msg servletcontext.getAttribute(string key); //移除指定的共享数据(指定key,删除对应的value) servletcontext.removeAttribute(Sstring key);
案例:尝试使用SecondServlet删除myFirstServlet新建的共享数据test,test的value值自定义
- 代码演示如下:
//MyFirstServle新增共享数据test并显示 import javax.servlet.*; import java.io.IOException; public class MyFirstServlet extends GenericServlet { @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("触发了继承GenericServlet类的子类MyFirstServlet类的service方法......"); //如何在servletContext作用域范围内添加共享数据 ServletContext servletContext = servletRequest.getServletContext(); servletContext.setAttribute("msg","这是MyFirstServlet设置的共享数据"); //MyFirstServle新增共享数据test并显示 servletContext.setAttribute("test","这是MyFirstServlet设置的test共享数据"); System.out.println("test="+servletContext.getAttribute("test")); } }
//SecondServlet尝试删除并显示MyFirstServlet设置的共享数据test 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 SecondServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("访问了SecondServlet里的doPost方法"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("访问了SecondServlet里的doGet方法"); //如何获取MyFirstServlet在servletContext作用域范围内设置的共享数据 ServletContext servletContext = request.getServletContext(); Object msg = servletContext.getAttribute("msg"); System.out.println("msg="+msg); //删除MyFirstServlet设置的共享数据test servletContext.removeAttribute("test"); System.out.println("SecondServlet已经删除了共享数据test"); System.out.println("共享数据test="+servletContext.getAttribute("test")); } }
六. 处理请求和响应的接口
6.1 HttpservletRequest接口
简介:
该接口是ServletRequest接口的子接口,封装了HTTP请求的相关信息(请求报文中的所有信息都被封装在里面)
主要功能:
- 获得请求头信息
request.getHeader(String key);
//获取请求头中客户端的产品信息 String header = request.getHeader("User-Agent"); System.out.println("客户端的产品信息如下"); System.out.println("header:"+header); //获取请求头中请求来源 String referer = request.getHeader("Referer"); System.out.println("请求来源如下"); System.out.println("referer:"+referer);
- 获得url的路径信息
request.getContextPath()//获取上下文路径 request.getServerName() //获取主机名 request.getServerPort() //获取端口号
//获取url String contextPath = request.getContextPath();//获取上下文路径 System.out.println("contextPath:"+contextPath); //获取主机名 String serverName = request.getServerName(); System.out.println("serverName:"+serverName); //获取端口号 int serverPort = request.getServerPort(); System.out.println("serverPort:"+serverPort);
- 获得请求参数 ★
请求参数是什么?
请求参数就是浏览器向服务器提交的数据。
浏览器向服务器如何发送数据?
① 附在url后面(和get请求一致,拼接的形式就行请求数据的绑定),如下下所示:
http://localhost:8989/MyServlet/MyHttpServlet?userId=20&username=jack
- ② 通过表单提交
<form action="MyHttpServlet" method="post"> 你喜欢的足球队<br /><br /> 巴西<input type="checkbox" name="soccerTeam" value="Brazil" /> 德国<input type="checkbox" name="soccerTeam" value="German" /> 荷兰<input type="checkbox" name="soccerTeam" value="Holland" /> <input type="submit" value="提交" /> </form>
- 使用HttpServletRequest对象获取请求参数
string request.getparameter(string key); string[] request.getparametervalues("hobby");
//获取请求参数 //根据表单的name值获取它的value值 String username = request.getParameter("username");//获取表单中name为username的value值,下同 System.out.println("username="+username); String password = request.getParameter("password"); System.out.println("password="+password); String gender = request.getParameter("gender"); System.out.println("gender="+gender); //如何根据一个name获取有多个并存的value值 String[] hobbies = request.getParameterValues("hobby"); System.out.println("hobbies:"); for (String hobby : hobbies) { System.out.println(hobby); }
- 获取请求方式
request.getMethod()
//获取请求方式 String method = request.getMethod(); System.out.println("请求方式:"); System.out.println("method:"+method);
- 转发并共享数据
转发是进行页面跳转的主要手段之一
- 什么是转发?如下图所示
应用场景如下:
a. 转发到第二个servlet
//HttpServletRequest对象reg转发客户端请求至register_error的servlet中 req.getRequestDispatcher("register_error").forward(req,resp);
- b. 转发到一个网页
//HttpServletRequest对象reg转发客户端请求至网页register_error中 req.getRequestDispatcher("regist_error.html").forward(req,resp);
- 使用步骤:
a.获得转发器对象
RequestDispatcher requestDispatcher=request.getRequestDispatcher(目标路径);
- b.进行转发操作(将request和response需要传递过去)
requestDispatcher.forward(request,response);
- 进行页面跳转的代码:
//跳转至root.html request.getRequestDispatcher("root.html").forward(request,response);
- Secondservlet能否获得到请求中的请求参数?
可以的,因为转发将request对象传递过去了
- request可以作为域对象共享数据(请求域)
应用域(ServletContext):
数据共享范围是整个web应用请求域(HttpServletRequest)
:数据共享的范围是本次请求,当响应结束了,请求也结束
//添加共享数据 setAttribute(string key,object value); //获取共享数据 getAttribute(string key) //移除共享数据 removeAttribute(string kev)
6.2 HttpservletResponse接口
简介:
- 该接口是ServletResponse接口的子接口,封装了服务器针对于HTTP响应的相关信息。(暂时只有服务器的配置信息,没有具体的和响应体相关的内容)
- 由Servlet容器创建其实现类对象,并传入service(HttpServletRequest req, HttpServletResponse res)方法中。
- HttpServletResponse对象指的是容器提供的HttpServletResponse实现类对象。
主要功能:
a.通过输出流将响应数据输出给客户端
Printwriter writer=response.getwriter(); writer.write("<h1>success</h1>");
b.可以设置响应的乱码(添加响应头的方式)
response.addHeader("Content-Type","text/html;charset=utf-8"); 简写:response.setContentType("text/html;charset=utf-8");
c.重定向
页面跳转的主要手段之一
什么是重定向?如下图所示:
应用场景如下:
①重定向至另一个Servlet
response.sendRedirect("second");
②重定向至页面
response.sendRedirect("admin.html");
当发送到firstservlet请求中的请求参数,Secondservlet是否能获取到?
取不到;因为发送了第二次请求(第一次请求中的请求参数和第二次请求毫无关系)
重定向能否使用请求域共享数据?
不可以
转发和重定向的区别
转发 | 重定向 | |
浏览器的感知 | 感知不到 | 感知到 |
网址栏里的网址 | 不变 | 会改变 |
请求的次数 | 一次请求 | 两次请求 |
请求域中的共享数据 | 可以访问 | 不可以访问 |
发起者 | request | response |
WEB-INF | 可以访问 | 不可以访问 |
目标资源 | 本服务器的资源 | 其他服务器的资源 |
ps:
WEB-INF下的资源有一个特性:客户端是访问不到的,但是服务器可以访问,可以把不想让客户端直接访问的资源,放在WEB-INF下
七. 请求和响应乱码的处理
7.1 请求乱码
①
get请求
:tomcat8已经处理好了
注意:
若你的Tomcat版本为7及以下,就需要修改tomcat的配置文件。在server.xml文件修改Connector标签,添加URIEncoding="utf-8"属性,如下图所示:
②
post请求
:中文乱码问题
解决方案:
在代码中获取请求参数之前,设置字符集
代码如下:
request.setcharacterEncoding("utf-8");
案例:form表单以post方式向FirstServlet提交数据,演示post乱码问题
代码演示如下:
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 FirstServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //请求 //post方法的中文乱码问题 // request.setCharacterEncoding("utf-8"); String username = request.getParameter("username"); System.out.println("username="+username); String password = request.getParameter("password"); System.out.println("password="+password); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("触发了FirstServlet的doGet方法......."); /* //设置请求域的共享数据 //注意,设置的共享数据需要放在使用请求转发的代码之前,不然另一个servlet无法获取之前设的请求域共享数据 request.setAttribute("requestMsg","这是requestMsg共享的数据"); request.setAttribute("msg","这是msg"); //实现转发跳转至secondservlet // request.getRequestDispatcher("second").forward(request,response); //实现重定向至secondservlet response.sendRedirect("second"); */ } }
添加字符集后修改如下:
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 FirstServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //请求 //post方法的中文乱码问题 request.setCharacterEncoding("utf-8"); String username = request.getParameter("username"); System.out.println("username="+username); String password = request.getParameter("password"); System.out.println("password="+password); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("触发了FirstServlet的doGet方法......."); /* //设置请求域的共享数据 //注意,设置的共享数据需要放在使用请求转发的代码之前,不然另一个servlet无法获取之前设的请求域共享数据 request.setAttribute("requestMsg","这是requestMsg共享的数据"); request.setAttribute("msg","这是msg"); //实现转发跳转至secondservlet // request.getRequestDispatcher("second").forward(request,response); //实现重定向至secondservlet response.sendRedirect("second"); */ } }