本节内容
1.HttpServletRequest对象
2.HttpServletResponse对象
3.会话追踪
4.session与cookie
Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。
request和response对象即然代表请求和响应,那我们要获取客户机提交过来的数据,只需要找request对象就行了。要向客户机输出数据,只需要找response对象就行了。
一、HttpServletRequest
HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息。
常用方法:
getRequestURL方法返回客户端发出请求时的完整URL。
getRequestURI方法返回请求行中的资源名部分。
getQueryString 方法返回请求行中的参数部分。
getPathInfo方法返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以“/”开头。
getRemoteAddr方法返回发出请求的客户机的IP地址。
getRemoteHost方法返回发出请求的客户机的完整主机名。
getRemotePort方法返回客户机所使用的网络端口号。
getLocalAddr方法返回WEB服务器的IP地址。
getLocalName方法返回WEB服务器的主机名
package com.xk; import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class LoginServlet */ public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public LoginServlet() { super(); // TODO Auto-generated constructor stub } @Override public void init(ServletConfig config) throws ServletException { } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /** * 1.获得客户机信息 */ String requestUrl = request.getRequestURL().toString();//得到请求的URL地址 String requestUri = request.getRequestURI();//得到请求的资源 String queryString = request.getQueryString();//得到请求的URL地址中附带的参数 String remoteAddr = request.getRemoteAddr();//得到来访者的IP地址 String remoteHost = request.getRemoteHost(); int remotePort = request.getRemotePort(); String remoteUser = request.getRemoteUser(); String method = request.getMethod();//得到请求URL地址时使用的方法 String pathInfo = request.getPathInfo(); String localAddr = request.getLocalAddr();//获取WEB服务器的IP地址 String localName = request.getLocalName();//获取WEB服务器的主机名 System.out.println(requestUrl); System.out.println(requestUri); System.out.println(queryString); System.out.println(remoteAddr); System.out.println(remoteHost); System.out.println(remotePort); System.out.println(remoteUser); System.out.println(method); System.out.println(pathInfo); System.out.println(localAddr); System.out.println(localName); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
获取请求头信息
getHeader(string name)方法:String
getHeaders(String name)方法:Enumeration
getHeaderNames()方法
package com.xk; import java.io.IOException; import java.util.Enumeration; import javax.servlet.RequestDispatcher; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class LoginServlet */ public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public LoginServlet() { super(); // TODO Auto-generated constructor stub } @Override public void init(ServletConfig config) throws ServletException { } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取所有的头信息的名称 Enumeration<String> requestHeader=request.getHeaderNames(); while (requestHeader.hasMoreElements()) { String name=requestHeader.nextElement(); //获取头信息 String value= request.getHeader(name); System.out.println(name+"------"+value); } } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
accept------image/gif, image/jpeg, image/pjpeg, application/x-ms-application, application/xaml+xml, application/x-ms-xbap, */* accept-language------zh-CN ua-cpu------AMD64 accept-encoding------gzip, deflate user-agent------Mozilla/5.0 (Windows NT 6.2; Win64; x64; Trident/7.0; rv:11.0) like Gecko host------localhost:8080 connection------Keep-Alive
获取客户端请求参数:
getParameter(String)方法(常用) getParameterValues(String name)方法(常用) getParameterNames()方法(不常用) getParameterMap()方法(编写框架时常用)
package com.xk; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class RegisterServlet */ @WebServlet("/RegisterServlet") public class RegisterServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public RegisterServlet() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.getWriter().append("Served at: ").append(request.getContextPath()); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 接收前端form表单提交的数据:通过form表单中标签的name属性来获取值 String userid = request.getParameter("userid"); String username = request.getParameter("username"); String userpass = request.getParameter("userpass"); String sex = request.getParameter("sex"); String dept = request.getParameter("dept"); // 获取选中的兴趣,因为可以选中多个值,所以获取到的值是一个字符串数组,因此需要使用getParameterValues方法来获取 String[] insts = request.getParameterValues("inst"); String note = request.getParameter("note");// 获取填写的说明信息 String hiddenField = request.getParameter("hiddenField");// 获取隐藏域的内容 } }
接收表单数据中文乱码问题:
由于客户端与服务器编码不一致。解决办法:统一编码
如果是POST请求使用:
//解决中文乱码 request.setCharacterEncoding("utf-8");
如果是GET请求:
如果你使用的是Tomcat8以下的,需要处理,如果使用的是Tomcat8以上的不需要处理。
String username = request.getParameter("username"); //get处理乱码 String name= new String(username.getBytes("iso-8859-1"),"utf-8");
使用request进行转发:
请求转发:指一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理
1、通过ServletContext的getRequestDispatcher(String path)方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发。
2、通过request对象提供的getRequestDispatche(String path)方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发。
//请求转发 request.getRequestDispatcher("/login.com").forward(request, response);
request对象作为一个域对象(Map容器)使用时,主要是通过以下的四个方法来操作
- setAttribute(String name,Object o)方法,将数据作为request对象的一个属性存放到request对象中,例如:request.setAttribute("data", data);
- getAttribute(String name)方法,获取request对象的name属性的属性值,例如:request.getAttribute("data")
- removeAttribute(String name)方法,移除request对象的name属性,例如:request.removeAttribute("data")
- getAttributeNames方法,获取request对象的所有属性名,返回的是一个,例如:Enumeration<String> attrNames = request.getAttributeNames();
二、HttpServletResponse对象
HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法
负责向客户端(浏览器)发送数据的相关方法
负责向客户端(浏览器)发送响应头的相关方法
负责向客户端(浏览器)发送响应状态码的相关方法
Response对象的使用:
向浏览器响应数据:使用 OutputStream流
package com.xk; import java.io.IOException; import java.io.OutputStream; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class RegisterServlet */ @WebServlet("/RegisterServlet") public class RegisterServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public RegisterServlet() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String data = "这是OutputStream流输出"; // 获取OutputStream输出流 OutputStream out = response.getOutputStream(); // 通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码 response.setHeader("content-type", "text/html;charset=UTF-8"); // 将字符转换成字节数组,指定以UTF-8编码进行转换 byte[] dataByteArr = data.getBytes("UTF-8"); // 使用OutputStream流向客户端输出字节数组 out.write(dataByteArr); } }
使用:PrintWriter
在获取PrintWriter输出流之前首先使用"response.setCharacterEncoding(charset)"设置字符以什么样的编码输出到浏览器,如:response.setCharacterEncoding("UTF-8");设置将字符以"UTF-8"编码输出到客户端浏览器,然后再使用response.getWriter();获取PrintWriter输出流,这两个步骤不能颠倒
package com.xk; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class RegisterServlet */ @WebServlet("/RegisterServlet") public class RegisterServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public RegisterServlet() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String data = "这是OutputStream流输出"; //设置将字符以"UTF-8"编码输出到客户端浏览器 response.setContentType("text/html;charset=utf-8"); /*PrintWriter out = response.getWriter();这句代码必须放在response.setCharacterEncoding("UTF-8");之后 否则response.setCharacterEncoding("UTF-8")这行代码的设置将无效,浏览器显示的时候还是乱码*/ //获取PrintWriter输出流 PrintWriter out = response.getWriter(); //通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码 response.setHeader("content-type", "text/html;charset=UTF-8"); out.write(data); } }
HttpServletResponse常见应用——设置响应头控制浏览器的行为
设置http响应头控制浏览器禁止缓存当前文档内容
response.setDateHeader("expries", -1); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Pragma", "no-cache");
设置http响应头控制浏览器定时刷新网页(refresh)
response.setHeader("refresh", "5");//设置refresh响应头控制浏览器每隔5秒钟刷新一次
通过response实现请求重定向
请求重定向指:一个web资源收到客户端请求后,通知客户端去访问另外一个web资源,这称之为请求重定向
实现方式:response.sendRedirect(String location),即调用response对象的sendRedirect方法实现请求重定向
response.sendRedirect("register.html");
请求转发与请求重定向的区别:
转发:一次请求没有结束。
重定向: 一次请求结束,使用新的URL重新发起请求。
三、会话追踪
会话:会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。
有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学曾经来过,这称之为有状态会话
每个用户在使用浏览器与服务器进行会话的过程中,不可避免各自会产生一些数据,程序要想办法为每个用户保存这些数据。
保存会话数据的技术:
cookie:Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了
session:Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。
Cookie:
- 一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。
- 一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。
- 浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
- 如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。
cookie存取中文:
要想在cookie中存储中文,那么必须使用URLEncoder类里面的encode(String s, String enc)方法进行中文转码
Cookie cookie = new Cookie("userName", URLEncoder.encode("龙之殇", "UTF-8")); response.addCookie(cookie);
在获取cookie中的中文数据时,再使用URLDecoder类里面的decode(String s, String enc)进行解码
URLDecoder.decode(cookies[i].getValue(), "UTF-8")
Session:在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下)。因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,为用户服务
session与cookie:
- Cookie是把用户的数据写给用户的浏览器。
- Session技术把用户的数据写到用户独占的session中。
- Session对象由服务器创建,开发人员可以调用request对象的getSession方法得到session对象。
服务器创建session出来后,会把session的id号,以cookie的形式回写给客户机,这样,只要客户机的浏览器不关,再去访问服务器时,都会带着session的id号去,服务器发现客户机浏览器带session id过来了,就会使用内存中与之对应的session为之服务
session对象的创建时机
在程序中第一次调用request.getSession()方法时就会创建一个新的Session,可以用isNew()方法来判断Session是不是新创建的
//使用request对象的getSession()获取session,如果session不存在则创建一个 HttpSession session = request.getSession(); //获取session的Id String sessionId = session.getId(); //判断session是不是新创建的 if (session.isNew()) { response.getWriter().print("session创建成功,session的id是:"+sessionId); }else { response.getWriter().print("服务器已经存在session,session的id是:"+sessionId); }
session对象的销毁时机
session对象默认30分钟没有使用,则服务器会自动销毁session,在web.xml文件中可以手工配置session的失效时间
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>WebDemo1</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <!-- 设置Session的有效时间:以分钟为单位--> <session-config> <session-timeout>15</session-timeout> </session-config> </web-app>
当需要在程序中手动设置Session失效时,可以手工调用session.invalidate方法,摧毁session
HttpSession session = request.getSession();
//手工调用session.invalidate方法,摧毁session
session.invalidate();