你的位置:首页 > Java教程

[Java教程]Java Web之请求和响应


  Servlet最主要作用就是处理客户端请求并作出回应,为此,针对每次请求,Web容器在调用service()之前都会创建两个对象,分别是HttpServletRequest和HttpServletResponse。其中HttpServletRequest封装HTTP请求消息,HttpServletResponse封装HTTP响应消息。需要注意的是,Web服务器运行过程中,每个Servlet都会只创建一个实例对象,不过每次请求都会调用Servlet实例的service(ServletRequest req, ServletResponse res)方法,这里HttpServletRequest是ServletRequest的子类,HttpServletResponse是ServletResponse的子类。

  HttpServletRequest和HttpServletResponse接口继承关系图如下所示:

 1、HttpServletResponse

  HttpServletResponse接口继承自ServletResponse接口,由于HTTP响应消息分为状态行、响应消息体、消息体三部分,因此,在HttpServletResponse接口中定义了向客户端发送响应状态码、响应消息头、响应消息体的方法。虽然HttpServletResponse接口中的方法较多,但是我们常用的也就是那么几个,如果用到其他的方法了可以阅读响应的源码或者相关资料就行了。

发送状态码相关函数

方法说明
public void setStatus(int sc)设置响应消息状态码,Web服务器默认产生一个状态码为200的状态行
public void sendError(int sc)发送表示错误信息的状态码,第二个方法还增加了一个用于提示说明的文本信息
public void sendError(int sc, String msg)

发送响应消息头相关函数

方法说明
public void addHeader(String name, String value)设置HTTP响应头字段,name指定字段名称,value指定字段值。addHeader可以增加同名的响应头字段,setHeader则会覆盖同名的头字段
public void setHeader(String name, String value)
public void setContentLength(int len) 设置响应消息的实体内容的大小,单位为字节,即设置Content-Length字段的值
public void setContentType(String type)设置Servlet输出内容的MIME类型,即设置Content-Type字段的值 
public void setCharacterEncoding(String charset)设置输出内容字符编码,即设置Content-Type字段的值,注意,该方法优先级比setContentType的高
public void sendRedirect(String location)Servlet请求重定向

发送响应消息体相关函数

方法说明
public ServletOutputStream getOutputStream()获取HttpServletResponse的字节输出流ServletOutputStram类型
public PrintWriter getWriter()获取HttpServletResponse的字符输出流ServletWriter类型

中文输出乱码问题

  计算机中的数据都是以二进制形式存储的,因此,传输文本时,就会发生字符的字节之间的转换。字符与字节之间的转换时通过查码表完成的,字符转换为字节的过程称为编码,字节转换为字符的过程称为解码,如果编码和解码使用的码表不一样,则会出现乱码问题。

  注意:HttpServletResponse对象的字符输出流在编码时,默认采用的是ISO 8859-1编码,该编码方式不兼容中文,比如会将"中国"编码为"63 63"(在ISO 8959-1的码表中查不到的字符会显示63)。当浏览器对接收到的数据进行解码时,会默认采用GB2312,将"63"解码为"?",浏览器就将"中国"两个字符解码为"??"。

HttpServletResponse程序示例

package zzz;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class Hello extends HttpServlet {  @Override  public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {    // 设置响应消息编码,注释后"中国"会显示"??"乱码    response.setContentType("text/html;charset=utf-8");    PrintWriter out = response.getWriter();        out.println("hello 中国");  }    @Override  public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {    this.doGet(request, response);  }}

  有时会遇到定时跳转页面的问题,HTTP中Refresh头字段可以通知浏览器在指定的时间内自动刷新并跳转到其他页面,网页定时刷新并跳转到指定页面。

package zzz;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class Hello extends HttpServlet {  @Override  public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {    // 设置响应消息编码    response.setContentType("text/html;charset=utf-8");    response.setHeader("Refresh", "2;url=http://www.baidu.com");    PrintWriter out = response.getWriter();    out.println("hello 中国,2秒后跳转到百度...");  }    @Override  public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {    this.doGet(request, response);  }}

View Code

 2、HttpServletRequest

  HttpServletRequest接口继承ServletRequest接口,专门用于封状HTTP请求消息。由于HTTP请求信息包括请求行、请求头和请求体三部分, 所以HttpServletRequest接口定义了获取请求行、请求头和请求体的相关方法。

获取请求行的相关方法

方法说明
public String getMethod()获取HTTP请求方式,POST、GET等
public String getRequestURI()获取请求行中资源名称部分
public String getQueryString()获取请求行中的参数部分
public String getProtocol()获取请求行中协议名称和版本,如HTTP 1.1
public String getContextPath()获取请求URL中属于Web应用程序的路径

  其实关于请求行的方法从方法名中就可以看出其作用,这里就不一一贴出来了。

获取请求消息头的相关方法

方法说明
public String getHeader(String name)获取指定字段的值,如果没有返回null,如果有多个返回第一个值
public Enumeration<String> getHeaders(String name)返回一个指定字段的Enumeration集合对象
public Enumeration<String> getHeaderNames()返回一个包含所有字段的Enumeration集合对象
public String getContentType()获取Content-Type字段的值

打印请求消息头字段的所有值

package zzz;import java.io.IOException;import java.io.PrintWriter;import java.util.Enumeration;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class Hello extends HttpServlet {  @Override  public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {    // 设置响应消息编码    response.setContentType("text/html;charset=utf-8");    PrintWriter out = response.getWriter();    Enumeration<String> names = request.getHeaderNames();    while (names.hasMoreElements()) {      String name = names.nextElement();      String value = request.getHeader(name);      out.println(name + ": " + value + "</br>");    }  }    @Override  public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {    this.doGet(request, response);  }}

View Code

获取请求体的相关方法

方法说明
public ServletInputStream getInputStream()获取请求的ServletInputStream对象,如果实体内容为非文本,只能通过getInputStream方法获取请求体消息体
public BufferedReader getReader()获取请求的BufferedReader对象,该对象会将实体内容字节数据转换为指定字符集编码的文本字符串

获取请求参数

方法说明
public String getParameter(String name)获取指定的参数值,没有该参数返回null
public Enumeration<String> getParameterNames()返回一个包含所有参数名的Enumeration对象
public String[] getParameterValues(String name)HTTP请求中可能有多个相同的参数,获取同一个参数名对应的所有参数值

  获取请求参数实例见:http://www.cnblogs.com/xdp-gacl/p/3798347.html

 3、RequestDispatcher接口

  当一个Web资源受到客户端请求后,如果希望服务器通知另外一个资源如处理请求,除了使用功能sendRedirect()实现重定向外,还可以通过RequestDispatcher接口的实例对象来实现,在ServletRequest接口中定义了一个获取RequestDispatcher对象的方法--getRequestDispatcher(String path),它返回某个路径所指定资源的RequestDispatcher对象,参数path必须以"/"开头,用于表示当前Web应用的根目录,也就是path路径必须是在本Web程序中,否则会出现异常。

RequestDispatcher接口中方法

方法功能
public void forward(ServletRequest request, ServletResponse response)将一个Servlet传递给另外一个Web资源,将请求传递给其他资源进行响应
public void include(ServletRequest request, ServletResponse response)用于将其他资源作为当前响应内容包含进来

4、参考资料

  1、javaweb学习总结(十)——HttpServletRequest对象(一)

  2、Java Web之Servlet技术