1,request对象和resqonse对象的原理
- request对象是来获取请求消息,response对象是来设置响应消息的
request
1,request对象继承体系结构:
ServletRequest(接口)----(继承自)----HttpServletRequest(接口)----(继承自)----org.apache.catalina.connector.requestFacade(类tomcat)
2,request功能:获取请求对象消息
- 获取请求行数据:
- GET /day14/demo1?name=zhangsan HTTP/1.1
- 方法:
- 1,获取请求方式 :GET
String getMethod()
2,获取虚拟目录:/day14_request_war_exploded
String getContextPath()
- 3, 获取Servlet路径:/RequestDemo1
String getServletPath()
- 4, 获取get方式请求参数:name=zhangsan
String getQueryString()
5,获取请求URI:/day14_request_war_exploded/RequestDemo1
String getRequestURI()
:/day14_request_war_exploded/RequestDemo1StringBuffer getRequestURL()
:http://localhost:8080/day14_request_war_exploded/RequestDemo1- URL:统一资源定位符
- URI:统一资源标识符
- 6,获取协议以及版本号:HTTP/1.1
String getProtocol()
- 7,获取客户机的IP地址:
String getRemoteAddr()
- 1,获取请求方式 :GET
示例:
package cn.jsp.web.request;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 演示Request对象获取请求行数据
*/
@WebServlet("/RequestDemo1")
public class RequestDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求方式
String method = request.getMethod();
System.out.println(method);
//获取虚拟目录
String contextPath = request.getContextPath();
System.out.println(contextPath);
//获取Servlet路径
String servletPath = request.getServletPath();
System.out.println(servletPath);
//获取get方式请求参数
String queryString = request.getQueryString();
System.out.println(queryString);
//获取请求URI
String requestURI = request.getRequestURI();
System.out.println(requestURI);
StringBuffer requestURL = request.getRequestURL();
System.out.println(requestURL);
//获取协议以及版本
String protocol = request.getProtocol();
System.out.println(protocol);
//获取客户机IP
String remoteAddr = request.getRemoteAddr();
System.out.println(remoteAddr);
}
}
运行结果:
-
获取请求头数据:
-
方法:
- 1,
String getHeader(String name)
:通过请求头的名称获取请求头的值
package cn.jsp.web.request; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Enumeration; @WebServlet("/RequestDemo2") public class RequestDemo2 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //演示获取请求头数据 //1,获取所有请求头名称 Enumeration<String> headerNames = request.getHeaderNames(); //遍历 while (headerNames.hasMoreElements()){ String name = headerNames.nextElement(); //根据名称获取请求头的值 String value = request.getHeader(name); System.out.println(name + "---" + value); } } }
运行结果:
host---localhost:8080 connection---keep-alive cache-control---max-age=0 upgrade-insecure-requests---1 user-agent---Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3947.100 Safari/537.36 accept---text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 accept-encoding---gzip, deflate, br accept-language---zh-CN,zh;q=0.9 cookie---JSESSIONID=AFA50683AA3D9544C967B201C7F2580F; Idea-712eb87f=92c060fc-0b9a-4df6-b2c3-cb9900a2b912
- 2,
Enumeration<String> getHeaderNames()
:获取所有的请求头名称
- 1,
-
-
获取请求体数据:
- 请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数
- 步骤:
- 1,获取流对象:
BufferedReader getReader()
:获取字符输入流,只能操作字符数据ServletInputStream getInputStream()
:获取字节输入流,可以操作所有类型数据
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取请求消息体---请求参数 //1,获取字符流 BufferedReader br = request.getReader(); //2,读取数据 String line = null; while((line = br.readLine()) != null){ System.out.println(line); } }
- 1,获取流对象:
-
其他功能:
-
1,获取请求参数通用方式:get和post请求都可以使用下列方法获取
- 1,
String getParameter(String name)
:根据参数名称获取参数值 - 2,
String[ ] getParameterValues(String name)
:根据参数名称获取参数值的数组 - 3,
Enumeration<String> getParameterNames()
:获取所有请求参数的参数名称 - 4,
Map<String,String[]> getParameterMap()
:获取所有参数的map集合
package cn.jsp.web.request; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Map; import java.util.Set; @WebServlet("/requestDemo6") public class RequestDemo6 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //post 获取请求参数 //设置流的编码 request.setCharacterEncoding("utf-8") //根据参数名称获取参数值 String username = request.getParameter("username"); //根据参数名称获取参数值的数组 String[] hobbies = request.getParameterValues("hobby"); /* for (String hobby : hobbies){ System.out.println(hobby); } */ //获取所有请求参数的参数名称 /* Enumeration<String> parameterNames = request.getParameterNames(); while (parameterNames.hasMoreElements()){ String name = parameterNames.nextElement(); System.out.println(name); String value = request.getParameter(name); System.out.println(value); System.out.println("--------------------------------"); } */ //获取所有参数的map集合 Map<String, String[]> parameterMap = request.getParameterMap(); //遍历 Set<String> keyset = parameterMap.keySet(); for (String name : keyset){ //获取键获取值 String[] values = parameterMap.get(name); System.out.println(name); for (String value :values){ System.out.println(value); } System.out.println("-------------------------"); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /*//get 获取请求参数 //根据参数名称获取参数值 String username = request.getParameter("username"); System.out.println("get"); System.out.println(username);*/ this.doPost(request,response); } }
- 中文乱码问题:
- get方式:tomcat8已经将get方式乱码问题解决
- post方式:会乱码
- 解决:在获取参数前,设置request的编码
request.setCharacterEncoding("utf-8");
- 1,
-
2,请求转发:一种在服务器内部的资源跳转的方式
-
步骤:
- 1,通过request对象获取请求转发器对象:
RequestDispatcher getRequestDispatcher(String path)
- 2,使用RequestDispatcher对象来进行转发:
forward(ServletRequest request,ServletResponse response)
- 下面是主要实现代码:
//转发到demo8资源 /* RequestDispatcher requestDispatcher = request.getRequestDispatcher("requestDemo8"); requestDispatcher.forward(request,response); */ request.getRequestDispatcher("/requestDemo8").forward(request,response);
- 1,通过request对象获取请求转发器对象:
-
特点:
- 1,浏览器地址栏路径不发生变化
- 2,只能转发到当前服务器内部资源中
- 3,转发是一次请求
-
-
3,共享数据
-
域对象:一个有作用范围的对象,可以在范围内共享数据
-
request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
-
方法:
- 1,
void setAttribute(String name,Object obj)
:存储数据
//存储数据到request域中 request.setAttribute("msg","hello");
- 2,
Object getAttribute(String name)
:通过键获取值
//获取数据 Object msg = request.getAttribute("msg"); System.out.println(msg);
- 3,
void removeAttribute(String name)
:通过键移除键值对
- 1,
-
-
4,获取ServletContext:
ServletContext getServletContext()
:ServletContext servletContext = request.getServletContext();
-
BeanUtils工具类
简化数据封装:commons-beanutils-1.8.0.jar
用于封装JavaBean的
- JavaBean:标准Java类
- 1,要求:
- 1,类必须被public修饰
- 2,必须提供空参的构造器
- 3,成员变量必须使用private修饰
- 4,提供公共的setter和getter方法
- 2,功能:封装数据
- 1,要求:
示例:
/*
//获取请求参数
String username = request.getParameter("username");
String password = request.getParameter("password");
//封装user对象
User loginUser = new User();
loginUser.setUsername(username);
loginUser.setPassword(password);
*/
//获取所有请求参数
Map<String, String[]> map = request.getParameterMap();
//创建User对象
User loginUser = new User();
//使用BeanUtils封装
try {
BeanUtils.populate(loginUser,map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
Response
响应消息:服务器端发送给客户端的数据
- 数据格式:
-
1,响应行
- 1,组成:协议/版本 响应状态码 状态码描述
- 2,响应状态码:服务器告诉客户端浏览器本次请求和响应的一个状态
- 3,响应状态码分类:
- 1,1xx:服务器接收客户端消息,但没有接收完成,等待一段时间后,发送1xx多状态码
- 2,2xx:成功。代表:200
- 3,3xx:重定向。代表:302(重定向),304(访问缓存)
- 4,4xx:客户端错误。代表:404(请求路径没有对应的资源);405(请求方式没有对应的doXxx方法)
- 5,5xx:服务端错误。代表:500(服务器端出现异常)
-
2,响应头
- 1,格式:
头名称:值
- 2,常见的响应头:
- 1,Content-Type:服务器告诉客户端本次响应体数据格式以及编码格式
- 2,Content-disposition:服务器告诉客户端以什么格式打开响应体数据
- in-line:默认值,在当前页面内打开
- attachment;filename-xxx:以附件形式打开响应体。文件下载
- 1,格式:
-
3,响应空行
-
4,响应体:传输的数据
-
Response对象
功能:设置响应消息
- 1,设置响应行
- 1,格式:HTTP/1.1 200 OK
- 2,设置状态码:
setStatus(int sc)
- 2,设置响应头:
setHeader(String name,String value)
- 3,设置响应体
- 使用步骤:
- 1,获取输出流
- 字符输出流:
PrintWriter getWriter()
- 字节输出流:
ServletOutputStream getOutputStream()
- 字符输出流:
- 2,使用输出流,将数据输出到客户端浏览器
- 1,获取输出流
- 使用步骤:
案列
1,完成重定向
- 重定向:资源跳转的方式
//访问/responseDemo1会自动跳转到/responseDemo2
/*//1,设置状态码为302
response.setStatus(302);
//2,设置响应头location
response.setHeader("location","/day15/responseDemo2");
*/
//简单的重定向方法
response.sendRedirect("/day15/responseDemo2");
- 重定向的特点:redirect(和转发(forward)的特点对比)
- 1,地址栏发生变化
- 2,重定向可以访问其他站点(服务器)的资源
- 3,重定向是两次请求,不能使用reques对象来共享数据。
2,服务器输出字符数据到浏览器
步骤:
- 1,获取字符输出流
- 2,输出数据
注意乱码问题:解决办法如下
//设置编码
//resp.setCharacterEncoding("utf-8");
//告诉浏览器,服务器发送消息体数据的编码,建议浏览器使用该编码
//resp.setHeader("content-type","text/html;charset=utf-8");
//简单形式设置编码,在获取流之前
resp.setContentType("text/html;charset=utf-8");
//获取字符输出流
PrintWriter pw = resp.getWriter();//获取的流默认编码是ISO-8859-1
//输出数据
//pw.write("<h1>hello response</h1>");
pw.write("你好,response");
3,服务器输出字节数据到浏览器
步骤:
- 1,获取字节输出流
- 2,输出数据
//简单形式设置编码
resp.setContentType("text/html;charset=utf-8");
//获取字节输出流
ServletOutputStream sos = resp.getOutputStream();
//输出数据
sos.write("你好,hello".getBytes("utf-8"));
ServletContext 对象
1,概念:代表整个web应用,可以和整个程序的容器(服务器)来通信
2,获取
- 1,通过request对象获取
request.getServletContext();
- 2,通过HttpServlet获取
this.getServletContext();
3,功能:
- 1,获取MIME类型:
- MIME类型:在互联网通信过程中定义的一种文件数据类型
- 格式: 大类型/小类型 text/html image/jpeg
- 获取:
String getMimeType(String file)
- MIME类型:在互联网通信过程中定义的一种文件数据类型
- 2,域对象:共享数据
- 1,
setAttribute(String name,Object value)
- 2,
getAttribute(String name)
- 3,
removeAttribute(String name)
- ServletContext对象范围:所有用户所有请求的数据
- 1,
- 3,获取文件的真实(服务器)路径
- 1,方法:
String getRealPath(String path)
- 1,方法:
//通过HttpServlet获取
ServletContext context = this.getServletContext();
//获取文件的服务器路径
String realPath = context.getRealPath("/b.txt");
File file = new File(realPath);
//System.out.println(realPath);
String c = context.getRealPath("/WEB-INF/c.txt");
System.out.println(c);
案例:文件下载
文件下载需求:
- 1, 页面显示超链接
- 2,点击超链接后弹出下载提示框
- 3,完成图片文件下载
步骤:
- 1,定义页面,编辑超链接href属性,指向Servlet,传递资源名称filename
- 2,定义Servlet
- 1,获取文件名称
- 2,使用字节输入流加载文件进内存
- 3,指定response的响应头:content-disposition:attachment;filename=xxx
- 4,将数据写出到response输出流
package cn.jsp.web.download;
import cn.jsp.web.utils.DownLoadUtils;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求参数,文件名称
String filename = request.getParameter("filename");
//使用字节输入流加载文件进内存
//找到文件服务器路径
ServletContext servletContext = this.getServletContext();
String realPath = servletContext.getRealPath("/img/" + filename);
//用字节流关联
FileInputStream fis = new FileInputStream(realPath);
//设置response的响应头
//设置响应头类型:content-type
String mimeType = servletContext.getMimeType(filename);//获取文件的mime类型
response.setHeader("content-type",mimeType);
//设置响应头打开方式:content-disposition
//解决中文文件名问题
//获取user-agent请求头
String agent = request.getHeader("user-agent");
//使用工具类方法编码文件名即可
filename = DownLoadUtils.getFileName(agent, filename);
response.setHeader("content-disposition","attachment;filename="+filename);
//将输入流的数据写出到输出流中
ServletOutputStream sos = response.getOutputStream();
byte[] buff = new byte[1024 * 8];
int len = 0;
while((len=fis.read(buff))!=-1){
sos.write(buff,0,len);
}
fis.close();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}