面对扑面而来的web请求,Servlet最关心的3个问题是:
处理哪个请求?
怎么从请求中取出数据?
怎么把结果写入响应?
Servlet还会有下列需求:如何跟其它Servlet分享信息、以及彼此协调?如何保存会话数据?如何读写cookie?
Url:从浏览器中观察到的网址 Http Method: 请求的发送方式( get/post/put/delete/head ) web请求的表现形式web容器把请求相关的工作,都封装到了 HttpServletRequest中;把响应相关的工作,都封装到了 HttpServletResponse中;然后通过 doXXX()方法的形参,直接提供给我们使用。
![8be6aad82a41a863c802c18dde3cf1e7.png](https://i-blog.csdnimg.cn/blog_migrate/5983f731d35be5935552b22b5407c512.png)
1.处理哪个请求?
Servlet要处理哪个请求,由它自己说了算:①通过@WebServlet(" 项目相对路径"),指定请求的Url②通过 doXXX()方法,指定请求的发送方式web容器会根据这个约定,将指定的请求路由给Servlet,比如:![57ea77776f0fe51edd4f1059e11f2570.png](https://i-blog.csdnimg.cn/blog_migrate/6a36da2f857a0a1ad2ecc180d6490425.png)
http://{服务器ip}:{web容器用的port}/{项目名称}/{ 项目相对路径} 完整的Url格式
2.怎么从请求中取出数据?
首先,我们要正确识别请求:文本以一定的编码形式存在,如果浏览器使用utf-8格式的编码,Servlet也必须用同样的编码格式,否则会出现乱码:
request.setCharacterEncoding("utf-8");
然后,我们可以从请求中,取出两部分内容:①body:纯数据干货②header:描述请求的元数据(当成请求的注释好了)
request.getParameter("body中的参数名");request.getParameterValues("body中的参数名");request.getHeader("header名称");
3.怎么把结果写入响应?
同样,我们要先考虑编码,让Servlet和浏览器使用同样的编码格式:response.setCharacterEncoding("utf-8");
然后,我们可以往响应中,写两部分内容:①body:纯数据干货②header:描述响应的元数据(当成响应的注释好了)
response.getWriter().append("响应文本");response.setHeader("header名称", "header值");
ContentType
是常用的响应头,为了方便使用,提供了独立的方法:
response.setContentType("text/html;charset=UTF-8");
有时不返回具体的数据,而是让浏览器跳转到其它页面:
response.sendRedirect("其它url");
Servlet还会有下列需求:如何跟其它Servlet分享信息、以及彼此协调?如何保存会话数据?如何读写cookie?
4.如何跟其它Servlet分享信息、以及彼此协调?
如果把Servlet比作一个人,一个项目就好比一个群,需要一个 管理者来组织协调,这个 群主就是 ServletContext,要找到群主,使用下面这行代码:ServletContext context = request.getServletContext();
Servlet通过两种手段互相分享信息:①群主事先写好公告,大家只管看②每个人在公告板上写字,其他人可以看、也可以改对于第①种情况,我们把信息提前写在web.xml文件中,然后用ServletContext读取:
![7d1f937fe1898178be065f33e26b0e23.png](https://i-blog.csdnimg.cn/blog_migrate/d9603ab69f700b6ee6aceb43635bbdaf.png)
String strDebugMode = context.getInitParameter("DebugMode");
对于第②种情况,我们直接用
S
ervletContext
读写数据:
context.setAttribute("名称", "值");context.getAttribute("名称");
此外,有些工作需要多个Servlet合作完成:每人完成一部分,然后整合到一起。整合方式有两种:①交给下一个人,由他整合②拿到下一个人的结果,我来整合对于第①种情况,使用
forward:
context.getRequestDispatcher("/servlet2") .forward(request, response);
对于第②种情况,使用 include:
context.getRequestDispatcher("/servlet2") .include(request, response);
5.如何保存会话数据?
会话的实现,是浏览器cookie和服务器 HttpSession配合的结果。第一次用到会话时,通过请求来创建:HttpSession session = request.getSession();
然后,可以在session中存储数据:
session.setAttribute("名称", "值");
Servlet返回响应时,会把sessionId写入cookie;浏览器下次发请求时,
s
essionI
d
被自动携带;此时,我们再次获取会话:
HttpSession session = request.getSession();
它自动用sessionId查找到上次的session,我们可以读取上次存储的数据:
session.getAttribute("名称");
这样,就实现了一个session被多个请求共享的效果,cookie用sessionId串起了多个请求,这就是会话的原理。如果用户退出系统,我们想让session立即失效,可以用下面的代码:
session.invalidate();
通常,为了保护账户安全,只要
浏览器长时间不发请求,session就应该自动失效,我们称之为session过期时间,在web.xml文件中配置:
![ddbd562acad6eec5a71ed23ef34b99cf.png](https://i-blog.csdnimg.cn/blog_migrate/86c92a0cb11f4126716ff2142d7869ee.png)
6.如何读写cookie?
Servlet专门定义了Cookie类,用以封装cookie的数据。从 请求中读cookie:Cookie[] cookies = request.getCookies();for (Cookie c : cookies) { String name = c.getName(); // 名称 String value = c.getValue(); // 值}
往响应中写cookie:
Cookie cookie = new Cookie("名称", "值");response.addCookie(cookie);