一、response
作用:往浏览器写东西。组成部分:响应行、响应头、响应体。
1.操作响应行
格式:协议/版本 状态码 状态码说明
状态码:
1. 1xx:已发送请求
2. 2xx:已完成响应
3. 200:正常响应
4. 3xx:还需浏览器进一步操作
5. 302:重定向 配合响应头:location
6. 304:读缓存
7. 4xx:用户操作错误
8. 404:用户操作错误.
9. 405:访问的方法不存在
10. 5xx:服务器错误
11. 500:内部异常
常用方法:setStatus(int 状态码):针对于 1 2 3
了解方法:sendError(int 状态码):针对于 4xx和5xx
操作响应头:
setHeader(String key,String value):设置字符串形式的响应头
了解:setIntHeader(String key,int value):设值整数的响应头
了解:setDateHeader(String key,long value):设值时间的响应头
addHeader(String key,String value):添加置字符串形式的响应头 之前设置过则追加,若没有设置过则设置
了解:addIntHeader(String key,int value):添加整形的响应头
了解:addDateHeader(String key,long value):添加时间的响应头
常用的响应头:
location:重定向
refresh:定时刷新
content-type:设置文件的mime类型,设置响应流的编码及告诉浏览器用什么编码打开
content-disposition:文件下载
2.重定向
方式1:
response.sendRedirect("/day10/loc2");主要用这种
方式2:
response.setStatus(302);
respooen.setHeader("location","/day10/loc2");
3.定时刷新
方案1:设置头 refresh
respooen.setHeader("refresh","秒数;url=跳转的路径");
方案2:http的meta标签
<meta http-equiv="refresh" content="3;url=/day10/refresh2.html">
4.操作响应体
常用方法:Writer getWriter():字符流、ServletOutputStream getOutputStream():字节流
注意:两个流互斥,当响应完成之后,服务器会判断流是否已经关闭,若没有关闭,服务器会关闭该流。
public class PrintSerlvet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//处理响应的中文乱码
//response.setContentType("text/html;charset=utf-8");
response.setHeader("content-type", "text/html;charset=utf-8");
//ServletOutputStream os = response.getOutputStream();
//打印表格
//获取字符流
PrintWriter w = response.getWriter();
w.print("<table border='1'><tr>");
w.print("<td>用户名:</td>");
w.print("<td>tom</td></tr>");
w.print("<tr><td>密码:</td>");
w.print("<td>123</td>");
w.print("</tr></table>");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
5.处理响应中文乱码
方式1:response.setContentType("text/html;charset=utf-8");主要用这种
方式2:response.setHeader("content-type", "text/html;charset=utf-8");
6.文件下载
方式1.超链接下载
<a href="/day10/download/day10.txt">下载 day10.txt</a>
若浏览器能解析该资源的mime类型,则直接打开;若不能,则下载。
方式2.编码下载,通过servlet完成,设置两个头和一个流。
<a href="/day10/download?name=day10.txt">下载 day10.txt</a>
public class DownServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
ServletContext context = this.getServletContext();
String filename = request.getParameter("name");
String mimeType = context.getMimeType(filename);
response.setContentType(mimeType);
response.setHeader("content-disposition", "attchment;filename=" + filename);
InputStream is = context.getResourceAsStream("down/" + filename);//文件在down目录下,down目录在web目录下
ServletOutputStream os = response.getOutputStream();
int len = -1;
byte[] b = new byte[1024];
while ((len = is.read(b)) != -1) {
System.out.println("out");
os.write(b, 0, 200);
}
os.close();
is.close();
}
}
扩展:使用commons-io工具类,简化流的操作
对拷流:
IOUtils.copy(is,os);
os.close();
is.close();
中文名称的文件名下载的时候名称会出现问题,中文部分会缺失,常见的浏览器需要提供文件名称的utf-8编码,对于火狐来说需要提供文件名称的base64编码
方案1:使用工具类DownLoadUtils
方案2:网上的方式(8成好使):new String(filename.getByte("gbk"),"iso8859-1");
二、request
作用:获取浏览器发送过来的数据。组成部分:请求行 请求头 请求体。
创建:一次请求来的时候
销毁:响应生成的时候
1.操作请求行
格式:请求方式 请求资源 协议/版本
常用方法:
String getMethod():获取请求方式
String getRemoteAddr():获取请求者的ip地址
String getContextPath() :在java中获取项目名称 (/day10),用于动态获取项目名称
了解方法:
getRequestURI():获取的是 从项目名到参数(?)之前的内容 /day10/regist
getRequestURL():获取的带协议的完整路径 http://localhost/day10/regist
String getQueryString():get请求的所有参数 username=tom&password=123
String getProtocol():获取协议和版本
2.操作请求头
格式:key/value(value可以是多个值)
常用方法:String getHeader(String key):通过key获取指定的value (一个)
了解方法:
Enumeration getHeaders(String name) :通过key获取指定的value(多个)
Enumeration getHeaderNames() :获取所有的请求头的名称
int getIntHeader(String key):获取整型的请求头
long getDateHeader(String key):获取时间的请求头
重要的请求头:
user-agent:浏览器内核 msie firefox chrome
referer:页面从那里来 防盗链
3.操作请求参数
常用方法:
String getParameter(String key):获取一个值
String[] getParameterValues(String key):通过一个key获取多个值
Map<String,String[]> getParameterMap():获取所有的参数名称和值
请求的中文乱码:
对于get请求,参数追加到地址栏,会使用utf-8编码,服务器(tomcat7)接受到请求之后,使用iso-8859-1解码,所以会出现乱码。对于post请求,参数是放在请求体中,服务器获取请求体的时候使用iso-8859-1解码,也会出现乱码。
通用的方法:
username = new String(参数.getBytes("iso-8859-1"),"utf-8");
针对于post请求(get不行),只需要将请求流的编码设置成utf-8即可,主要用下面这种方式。
request.setCharacterEncoding("utf-8");
扩展:
URLEncoder.encode(s, "utf-8"); 指定编码
URLDecoder.decode(s8, "iso8859-1");指定解码
4.请求转发
request.getRequestDispatcher("内部路径").forward(request,response);
请求转发和重定向区别:
重定向发送两次请求,请求转发一次请求;
重定向地址栏发生改变,请求转发不变;
重定向是从浏览器发送,请求转发是服务器内部;
重定向不存在request域对象,请求转发可以使用request域对象;
重定向是response的方法,请求转发是request的方法;
重定向可以请求站外资源,请求转发不可以。
扩展:封装数据,apache的BeanUtils
1.导入两个jar包(commons-beanutils-1.8.3.jar和commons-logging-1.1.1.jar)
2.调用 BeanUtils.populate(Object bean,map);
BeanUtils.populate(user, request.getParameterMap());