学习JavaWeb第十三天
Servlet进阶
HttpServletResponse接口的使用:
- 简介:服务器接收到请求需要进行处理,将处理以后的结果显示回浏览器端(将这个过程称为是响应Response)。
常规方法:
- Response设置响应行
- setStatus(int sc) //一般不用
- 200 正确
- 302 重定向
- 304 查找本地缓存
- SendError( int I ,String str);
- setStatus(int sc) //一般不用
- 设置响应头方法:
-
addHeader(String key,String value) 添加响应头,值为String类型
-
addIntHeader(String key,int value) 添加响应头,值为int类型
-
addDateHeader(String key,long l) 添加响应头,值为日期类型
-
setHeader(String key,String value) 更改响应头,值为String类型
-
setIntHeader(String key,int value)更改响应头,值为int类型
-
setDateHeader(String key,long l)更改响应头,值为日期类型
-
addHeader和setHeader区别:
- addHeader(), 最终得到响应头的结果 一个key对应多个value的情况
- setHeader(), 最终得到响应头的结果 一个key对应一个value的情况
-
字符流的中文乱码问题
- 产生乱码原因: 编码和解码不一致
- 原因:- 字符流是有缓冲区的,response获得字符流,response设计默认的缓冲区编码是ISO-8859-1。这个字符集不支持中文的。
- GET方式接收中文
Tomcat8.0版本之后, Tomcat自动处理了get请求的中文乱码问题
- 解决 :设置response获得字符流缓冲区的编码 与 设置浏览器默认打开时候采用的字符集一致即可。
- 响应乱码(比如说在网页输出的乱码问题):
- 方式一 :设置response获得字符流的缓冲区的编码:
response.setCharacterEncoding(“utf-8”);
response.setHeader(“Content-Type”,“text/html;charset=utf-8”); - 方式二:设置浏览器打开页面时采用的字符集
response.setContentType(“text/html;charset=utf-8”);
- 方式一 :设置response获得字符流的缓冲区的编码:
- 请求乱码(比如说网页提交数据的乱码问题)
- request.setCharacterEncoding(“utf-8”);
- 响应乱码(比如说在网页输出的乱码问题):
- tomcat运行时命令行乱码
- 在 tomcat的\conf\logging.properties中设置该属性:
- java.util.logging.ConsoleHandler.encoding = GBK
- 在 tomcat的\conf\logging.properties中设置该属性:
向浏览器写数据:
- 字符格式:response.getWriter() 返回字符流PrintWriter对象
- 字节格式:response.getOutputStream() 返回字节输出流ServletOutputStream对象,响应非文本类型的数据
- write和print区别:
- response.getWriter().write() 使用字符串数据,原样输出。若输出是整数,查询编码表编译相对应的字母。
response.getWriter().print() 无论什么,原样打印
response.getOutputStream().write() 写的是字节 - 注意点:这两个流不能够同时出现 即字节和 字符流不能同时出现,否则报错
- response.getWriter().write() 使用字符串数据,原样输出。若输出是整数,查询编码表编译相对应的字母。
响应头信息:
使用示例:
- 告诉浏览器以附件形式下载文件:response.setHeader(“content-disposition”, “attachment;filename=”+URLEncoder.encode(filename, “utf-8”));
- 解析:
- 设置其属性1 “content-disposition” 即MIME协议,告诉浏览器要下载文件的协议。
- 设置其属性2 “attachment;filename=123.txt” attachment属性即告诉浏览器以附件的方式下载文件 filename 告诉浏览器下载的文件名称
- 其中,filename的属性常常因为编码格式原因而乱码,解决方案:调用格式编码的工具类的encode()格式转换方法比如:URLEncoder.encode(filename, “utf-8”)
- 解析:
- 通过请求头,设置重定向链接为具体网页
- (前提条件:先设置页面为重定向状态 response.setStatus(302); )
- response.setHeader(“location”, “http://baidu.com”);//立刻跳转
- response.setHeader(“refresh”,“5;url=index.jsp”); //设置5秒后重定向的某个网页
- (前提条件:先设置页面为重定向状态 response.setStatus(302); )
- response.sendRedirect(request.getContextPath()+"/product?method=findAllPage");
- 页面重定向的方法 (要指明具体的项目 内外网都可以跳转到 )
- 例如:response.sendRedirect(“http://baidu.com”);
关于从服务器下载文件的使用步骤:
- 1、首先通过请求对象的getParameter方法获取网页表单的指定属性的属性值。getParameter(“filename”)
- 2、调用响应对象的setHeader方法,
- 3、调用请求体的getServletContext()方法,该方法返回的是一个ServletContext对象 (即全局域对象)
- 4、调用ServletContext对象的getRealPath(“img/”+filename)方法,获取相对路径所在的绝对路径
- 5、调用文件输入流读取该文件
- 6、调用响应体的getOutputStream()方法获取输出流。返回的是一个ServletOutputStream流对象。
- 7、调用ServletOutputStream流对象的write()方法将输入流 输出到客户端
- 8、关闭流资源
- 9、注意点:
- 在调用文件流后不可在调用其他字符流,比如说调用文本输出流会出错
核心代码:
String filename = request.getParameter("filename");
response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(filename, "utf-8"));
ServletContext context = request.getServletContext();
String realPath = context.getRealPath("img/"+filename);
System.out.println(realPath);
FileInputStream fis=new FileInputStream(realPath);
byte[] b=new byte[1024];
int len=-1;
//页面字节输出流
ServletOutputStream outputStream = response.getOutputStream();
while ((len=fis.read(b))!=-1) {
outputStream.write(b,0,len);
}
outputStream.close();
fis.close();
HttpServletRequest接口的使用:
-
request.getRequestDispatcher(“errorServlet”).forward(request,response);页面转发的方法(不用指明具体的项目,只能内网跳转)
-
Request对象获取请求头
- getHeader(String name) 获得一个key对应一个value的请求头
- getHeaderNames() 获取所有的请求头的键 返回的枚举类型Enumeration< String>
- 网站防盗链思想 request.getHeader(“Referer”);获取到对应的请求ip地址来区别判断
- 浏览器兼容思想 request.getHeader(“User-Agent”);获取到浏览器的名字等,分别适配
-
Request对象获取请求行
- 1.获取其提交方式:request.getMethod();
- 2.获取URI 请求的参数,请求服务器路径(不包含域名\端口号) request.getRequestURI();
- 3.获取URL 请求的参数,请求服务器路径(包含域名\端口号) request.getRequestURL()
- 4.获取请求行参数的部分:request.getQueryString();
- http://localhost:8080/MyDay13/m1?method=find //得到: method=find
- 5.获取协议以及版本:request.getProtocol();
- 6.获取web 的根目录:request.getContextPath();
- 7.获取servlet的路径,或者是名称:request.getServletPath();
- 8.获取请求客户端的ip地址:request.getRemoteAddr();
- 9.获取其端口号:request.getServerPort();
- 10.获取其协议:request.getScheme();
-
Request获取请求体参数
- String getParameter(表单中的name值) 获得提交的参数(一个name对应一个value)
- String[] getParameterValues(表单中的name值) 获得提交的参数(一个name对应多个value)
- Map<String,String[]> getParameterMap() 获得提交的参数,将提交的参数名称和对应值存入到一个Map集合中
Request域对象:客户端浏览器向服务器发送的一次请求信息的封装。那么实质上向Request中所保存的数据有效期也是一次请求范围。一次请求范围:从客户端浏览器向服务器发送一次请求,服务器针对这次请求对浏览器作出响应。当服务器作出响应之后,请求对象就销毁了,保存在其中的数据就无效了。
作为域对象 Request的方法:
- void setAttribute(String name, Object obj) 向Request域中保存数据
- Object getAttribute(String name) 从Request域中获取数据
- removeAttribute(String name) 从Request域中移除数据
关于请求转发和重定向区别:
- 请求转发: 转发路径不带工程名称 调用请求头对象的getRequestDispatcher("").forward(request,response);
- 重定向:重定向需要带工程名路径 或具体地址 调用响应头对象的sendRedirect(“http://baidu.com”)方法
- Request转发:在服务器内部执行,一次请求,url 地址不会发生改变,可以携带参数, 安全与效率高,可以访问到web-inf 下的资源
- Response:在客户端执行,二次请求,url地址是会发生改变,可以携带参数(一般不会使用),安全与效率低,跳转到另一个项目,不可以访问到web-inf下的资源
- 使用转发的前提:效率高,安全性,传递参数的时候,就使用转发,比如查询
- 使用重定向的前提:上一次连接与本次连接没有任何关系的时候的,不需要携带参数,需要跳转到其它项目,比如增加、删除、修改
- 由此:请求转发跳转页面,地址栏不会变更,可以获取到之前的request的属性
响应重定向跳转页面,地址栏产生变更,产生了二次请求,而request域是一次访问有效,所以不能获取之前的request的属性