1.一次请求的详细过程
- 浏览器向服务端发送请求
- web服务器监听到新的请求,启动一个单独的处理线程。
- 使用io流读取用户的请求数据
- 从请求数据中解析参数,并创建请求的servlet对象(当这个servlet是第一次被请求,并且没有设置为start-on-load),创建HttpServletRequest,HttpServletRequest对象,传递给请求的servlet对象的service方法。
- service()方法根据请求的类型将处理传递给doPost()或doGet()方法,如果service方法被重写,且没有调用doPost和doGet,则执行处理语句后直接返回给前台。
- 由servlet处理用户请求,生成响应数据。
- web服务器使用io流向客户端发送响应数据。
2. servlet中的内置对象
1.servlet之间的数据交换
- application
- session
- request
- page
是四个map型结构,并允许jsp和servlet从这四个对象中存取对象:
- 存:void setAttribute(String objectname,Object object)
- 取:Object getAttribute(String objectname)
区别是这四个对象的作用域不同:
- application:整个web应用
- session:一次会话
- request:一次请求
- page:当前页面
2. servlet与前台的数据交换:
1. 前台->servlet
通过request对象获得:request.getParameter(String name);
2. servlet->前台
通过JSON和response对象
PrintWriter pw=response.getWriter();
JSONObject obj=new JSONObject();
obj.put("keyName",value);
obj.put("keyName2",value2);
pw.writer(obj);
3. Cookie
cookie也是map型结构,用于客户端与服务器之间数据交互,cookie由服务器端生成发送给客服端,并在客户端储存,在之后的一段时间内,客户端的请求中会包含cookie的内容。
向服务器给客服端的响应中,添加一条cookie
//add cookie
Cookie cid=new Cookie("key", value);
cid.setMaxAge(cookieMaxAge);
response.addCookie(cid);
服务器取出客户端发来的请求数据中的cookie:
Cookie[] cookies=req.getCookies();
ArrayList<String> ids=new ArrayList<>();
if(cookies==null){
return null;
}
for(Cookie c:cookies){
if(c.getName().equals("id")){
ids.add(c.getValue());
}
}
//ids中取到到cookie中所有key为id的value
4.请求转发和重定向的区别
- 请求转发是一个请求一次响应,而重定向是两次请求两次响应
- 请求转发地址栏不变化,而重定向会显示后一个请求的地址
- 请求转发只能转发到本项目其他Servlet,而重定向不只能重定向到本项目的其他Servlet,还能定向到其他项目
- 请求转发是服务器端行为,只需给出转发的Servlet路径,而重定向需要给出requestURI,即包含项目名!
- 请求转发和重定向效率是转发高!因为是一个请求!
- 需要地址栏发生变化,那么必须使用重定向!
- 需要在下一个Servlet中获取request域中的数据,必须要使用转发!
简而言之就是,请求转发是服务器端在一次请求里调用另一个servlet,重定向是先向客户端返回一条响应状态302,并附上要求客户端重新发送请求的url,由客户端再发一条请求。
请求转发:
重定向:
5.ServletContext
- ServletContext是Servlet三大域对象之一
- ServletContext在服务器启动时创建,在服务器关闭时销毁,一个JavaWeb应用只创建一ServletContext对象
1. 它的功能分类:
- 存取数据
- 读取web.xml中的应用初始化参数
- 读取应用资源
2. 获取ServletContext对象
在HttpServlet中可以通过以下方法来获取ServletContext对象
* ServletContext sc = this.getServletContext()
* ServletContext sc = this.getServletConfig().getServletContext()
3. 存取数据
因为在一个JavaWeb应用中,只有一个ServletContext对象,所以在ServletContext中保存的数据可以共整个JavaWeb应用中的动态资源共享,ServletContext是Servlet三大域对象之一,域对象内部有一个Map,用来保存数据
- void setAttribute(String name, Object value):用来添加或替换ServletContext域数据
- servletContext.setAttribute(“xxx”, “XXX”),添加域数据
- servletContext.setAttribute(“xxx”, “XXXX”),覆盖域数据,因为在域中已经存在了名为xxx的数据,所以这次就是覆盖了
- Object getAttribute(String name):通过名称来获取域数据
- void removeAttribute(String name):通过名称移除域数据
- Enumeration getAttributeNames():获取所有ServletContext域数据的名称
4. 读取web.xml中配置的应用初始化参数
<context-param>
<param-name>p1</param-name>
<param-value>v1</param-value>
</context-param>
<context-param>
<param-name>p2</param-name>
<param-value>v2</param-value>
</context-param>
- servletContext.getInitParameter(“p1”),返回v1
- servletContext.getInitParameter(“p2”),返回v2
- servletContext.getInitParameterNames(),返回Enumeration,包含p1和p2
5. 获取项目资源
String getRealPath(String path):获取资源的真实名称
String path = servletContext.getRealPath(“/WEB-INF/a.jpg”);
返回值为/WEB-INF/a.jpg真实路径,即磁盘路径:C:/tomcat6/wabapps/hello/WEB-INF/a.jpgInputStream getResourceAsStream(String path):获取资源的输入流
InputStream in = servletContext.getResourceAsStream(“/WEB-INF/a.jpg”);
返回的是a.jpg的输入流对象,可以从流中得到a.jpg的数据Set getResourcePaths(String path):获取指定目录下的所有资源路径
Set paths = servletContext.getResourcePaths(“/WEB-INF”);
返回的Set中包含如下字符串:/WEB-INF/lib/
/WEB-INF/classes/
/WEB-INF/web.xml
/WEB-INF/a.jpg
6. servlet3.0支持文件上传
需在注解上加入:
@MultipartConfig
通过request可以获取上传的part
//get files
Collection<Part> files = request.getParts();
调用Part的writer(String filename)方法直接写入本地
for(Part file:files){
file.write(filename);
}
7. 连接池的概念
设置了连接数量的上限和下限,作用:
- 使得在访问量很小的时候,仍然保持着一些连接,当突然有请求访问时,可以直接从池中获取,而不必重新创建。
- 访问量很大时候,超过了连接的上限,也不在创建新的连接对象,而是将请求放入请求队列。
实现:
1. 创建一个连接池
2. 使用连接时从池中取出,用完放回池。
3. 超过一定时间没人用的连接会timeout,但最少保持一定数量的链接
2.Filter
Filter是JavaWeb三大组件之一(Servlet,Filter,Listener),用于对请求在servlet前进行预处理,和相应生成后,返回客户端之前进行善后,是典型的处理链操作,是aop的雏形。
do something//预处理
chain.doFilter(request, response);//放行
do something//善后处理