Request&Response原理
Request对象和response对象的原理
- request和response对象是由服务器创建的。我们来使用它们
- request对象是来获取请求消息。response对象是来设置响应消息
request&reponse对象原理
Request
Request对象继承体系结构
- ServletRequest -- 接口 <-- 继承 HttpServletRequest -- 接口 <-- 实现 org.apache.catalina.connector.RequestFacade
Request 功能
1. 获取请求消息数据
- 获取请求行数据
- GET /demo/demo1?name=zhangsan HTTP/1.1
- 方法
- 获取请求方式
- String getMethod()
- 获取虚拟目录 /demo/demo1中的/demo
- String getContextPath()
- 获取Servlet路径 /demo/demo1中的/demo1
- String getServletPath()
- 获取get方式请求参数 name=zhangsan
- String getQueryString()
- 获取请求uri: /demo/demo1
- String getRequestURI(): /demo/demo1
- String getRequestURL(): http://localhost/demo/demo1
- 获取协议及版本:HTTP/1.1
- String getProtocol() 获取请求协议
- 获取客户机IP地址
- String getRemoteAddr():
- 获取请求方式
- 方法
- 获取请求头数据
- 方法
- String getHeader(String name):通过请求头的名称获取请求头的值
- Enumeration<String> getHeaderNames():获取所有请求头名称
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取所有head的值
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String header = request.getHeader(headerNames.nextElement());
System.out.println(header);
}
}
- 获取请求体数据
- 只有POST请求方式才有请求体,在请求体中封装了POST请求的请求参数,将请求体封装为流对象
- 步骤
- 获取流对象
- BufferedReader getReader() 获取字符输入流 只能操作字符数据
- ServletInputStream getInputStream() 获取字节输入流,可以操作所有类型的数据(用于文件上传)
- 再从流对象中拿数据
- 获取流对象
//获取请求体
BufferedReader br = request.getReader();
String readLine = null;
while ((readLine = br.readLine()) != null) {
response.getWriter().write(readLine);
}
2. 其它功能
- 通用方式获取请求参数:适用于GET POST
String getParameter(String name):根据参数名称获取参数值 username=zs&password=123
String[] getParameterValues(String name) 根据参数名称获取参数值的数组 hobby=xxx&hobby=game
Enmmeration<String> getParameterNames() 获取所有请求的参数名称
Map<String,String[]> getParameterMap() 获取所有参数的键值对map
-
中文乱码问题
- GET方式:tomcat 8 已经将get方式乱码方式解决了
- POST方式:会乱码
解决:由于getParameter仍然是通过流的方式获取参数,所以我们解决乱码问题需要在获取参数前,设置request的编码
request.setCharacterEncoding("utf-8");
- 请求转发 一种在服务器内部的资源跳转方式
- 步骤:
- 通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
- 使用RequestDispatcher对象来进行转发:forward(ServletRequest request,ServletResponse response)
- 特点:
- 浏览器地址栏路径没有发生变化
- 只能访问当前服务器内部资源中
- 转发是一次请求
- 步骤:
- 数据共享
- 域对象:一个有作用范围的对象可以在范围内共享数据
- request域:作用范围为一次请求,一般用于请求转发的多个资源中共享数据
- 共享数据提供的方法:
* setAttributes(String name,Object obj) 存储数据
* getAttribute(String name):通过键获取值
* removeAtttibute(String name) 从域中移除数据
- 共享数据提供的方法:
- 获取ServletContext
- ServletContext getServletContext() 获取ServletContext
Response对象
- 功能:设置响应消息
- 设置响应头
- setHeader(String name,String value) 设置响应头
- 设置响应行
- 格式:HTTP/1.1 200 ok
- 设置状态码:setStatus(int sc)
- 设置响应体
- 使用步骤
- 获取输出流
- 字符输出流 PrinterWriter getWriter()
- 字节输出流 ServlletOutputStream getOutputStream()
- 使用输出流,将数据输出到客户端浏览器
- 获取输出流
案例
重定向
- 重定向是一种资源跳转的方式
- 方式1:先设置状态码302 设置响应头location为重定向的地址
//响应设置状态码
resp.setStatus(302);
//设置重定向路径
resp.setHeader("location","/reslsn/target");
- 方式2:使用sendRedirect(location)
resp.sendRedirect("/reslsn/target");
- 重定向的特点
- 重定向的地址栏会发生变化
- 重定向可以访问其他站点的资源
- 重定向是两次请求,不能使用request对象来共享数据
- 转发的特点
- 转发地址栏路径不变
- 转发只能访问当前服务器下的资源
- 转发只是一次请求,意味着可以使用request来共享数据
- 路径的写法
- 相对路径:通过相对路径不可以确定唯一资源
- ./index.html 不以/开头 以.开头 相对路径中的./是可以省略的
- 规则:确定访问当前资源和目标资源之间的相对位置关系
- ./:当前目录
- ../:后退一级目录
- 绝对路径:通过绝对路径可以确定唯一资源
- 如:http://localhost/xxx
- 以/开头的路径
- 规则:判断定义的路径是给谁用的?
- 给浏览器用的需要添加虚拟目录
- 建议虚拟目录动态获取:request.getContextPath()
- 给服务器用的不需要添加虚拟目录
- 给浏览器用的需要添加虚拟目录
服务器输出字符数据到浏览器
获取字符流
resp.getWriter().write()
设置响应编码 处理中文数据
使用Response setContextType() 指定编码为:text/html;charset=编码
服务器输出字节数据到浏览器
获取字节输出流
ServletOutPutStream sos = resp.getOutPutStream();
sos.write(byte)
ServletContext
概念:
ServletContext对象代表整个web工程,可以和程序的容器(服务器)来通信
获取
- 通过Request对象获取:Request.getServletContext()
- 通过HttpServlet获取:this.getServletContext()
功能
- 获取MIME类型:MIME是互联网中的一种文件类型
- MIME类型:在互联网通信过程中定义的一种文件数据类型
- 格式:大类型/小类型 text/html
- 获取 String getMimeType(String)
- ServletContext是一个域对象,可以用来共享数据
- setAttribute(String name,Object value)
- getAttribute(String name)
- removeAttribute(String name)
ServletContext域对象的范围:ServletContext代表整个Web项目,作用范围是最大的,可以共享所有用户的数据
- 获取文件的真实路径(服务器路径)
- String getRealPath("")
ServletContext context = this.getServletContext();
String realPath - context.getRealPath("/b.txt") //资源在web目录下 获取路径
String c = context.getRealPath("/WEB-INF/c.txt");//资源在WEB-INF目录下的资源访问
String a = context.getRealPath("/WEB-INF/classes/a.txt");//资源在src目录下的路径访问