Java Servlet 中 Request、Response讲解
一、request功能:
1.获取请求消息数据:
获取请求行数据:
GET /day16/demo1?name=zhangsan HTTP/1.1
-
获取请求方式:GET
String getMethod()
-
获取虚拟目录:/day16
String getContextPath()
-
获取Servlet路径:/demo1
String getServletPath()
-
获取get方式请求参数:name=zhangsan
String getQueryString()
-
获取请求URI: /day16/demo1
String getRequestURI():/day16/demo1
String getRequestURL()::http://localhost/day16/demo1
URL:统一资源定位符;
URI:统一资源标识符;
-
获取协议及版本:Http/1.1
String getProtocol()
-
获取客户机的IP地址:
String getRemoteAddr()
-
代码如下:
package cn.web.servlet; 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; @WebServlet("/demo1") // HttpServlet是一个抽象类, 继承的是GenericServlet类, GenericServlet类把所有方法都设置了默认值 , GenericServlet 继承了Servlet public class ServletDemo3 extends HttpServlet { /* HttpServlet可以通过请求方式进行分发 */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("调用的是Get方法"); // 1.获取请求方式 String method = req.getMethod(); System.out.println(method); // 输出结果:GET //2.获取虚拟目录 String contextPath = req.getContextPath(); System.out.println(contextPath); // 输出结果: /day_16 // 3.获取Servlet路径 String servletPath = req.getServletPath(); System.out.println(servletPath); // 输出结果:/demo1 // 4.获取get方式请求参数 String queryString = req.getQueryString(); System.out.println(queryString); //输出结果: name=zhangsan // 5.获取URI\URL String requestURI = req.getRequestURI(); System.out.println(requestURI); // 输出结果:/day_16/demo1 StringBuffer requestURL = req.getRequestURL(); System.out.println(requestURL); // 输出结果:http://localhost:8080/day_16/demo1 // 6.获取协议及版本 String protocol = req.getProtocol(); System.out.println(protocol); // 输出结果:HTTP/1.1 // 7.获取客户机的IP地址 String remoteAddr = req.getRemoteAddr(); System.out.println(remoteAddr); // 输出结果:0:0:0:0:0:0:0:1 } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("调用的是Post方法"); } }
获取请求头数据:
- 通过请求头的名称获取请求头的值:
String getHeader(String name)
-
获取所有的请求头名称:
Enumeration getHeaderNames()
-
代码实现:
package cn.web.servlet; 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("/demo05") public class ServletDemo05 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 演示获取请求头资源 // 1.获取所有请求头名称 Enumeration<String> headerNames = req.getHeaderNames(); // 2.遍历 while (headerNames.hasMoreElements()){ String name = headerNames.nextElement(); // 3. 根据名称获取请求头的值 String header = req.getHeader(name); System.out.println(header); } } }
获取请求体数据:
-
请求体:只有POST请求方式,才有请求体,在请求体中封装了POST请求的请求参数;
-
步骤:
- 获取流对象;
- BufferedReader getReader():获取字符输入流,只能操作字符数据;
- ServiletInputStream getInputStream():获取字节输入流,可以操作所有类型数据;
- 再从流对象中拿数据;
- 获取流对象;
-
代码:
// 字符输入流的样式 package cn.web.servlet; 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.BufferedReader; import java.io.IOException; @WebServlet("/demo06") public class ServletDemo06 extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取请求消息体.... 请求参数 // 1.获取字符流 BufferedReader reader = req.getReader(); String line = null; // 2.读取数据 while ((line = reader.readLine())!=null){ System.out.println(line); } } }
2.其它功能:
获取请求参数通用方式:不论get还是post请求方式都可以使用下列方法来获取请求参数
;
-
根据参数名称获取参数值:
String getParameter(String name)
比如:userName=zs&password=123
-
根据参数名称获取参数值的数组:
String[] getParameterValues(String name)
比如:body=xxx&body=yyy
-
获取所有请求参数名称:
Enumeration getParameterNames()
-
获取所有参数的map集合:
Map<String, String[]> getParameterMap()
代码:
package cn.web.servlet;
import javax.servlet.ServletConfig;
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;
import java.util.Map;
import java.util.Set;
@WebServlet("/demo07")
public class ServletDemo07 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("get");
// 1.根据参数名称获取参数值
String userName = req.getParameter("userName");
System.out.println(userName);
System.out.println("---------------------------");
// 2.根据参数名称获取数值的数组
String[] bodies = req.getParameterValues("body");
for (String body : bodies) {
System.out.println(body);
}
System.out.println("---------------------------");
// 3.获取所有请求的参数名称
Enumeration<String> parameterNames = req.getParameterNames();
while (parameterNames.hasMoreElements()){
String s = parameterNames.nextElement();
String parameter = req.getParameter(s);
System.out.println(parameter);
}
System.out.println("---------------------------");
// 4.获取所有参数的map集合
Map<String, String[]> parameterMap = req.getParameterMap();
Set<String> keySet = parameterMap.keySet();
for (String s : keySet) {
// 通过键获取值
String[] strings = parameterMap.get(s);
System.out.println(s);
for (String string : strings) {
System.out.println(string);
}
}
System.out.println("---------------------------");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("post");
// 无论请求post还是get 其它方式都可以运行
this.doGet(req, resp);
}
}
中文乱码问题:
get 方式:tomcat 8版本 已经讲 get 方式乱码问题解决了;
post 方式:会乱码;
- 解决:在获取参数前,设置request的编码 request.setCharacterEncoding(“utf-8”);
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("post"); // 将解决中文出现乱码情况 req.setCharacterEncoding("utf-8"); // 无论请求post还是get 其它方式都可以运行 this.doGet(req, resp); }
请求转发:一种在服务器内部的资源跳转方式;
- 步骤:
- 通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path);
- 使用 RequestDispatcher 对象进行转发:forward(ServletRequest request,ServletResponse response);
- 特点:
- 浏览器地址栏路径不会发生变化;
- 只能转发到当前服务器内部资源中;
- 转发是一次请求;
代码:
// demo08中的代码, 通过访问 /demo08 转发到 /demo09中
package cn.web.servlet;
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;
@WebServlet("/demo08")
public class ServletDemo08 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("demo08");
// 进行转发到 /demo09中
req.getRequestDispatcher("/demo09").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
// demo09 的代码
package cn.web.servlet;
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;
@WebServlet("/demo09")
public class ServletDemo09 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入___________demo09");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
// 输出结果:
demo08
进入___________demo09
共享数据:
-
域对象:一个有作用范围的对象,可以在范围内共享数据;
-
request 域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据;
-
方法:
- void setAttribute(String name,Object obj):存储数据;
- Object getAttitude(String name):通过键获取值;
- void removeAttribute(String name):通过键移除键值对;
-
代码:
// demo08中在域中设置对象 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("demo08"); // 存储数据到request 域中 req.setAttribute("msg", "hello!"); // 进行转发到 /demo09中 req.getRequestDispatcher("/demo09").forward(req, resp); }
// demo09 在域中获取对象 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("进入___________demo09"); // 获取数据 Object msg = req.getAttribute("msg"); System.out.println(msg); }
demo08 进入___________demo09 hello!
获取ServletContext:
概念:代表整个Web应用,可以和程序的容器(服务器)通信;
获取:
-
通过request对象获取;
request.getServletContext();
-
通过HttpServlet获取;
this.getServletContext();
// 获取ServletContext 对象
package cn.web.servlet;
import javax.servlet.ServletContext;
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;
@WebServlet("/servletContext")
public class ServletContextDemo extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取ServletContext
// 1.通过request对象获取
ServletContext context1 = request.getServletContext();
// 2.通过HttpServlet获取
ServletContext context2 = this.getServletContext();
// 比较两个context 是否相等
System.out.println(context1.equals(context2)); // 输出:true 说明获取ServletContext 两种方式都一样
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}
功能:
-
获取MIME类型;
-
MIME类型:在互联网通信过程中定义的一种文件数据类型:
-
格式:
大类型/小类型 text/html image/jpg
-
获取:String getMimeType(String file);
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1.通过HttpServlet获取 ServletContext context2 = this.getServletContext(); // 2.定义文件名称 String fileName = "a.jpg"; // 3.获取MIME 类型 String mimeType = context2.getMimeType(fileName); System.out.println(mimeType); // 输出结果: image/jpeg }
-
-
域对象:共享数据;
-
setAttribute(String name, Object value);
-
getAttrbute(String name);
-
removeAttribute(String name);
ServletContext对象资源,所有用户都能请求的数据;
-
-
获取文件的真实(服务器)路径;
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1.通过HttpServlet获取 ServletContext context2 = this.getServletContext(); // 2.获取文件的服务器路径 String realPath = context2.getRealPath("/a.text"); System.out.println(realPath); }
二、Response 功能:
1.功能:
设置响应信息:
- 格式:HTTP/1.1 200 ok
- 设置状态码:setStatus(int sc)
设置响应头:setHeader(String name,String value)
设置响应体:
-
获取输出流:
字符输出流:PrintWriter getWriter()
字节输出流:ServletOutputStream()
-
使用输出流,将数据输出到客户端浏览器;
案例实现:
-
重定向的案例:
// demo 重定向到 demo2中 以下是demo写法 package cn.web.servlet; 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; /* 完成重定向 */ @WebServlet("/responseDemo") public class ResponseDemo extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("demo被访问............"); /* 访问/responseDemo资源,会自动跳转到 /responseDemo02资源上 */ // 1.设置响应状态码信息, 302 表示重定向 // response.setStatus(302); // 2.设置响应头信息, 将返回定向资源的路径 // response.setHeader("location", "/day_16/responseDemo02"); // 最简单的重定向方法 response.sendRedirect("/day_16/responseDemo02"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
**重定向最简单的写法:**response.sendRedirect("/day_16/responseDemo02");`
// dam02的写法 package cn.web.servlet; 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; @WebServlet("/responseDemo02") public class ResponseDemo02 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("demo02被访问.................."); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
// 输出结果:说明访问demo可以被重定向到demo2中 demo被访问............ demo02被访问..................
- 重定向特点(redirect):
- 地址栏发生变化;
- 重定向可以访问其它站点(服务器)资源;
- 重定向是两次请求;
- 转发特点(forward):
- 地址栏不发生变化;
- 转发只能访问当前服务器下的资源;
- 转发是一次请求;(可以使用request对象来共享数据)
- 重定向特点(redirect):
2.简单案例:
服务器输出字符/字节数据到浏览器:
步骤:
- 获取字符/字节输出流;
- 输出数据;
注意:
-
乱码问题:
- PrintWirter pw = response.getWriter(); 获取的流默认编码是ISO-8859-1;
- 设置流的默认编码;
- 告诉浏览器响应体使用的编码;
简单形式,设置编码:
response.setContentType(“text/html; charset=utf-8”)
代码:
package cn.web.servlet;
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.io.PrintWriter;
@WebServlet("/responseServlet")
public class ResponseServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取流对象之前,设置流的默认编码: ISO-8859-1 设置为:GBK
// response.setCharacterEncoding("utf-8");
// 告诉浏览器, 服务器发送的消息体数据的编码, 建议浏览器使用该编码解码
// response.setHeader("content-type", "text/html;charset=utf-8");
// 推荐使用 设置编码
response.setContentType("text/html;charset=utf-8");
// 1.获取字符输出流
PrintWriter writer = response.getWriter();
// 2.输出数据
writer.write("哈喽啊~ hello");
// 1.获取字节输出流
ServletOutputStream outputStream = response.getOutputStream();
// 2.输出数据
outputStream.write("哈喽".getBytes("utf-8"));
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}