
request和response是什么?
request是请求,在浏览器输入地址,回车,就是一个请求
response是响应,服务器根据请求,返回数据到浏览器显示,就是一个响应
API:
response
设置响应体实现输出数据
使用字节流向页面输出
程序以什么码表输出,就一定要控制浏览器以什么码表打开。
- 设置浏览器的编码
让浏览器的编码和字节数组的编码一致 可有如下两种写法:
1 | response.setHeader("Content-type","text/html;charset=UTF-8") |
- 设置字节数组的编码
用html技术的<meta>
标签可以模拟一个http响应头,<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
response可用setCharacterEncoding
方法设置码表。
字符流输出:PrintWritet->response->浏览器,response->浏览器默认使用iso-8859
编码
文件下载
使用ServerContext
的getRealPath
方法,再InputStream
和OutputStream
如果下载文件是中文名为中文,则文件名需要经过url
编码URLEncoder.encode
文件下载的基本实现的步骤
(0)设置头信息 Content-Disposition
,无论是什么格式的文件都以下载方式打开
(1)在服务器上面有一个可以下载的文件
(2)从服务器上拿到这个文件(使用文件输入流得到文件)
(3)使用输出流把文件写到浏览器1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//输入关联下载的资源
String path = "/download/a.zip";
InputStream is = getServletContext().getResourceAsStream(path);
int lastIndexOf = path.lastIndexOf("/");
String filename = path.substring(lastIndexOf+1);
response.setHeader("Content-Disposition", "attachment;filename="+filename);
OutputStream os = response.getOutputStream();
int len = 0;
byte[] b = new byte[8192];
while ((len=is.read(b))!=-1) {
os.write(b, 0, len);
}
is.close();
os.close();
}
随机图片
使用BufferedImage
在内存生成图片,再使用ImageIO
输出。
画图使用Graphics
,旋转使用Graphics2D
汉字的区间:\u4e00
-\u9fa5
刷新和缓存
刷新:一般不在servlet里加refresh
头,而是在jsp
加入<meta>
头模拟。
缓存:加入expires
头,当前时间+要缓存的时长
请求重定向
重定向
- 设置状态码和
location
头即可,或者直接使用response
的sendRedirect
方法。 - 向服务器两次请求。
- 浏览器会改变地址栏,一般适用于登录、购物等场景。
转发
- 调用
ServletContex
对象的getRequestDispatcher
方法,再调用forward
方法。 - 向服务器一次请求,浏览器地址栏不变。
一些细节:
getOutputStream
和getWriter
方法跟别用于输出二进制数据、输出文本数据的ServletOutputStream
、Printwriter
对象,这两个方法相互排斥,只能调用其中一个,否则抛IllegalStateException
异常。response
的输出流会自己关闭。Servlet的service
方法结束后,Servlet引擎会检查并调用close
方法关闭该输出流对象。
Request
获取请求的基本信息
- URI:标识某个资源
- URL:标识互联网上某个资源
- 获取请求的url和uri
String url = request.getRequestURL().toString(); System.out.println(url); String uri = request.getRequestURI().toString(); System.out.println(uri);
- 获取url后面的请求参数部分的字符串
String params = request.getQueryString(); System.out.println(params);
- 获取请求方式
String method = request.getMethod(); System.out.println(method);
- 获取主机名,IP地址
String addr = request.getRemoteHost() + request.getRemotePort() + request.getRemoteAddr() + "==user=" + request.getRemoteUser(); System.out.println("addr: " + addr);
- 获取 Contexpath
String contextPath = request.getContextPath(); response.sendRedirect(contextPath + "/index.jsp");
中文乱码
url后面如果有中文数据,需要编码后再提交
表单提交的数据使用的码表和该页面的码表一致,而getParameter
方法默认使用ISO-8859
码表。
解决:
- 对于
post
提交的数据,在获取数据前要使用request
对象的setCharacterEncoding
设置码表。 - 对于
get
提交的数据,只能手工解决。先对数据调用getBytes("ISO-8859-1")
获取二进制字节,再用特定码表构建字符串。 - 超链提交的中文,解决办法同get提交的数据。
也可以通过改服务器配置来解决乱码问题,但一般不建议使用。 URIEncoding
:改tomcat的配置文件conf/server.xml
的连接器<Connector>
中的URIEncoding
属性useBodyEncodingForURI
:将conf/server.xml
的连接器<Connector>
中的useBodyEncodingForURI
置为true
请求转发
应用场景:MVC设计模式
- model : javabean;
- view : jsp;
- controller : servlet
使用request域对象把数据带给转发资源。调用request
对象的getRequestDispatcher
方法,再调用forward
方法。一次请求,浏览器地址栏不变。
forward
一些细节
- 不能在关闭输出流后再调用转发,也不能调用两次,否则会抛出异常。
- 跳转之前会清空response中的数据。即数据只是写入到缓冲区而没真正输出到客户端,则可调用forward方法,原来写入到缓冲区的内容被清空,但响应头字段信息保持。
include
方法可以用于包含一些公共页面(一般不在servlet中包含)
地址的写法
以斜杠/
开头。如果是给服务器用,则/
代表当前web应用;如果给浏览器用,则/
代表网站。
拾遗
1 使用字节流向页面输出
解决方法:
- 设置浏览器的编码
- 设置字节数组的编码
让浏览器的编码和字节数组的编码一致
1 | // <meta http-equiv="content-type" content="text/html; charset=UTF-8"> |
2 使用字符流向页面输出
解决方法:
- 设置response缓冲区的编码
- 设置浏览器的编码
response缓冲区的编码和浏览器的编码一致
1 | response.setCharacterEncoding("UTF-8"); |
3 字符流向页面输出中文乱码问题解决,简写方式1
2
3// <meta http-equiv="content-type" content="text/html; charset=UTF-8">
reesponse.setContentType("text/html; charset=UTF-8");
response.getWriter().write("4.2 ,简写 ,使用字符流向页面输出内容");
链接
有价值的内容包括:
验证码的案例
设置定时跳转