请求和常用对象
常用方法
获取请求的完整路径 (从http开始,到?前面)
String url = request.getRequestURL() + "";
System.out.println("获取请求的完整路径: " + url);
获取请求的部分路径 (从项目站点名开始,到?前面)
String uri = request.getRequestURI();
System.out.println("获取请求的部分路径: " + uri);
获取请求的参数 (从?开始,到最后的字符串)
String query = request.getQueryString();
System.out.println("获取请求的参数: " + query);
获取请求类型 (GET/POST)
String method = request.getMethod();
System.out.println("获取请求类型: " + method);
获取协议版本 (HTTP/1.1)
String p = request.getProtocol();
System.out.println("获取协议版本: " + p);
获取站点名
String web = request.getContextPath();
System.out.println("获取站点名: " + web);
刷新和页面自动跳转
设置响应头
response.setHeader("uname", "zhangsan");
设置一个错误状态码
response.sendError(404);
response.sendError(404,"由于颜值过低,无法访问!");
设置每3秒刷新一次
response.setHeader("refresh", "3");
指定秒数后跳转到指定路径
response.setHeader("refresh", "3;URL=http://www.shsxt.com");
```s
## 获取请求头
获取指定请求头的值
```java
String host = request.getHeader("host");
String agent = request.getHeader("User-Agent");
System.out.println(host);
System.out.println(agent);
获取所有请求头的名称集合
Enumeration<String> enumeration = request.getHeaderNames();
// 遍历
while(enumeration.hasMoreElements()) {
System.out.println(enumeration.nextElement());
}
获取请求参数
获取指定名称的参数值
String uname = request.getParameter("uname");
String upwd = request.getParameter("upwd");
System.out.println("姓名:" + uname + ",密码:" +upwd);
获取指定名称的所有参数值
String[] hobbys = request.getParameterValues("hobbys");
if (hobbys != null && hobbys.length >0) {
for (String hobby : hobbys) {
System.out.println("爱好:" + hobby);
}
}
获取所有的参数名
Enumeration<String> enumeration = request.getParameterNames();
while (enumeration.hasMoreElements()) {
String string = (String) enumeration.nextElement();
System.out.println("参数名:" + string);
}
获取所有参数名与参数值的map的对象
Map<String, String[]> map = request.getParameterMap();
System.out.println(map.get("uname")[0]);
请求参数乱码问题
乱码场景:
Tomcat8及以上版本,
POST请求, 乱码,要处理
request.setCharacterEncoding("UTF-8");
GET请求, 不乱码,不处理
Tomcat7及以下版本
POST请求 , 乱码,要处理
request.setCharacterEncoding("UTF-8");
GET请求, 乱码,要处理
new String(request.getParameter("uname").getBytes("IS0-8859-1"),"UTF-8")
乱码原因:
由于现在的 request 属于接收客户端的参数,所以必然有其默认的语言 编码。
主要是由于在解析过程中默认使用的编码方式为 ISO-8859-1(此编码不支持中文),所以解析时一定会出现乱码。
解决方案:
要想解决这种乱码问题,需要设置 request 中的编码方式,告诉服务器以何种方式来解析数据。
- 设置服务器解析编码 request.setCharacterEncoding(“UTF-8”);
只针对POST请求有效,GET请求无任何影响 - 或者在接收到乱码数据以后,再通过相应的编码格式还原。
接收乱码数据,再转换编码格式
new String(request.getParameter("uname").getBytes("IS0-8859-1"),"UTF-8")
无论是GET请求还是POST请求,都有效
请求转发
请求转发,是一种服务器的行为。
当客户端请求到达后,服务器进行转发,此时会将请求对象进行保存;
地址栏中的 URL 地址不会改变,得到响应后,服务器端再将响应发送给客户端,从始至终只有一个请求发出。
实现方式如下,达到多个资源协同响应的效果
格式:
request.getRequestDispatcher("跳转的路径").forward(request, response);
特点:
1、服务端行为,服务端跳转
2、地址栏不会发生改变
3、request对象共享
数据响应
getWriter()获取字符流(只能响应回字符);
getOutputStream()获取字节流(能响应一切数据)。
响应回的数据到客户端被浏览器解析。
注意:两者不能同时使用。
java.lang.IllegalStateException: getWriter() has already been called for this response
// 设置响应类型
response.setContentType("text/html"); // html格式
/* 字符流 */
// 得到字符流
PrintWriter printWriter = response.getWriter();
printWriter.write("<h2>Hello Writer</h2>");
// 刷新
printWriter.flush();
// 关闭流
printWriter.close();
/* 子节流 */
// 得到字节流
ServletOutputStream out = response.getOutputStream();
// 输出
out.write("<h2>Hello output</h2>".getBytes());
out.close();
响应乱码
乱码原因:
服务器响应的数据也会经过网络传输,服务器端有一种编码方式,在客户端也存在一种编码方式,当两端使用的编码方式不同时则出现乱码。
getWriter()的字符乱码
响应中文必定出乱码,由于服务器端在进行编码时默认会使用 ISO-8859-1 格式的编码,该编码方式并不支持中文。
解决方案:
第一步: 设置服务端编码为UTF-8
response.setCharacterEncoding("UTF-8");
第二步: 设置客户端的编码
response.setHeader("content-type", "text/html;charset=utf-8");
总结:
设置服务端与客户端的编码一致,且都支持中文 (这一句可代替上面两句设置)
response.setContentType("text/html;charset=utf-8");
getOutputStream()字节乱码
对于 getOutputStream()方式获取到的字节流,响应中文时,由于本身就是传输的字节, 所以此时可能出现乱码,也可能正确显示.
当服务器端给的字节恰好和客户端使用的编码方式一致时则文本正确显示,否则出现乱码。
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置服务端的编码
//response.setCharacterEncoding("UTF-8");
// 设置客户端的编码
//response.setHeader("content-type", "text/html;charset=utf-8");
// 设置服务端与客户端的编码一致,且都支持中文 (这一句可代替上面两句设置)
response.setContentType("text/html;charset=utf-8");
/* getWriter()的字符乱码 */
/*response.getWriter().write("中国");
response.getWriter().close();*/
/* getOutputStream()字节乱码 */
response.getOutputStream().write("中国".getBytes());
response.getOutputStream().close();
响应图片
1、获取项目存放在服务器中的真实路径
request.getServletContext().getRealPath("/");
2、获取图片的路径
3、通过路径得到file对象
4、判断file对象是否存在,且是一个标准文件
5、得到文件的输入流
6、得到字节输出流
7、输出文件
8、关闭资源
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1、获取项目存放在服务器中的真实路径 request.getServletContext().getRealPath("/");
String realPath = request.getServletContext().getRealPath("/");
System.out.println(realPath);
// 2、获取图片的路径
String filePath = realPath + "WEB-INF/image/jay.jpg";
// 3、通过路径得到file对象
File file = new File(filePath);
// 4、判断file对象是否存在,且是一个标准文件
if (file.exists() && file.isFile()) {
// 5、得到文件的输入流
InputStream in = new FileInputStream(file);
// 设置响应类型
response.setContentType("image/jpeg");
// 6、得到字节输出流
ServletOutputStream out = response.getOutputStream();
// 7、输出文件
byte[] bytes = new byte[1024];
int len = 0;
while ((len = in.read(bytes)) != -1) {
out.write(bytes,0,len);
}
// 8、关闭资源
out.close();
in.close();
} else {
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("<h2>文件不存在!</h2>");
response.getWriter().close();
}
}
重定向
- 重定向是一种服务器指导,客户端的行为。
- 客户端发出第一个请求,被服务器接收,经过处理服务器进行响应,与此同时,服务器给客户端一个地址(下次请求的地址 resp.sendRedirect(“url”);),当客户端接收到响应后,立刻、马上、自动根据服务器 给的地址进行请求的发送第二个请求,服务器接收请求并作出响应,重定向完成。
- 特点:
-
1、客户端跳转
-
2、地址栏会发生改变
-
3、request对象不共享
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Servlet05...");
// 获取参数
System.out.println("用户名:" + request.getParameter("uname"));
// 设置域对象
request.setAttribute("userName", "admin");
// 重定向
// response.sendRedirect("index.html");
// response.sendRedirect("Servlet06");
// 请求转发
request.getRequestDispatcher("Servlet06").forward(request, response);
}
请求转发和重定向
1、请求转发是服务端跳转,重定向是客户端跳转
2、请求转发时地址栏不发生改变,重定向时地址栏发生改变
3、请求转发时request对象共享,重定向时request对象不共享
4、请求转发的地址只能在当前站点下,重定向的地址可以是任意路径
5、请求转发时request作用域有效,重定向时request域对象无效
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Servlet06...");
// 获取参数
System.out.println("用户名:" + request.getParameter("uname"));
// 获取域对象
System.out.println(request.getAttribute("userName"));
// 请求转发
// request.getRequestDispatcher("index.html").forward(request, response);
// request.getRequestDispatcher("http://www.baidu.com").forward(request, response); // 404
// 重定向
// response.sendRedirect("index.html");
// response.sendRedirect("http://www.baidu.com");
}
绝对路径和相对路径
相对路径:相对当前资源的路径
绝对路径:
以http://开头的路径,已经跨域,可以访问任意地址 (只有客户端跳转才可使用)
以/开头
请求转发
"/“代表的是"http://localhost:8080/站点名/”
重定向
"/“代表的是"http://localhost:8080/”
public class Servlet07 extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/* 请求转发跳转 */
// 相对路径 当前相对路径是"http://localhost:8080/站点名/"
//request.getRequestDispatcher("index.html").forward(request, response); // OK
// 绝对路径 当前"/"代表的含义"http://localhost:8080/站点名/"
// request.getRequestDispatcher("/index.html").forward(request, response); // OK
// 相对路径 当前相对路径是"http://localhost:8080/站点名/"
// request.getRequestDispatcher("sr03/index.html").forward(request, response); // 404 /sr03/sr03/index.html
// 绝对路径 当前"/"代表的含义"http://localhost:8080/站点名/"
// request.getRequestDispatcher("/sr03/index.html").forward(request, response); // 404 /sr03/sr03/index.html
// 绝对路径 跨域 (请求转发不能跨域!)
// request.getRequestDispatcher("http://localhost:8080/sr03/index.html").forward(request, response); // 404 /sr03/http://localhost:8080/sr03/index.html
/* 重定向跳转 */
// 相对路径 当前相对路径是"http://localhost:8080/站点名/"
// response.sendRedirect("index.html"); // OK
// 绝对路径 当前"/"代表的含义"http://localhost:8080/"
// response.sendRedirect("/index.html"); // 缺失站点名 http://localhost:8080/index.html
// 相对路径 当前相对路径是"http://localhost:8080/站点名/"
// response.sendRedirect("sr03/index.html"); // 404 /sr03/sr03/index.html
// 绝对路径 当前"/"代表的含义"http://localhost:8080/"
// response.sendRedirect("/sr03/index.html"); // OK
// 绝对路径 跨域 (请求转发不能跨域!)
response.sendRedirect("http://localhost:8080/sr03/index.html");
}
}
创建cookie和发送cookie
创建Cookie
// 创建Cookie
Cookie cookie = new Cookie("uname","admin");
// 发送cookie
response.addCookie(cookie);
Cookie的获取
- getCookies()的方法用来获取客户端回传的所有 cookie 组成的一个数组,
- 如果需要获取单个 cookie 则需要通过遍历,
- getName()获取 Cookie 的名称,getValue()获取 Cookie 的值。
Cookie[] cookies = request.getCookies();
// 非空判断
if (cookies != null && cookies.length >0) {
// 遍历cookie数组
for (Cookie cookie : cookies) {
// 获取cookie的名称和值
String name = cookie.getName();
String value = cookie.getValue();
// 如果有中文,获取时通过 URLDecoder.decode()来进行解码
name = URLDecoder.decode(name);
value = URLDecoder.decode(value);
System.out.println("名称:" + name + ",值:" + value);
}
}
Cookie到期时间的设定
-
到期时间,到期时间用来指定该 cookie 何时失效。
-
默认为当前浏览器关闭即失效。
-
设定 cookie 的有效时间(通过到期时间计算),通过 setMaxAge(int time);方法设定 cookie 的最大有效时间,以秒为单位。
-
maxAge
-
默认-1.表示只在当前浏览器中存活,关闭浏览器后失效
-
正整数:表示存活指定秒数。无论是关闭浏览器还是电脑,都会存活。
-
负整数:表示只在当前浏览器中存活,关闭浏览器后失效
-
零:表示即刻删除
// 创建Cookie对象
Cookie cookie = new Cookie("uname1","zhangsan");
// 设置cookie的失效
cookie.setMaxAge(-1); // 表示只在当前浏览器中存活,关闭浏览器后失效
// 响应Cookie
response.addCookie(cookie);
// 创建Cookie对象
Cookie cookie2 = new Cookie("uname2","lisi");
// 设置cookie的失效
cookie2.setMaxAge(20); // 存活20秒
// 响应Cookie
response.addCookie(cookie2);
// 创建Cookie对象
Cookie cookie3 = new Cookie("uname3","wangwu");
// 设置cookie的失效
cookie3.setMaxAge(0); // 删除
// 响应Cookie
response.addCookie(cookie3);
Cookie的注意点
1、不跨浏览器和电脑
2、不能存中文
Cookie 中不能出现中文,如果有中文则通过 URLEncoder.encode()来进行编码,获取时通过 URLDecoder.decode()来进行解码。
3、如果服务器端发送重复的Cookie那么会覆盖原有的Cookie。
String name = "姓名";
String value = "至尊宝";
// 如果有中文则通过 URLEncoder.encode()来进行编码
name = URLEncoder.encode(name);
value = URLEncoder.encode(value);
// 创建Cookie对象
Cookie cookie = new Cookie(name,value);
// 响应Cookie
response.addCookie(cookie);
// 创建相同name的cookie
Cookie cookie2 = new Cookie("uname","admin666");
// 响应Cookie
response.addCookie(cookie2);
Cookie的路径
只要访问的路径中包含path的值,就可访问到对应的cookie
“/” 表示表示只要在当前服务器下的所有项目都可访问
默认的路径都是在站点名下面的
// 创建cookie
Cookie cookie = new Cookie("haha","hahahahahahah");
// 响应Cookie
response.addCookie(cookie);
// 创建cookie
Cookie cookie2 = new Cookie("lala","lalalalalalla");
// 设置path
cookie2.setPath("/"); // 表示只要在当前服务器下的所有项目都可访问
// 响应Cookie
response.addCookie(cookie2);
// 创建cookie
Cookie cookie3 = new Cookie("xixi","xixixixixixi");
// 设置path
cookie3.setPath("/sc04/test");
// 响应Cookie
response.addCookie(cookie3);