1.ServletContext
Tomcat启动的时候,需要识别webapps下的各个WEB应用,识别各个WEB应用的同时为每个WEB应用创建对应的对象ServletContext,一个WEB应用对应一个ServletContext.每个ServletContext中都有一个很大的MAP,并且tomcat在启动之初就向这个MAP中放入了大量的键值对的数据.当然我们也可以通过程序向这个大的MAP中放入键值对的数据.
注意:一个web应用对应唯一的一个ServletContext对象
ServletContext生命周期
同整个web应用的生命周期一致
1.1 ServletContext的作用
1.如何获取ServletContext对象:
ServletContext servletContext=getServletContext();
2.多个Servlet之间共享数据 attribute:属性
由于一个WEB应用只有一个ServletContext对象,当我们在访问服务端的Servlet时,都可以在Servlet中获取到当前应用唯一的ServletContext对象,所以可以利用ServletContext对象来实现共享数据.
3.获取到WEB项目下指定资源
WEB项目的运行位置和源码位置不在同一个位置,有时候我们需要获取到WEB项目在
运行过程中,指定资源的真实路径或者指定资源的输入流,此时可以通过ServletContext来获取?为什么可以获取到?因为ServletContext里存放了当前web项目的路径等信息.
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = getServletContext();
// 获取服务端指定目录下指定资源/目录的真实路径
String realPath = servletContext.getRealPath("/WEB-INF/config/conf.properties");
System.out.println(realPath);
// 获取服务端指定目录下指定文件的输入流对象
InputStream is=
servletContext.getResourceAsStream("/WEB-INF/config/conf.properties");
Properties properties = new Properties();
properties.load(is);
System.out.println(properties.get("name"));
}
4.获取到整个WEB全局的配置信息
我们之前在WEB中是为Servlet配置过键值对的数据,这些数据只能在当前的Servlet中获取到,如果希望配置一些参数,这些数据可以在所有Servlet都可以获取到,此时我们可以为当前应用配置全局的参数信息.配置方式如下:
<!--
全局的配置参数:所有的Servlet都可以获取到的
局部的Servlet配置参数:当前的Servlet可以获取到
-->
<context-param>
<param-name>username</param-name>
<param-value>mary</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>1234</param-value>
</context-param>
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = getServletContext();
System.out.println(servletContext.getInitParameter("username"));
System.out.println(servletContext.getInitParameter("password"));
Enumeration<String> initParameterNames = servletContext.getInitParameterNames();
while (initParameterNames.hasMoreElements()){
System.out.println(initParameterNames.nextElement());
}
}
5.获取到文件的mime类型
我们每次向客户端响应的内容类型可能是不一样的.在讲解HTTP协议那天,我们通过观察网络部分,发现如果本次响应的内容类型是一个HTML网页,那么在contentType消息头中对应的值是:text/html;如果如果本次响应的内容类型是一个css文件.有时候用户会下载我们服务端的不同资源,为了让浏览器更好的识别返回到客户端的内容类型,我们要设置一下本次响应的内容类型,但问题是:计算机业界各种类型的文件是很多的,我们怎么知道应该如何设置本次响应内容类型呢?就可以通过如下的API:
String value=ServletContext.getMimeType("333.avi");
ServletContext在tomcat/conf/web.xml中,根据文件后缀来查找本次响应内容是什么.
2.Response对象
2.1 Request/Response生命周期
每次服务端获取到来自客户端的请求之后,解析HTTP请求部分,将HTTP请求部分封装在HttpServletRequest对象中,同时创建HttpServletResponse对象, 之后在服务端完成本次响应之后,服务端就回收了刚才创建好的Request,Response对象. 下次请求到达服务端,会分配新的HttpServletRequest/HttpServletResponse对象
Request/Response何时创建?何时销毁?
总之:
HttpServletRequest对象代表的是从客户端到服务端请求这个过程
HttpServletResponse代表从服务端到客户端响应这个过程
2.2 HttpServletResponse对象的作用
既然HttpServletResponse代表从服务端到客户端响应这个过程,而且结合协议我们知道
HTTP协议响应包含三大块内容,分别是响应行,响应头,响应体.
HttpServletResponse可以控制响应部分的三个部分
Response控制响应行
//控制响应行的状态码
response.setStatus(302);
response.sendError(404, "ni yao qiu qing de zi bu cun zai ");
Response控制响应头
//测试利用response控制响应头
response.setHeader("test", "0000");
1_实现重定向302+location,
2_一句话搞定 response.sendRedrect(”路径”);
3_通过控制响应头实现定时刷新
4_重定向/定时刷新
response控制响应体
PrintWriter out=response.getWriter();
out.println(“ssss”);
OutputStream os=response.getOuputStream();
os.print();
3.Request
3.1 生命周期
请求一次创建一次,请求结束,对象被回收
3.2 作用
1_获取到请求部分三大块,客户端的部分信息IP
2_利用request实现请求转发(重点),利用request中的MAP存储数据
3.3 requestAPI
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 本次请求的方式: GET
String method = request.getMethod();
// 当前web路径: /DynamicWebProject_war_exploded
String contextPath = request.getContextPath();
// 远程客户端的ip: 0:0:0:0:0:0:0:1
String remoteAddr = request.getRemoteAddr();
// 获取header头
String header = request.getHeader("name");
Enumeration<String> headerNames = request.getHeaderNames();
// 获取请求体(表单参数)/路径之后
String name = request.getParameter("name");
Enumeration<String> parameterNames = request.getParameterNames();
Map<String, String[]> parameterMap = request.getParameterMap();
String[] parameterValues = request.getParameterValues("");
}
4.请求转发
4.1 什么是请求转发
当我们从客户端向服务端AAServlet发起请求的时候,在AAServlet中没有立即进行响应(即使在AAServlet中对客户端进行响应也无法将内容响应到客户端),而是将request/response继续向后传递,传递到BBServlet,在BBServlet中完成了本次响应.
4.2 为什么要有请求转发
因为本次请求到服务端希望做一些事情,但是在AAServlet做这件事情不合适,将要实现的功能分为2步来实现,一部分事情在AAServlet实现,剩余部分在BBServlet实现
4.3 请求转发本质是什么
服务端有2个Servlet(AA,BB),AA执行完毕之后,执行BB,AA和BB共享同一对request/response
ps:请求转发只能在当前项目内进行
public class ServletDemo04 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//向request中的名字为attributes的MAP中放入数据
request.setAttribute("name01", "tom");
request.setAttribute("name02", "mary");
//向客户端进行响应数据
response.getWriter().print("wo shi lai zi servletdemo04 de dai ma!");
//将request和response向后传递,传递给ServletDemo05 实现请求转发
//通过request获取到tomcat内部提供的API,叫做调度器对象
RequestDispatcher dispatcher = request.getRequestDispatcher("/ServletDemo05");
//dispatcher实现转发操作 Tomcat通过/ServletDemo05路径在WEB.XML找到对应全路径名cn.itcast.test00.ServletDemo05
dispatcher.forward(request, response);
}
}
public class ServletDemo05 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//可以获取到request中名称为attributes MAP中的数据
//获取到request中名称为attributes MAP中的所有的key
Enumeration<String> names = request.getAttributeNames();
//遍历names获取到每个key
while(names.hasMoreElements()){
String key = names.nextElement();
Object value = request.getAttribute(key);
System.out.println(key+"<___>"+value);
}
//向客户端进行响应
response.getWriter().print("wo shi serveltdemo05 zhong de dai ma!");
}
}
当我们访问ServletDemo04时,结果如下