HttpServletRequest和HttpServletResponse

Web服务器收到一个http请求,会针对每个请求创建一个HttpServletRequest和HttpServletResponse对象,向客户端发送数据找HttpServletResponse,从客户端取数据找HttpServletRequest;

1、HttpServletRequest

公共接口类HttpServletRequest继承自ServletRequest.客户端浏览器发出的请求被封装成为一个HttpServletRequest对象。所有的信息包括请求的地址,请求的参数,提交的数据,上传的文件客户端的ip甚至客户端操作系统都包含在其内;
一个 HTTP 请求包含以下三部分:
a.请求地址(URL)
b.请求头(Request headers)
c.实体数据(Entity body)

1.1、获得客户机信息

getRequestURL方法返回客户端发出请求时的完整URL。
getRequestURI方法返回请求行中的资源名部分。
getQueryString 方法返回请求行中的参数部分。
getRemoteAddr方法返回发出请求的客户机的IP地址 
getRemoteHost方法返回发出请求的客户机的完整主机名
getRemotePort方法返回客户机所使用的网络端口号
getLocalAddr方法返回WEB服务器的IP地址。
getLocalName方法返回WEB服务器的主机名 
getMethod得到客户机请求方式

1.2、获得客户机请求头

getHeader(string name)方法 
getHeaders(String name)方法 
getHeaderNames方法 

1.3、获得客户机请求参数(客户端提交的数据)

getParameter(name)方法
getParameterValues(String name)方法
getParameterNames方法 
getParameterMap方法

1.4、例子程序:

[java] view plain copy
public void doGet(HttpServletRequest request, HttpServletResponse response)  
        throws ServletException, IOException {  
        System.out.println("getRequestURL: "+request.getRequestURL());  
        System.out.println("getRequestURI: "+request.getRequestURI());  
        System.out.println("getQueryString: "+request.getQueryString());  
        System.out.println("getRemoteAddr: "+request.getRemoteAddr());  
        System.out.println("getRemoteHost: "+request.getRemoteHost());  
        System.out.println("getRemotePort: "+request.getRemotePort());  
        System.out.println("getRemoteUser: "+request.getRemoteUser());  
        System.out.println("getLocalAddr: "+request.getLocalAddr());  
        System.out.println("getLocalName: "+request.getLocalName());  
        System.out.println("getLocalPort: "+request.getLocalPort());  
        System.out.println("getMethod: "+request.getMethod());  
        System.out.println("-------request.getParamterMap()-------");  
        //得到请求的参数Map,注意map的value是String数组类型  
        Map map = request.getParameterMap();  
        Set<String> keySet = map.keySet();  
        for (String key : keySet) {  
        String[] values = (String[]) map.get(key);  
        for (String value : values) {  
            System.out.println(key+"="+value);  
        }  
     }  
        System.out.println("--------request.getHeader()--------");  
        //得到请求头的name集合  
        Enumeration<String> em = request.getHeaderNames();  
        while (em.hasMoreElements()) {  
        String name = (String) em.nextElement();  
        String value = request.getHeader(name);  
        System.out.println(name+"="+value);  
    }  

}  

浏览器上地址栏:

http://localhost:8080/RequestAndResponse/requestmethod?name=sunjob&password=123456&password=haha

控制台输出:

[plain] view plain copy
getRequestURL: http://localhost:8080/RequestAndResponse/requestmethod  
getRequestURI: /RequestAndResponse/requestmethod  
getQueryString: name=sunjob&password=123456&password=haha  
getRemoteAddr: 127.0.0.1  
getRemoteHost: 127.0.0.1  
getRemotePort: 2374  
getRemoteUser: null  
getLocalAddr: 127.0.0.1  
getLocalName: localhost  
getLocalPort: 8080  
getMethod: GET  
-------request.getParamterMap()-------  
name=sunjob  
password=123456  
password=haha  
--------request.getHeader()--------  
host=localhost:8080  
user-agent=Mozilla/5.0 (Windows NT 5.1; rv:17.0) Gecko/20100101 Firefox/17.0  
accept=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8  
accept-language=zh-cn,en-us;q=0.8,zh;q=0.5,en;q=0.3  
accept-encoding=gzip, deflate  
connection=keep-alive  
cache-control=max-age=0  

2、HttpServletResponse

HttpServletResponse继承了ServletResponse接口,并提供了与Http协议有关的方法,这些方法的主要功能是设置HTTP状态码和管理Cookie。HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法;
HttpServletResponse对象可以向客户端发送三种类型的数据:
a.响应头(Response headers)
b.状态码(Protocol—Status code—Description)
c.实体数据(Entity body )

2.1、常用方法

addHeader(String name,String value) 将指定的名字和值加入到响应的头信息中
encodeURL(String url) 编码指定的URL
sendError(int sc) 使用指定状态码发送一个错误到客户端
setDateHeader(String name,long date 将给出的名字和日期设置响应的头部
setHeader(String name,String value) 将给出的名字和值设置响应的头部
setStatus(int sc) 给当前响应设置状态码
HttpServletResponse.sendRedirect 方法对浏览器的请求直接作出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL的访问请求;方法调用者与被调用者使用各自的request对象和response对象,它们属于两个独立的访问请求和响应过程。
response.setContentType(“text/html;charset=utf-8”);
setContentType(String ContentType) 设置响应的MIME类型 ,页面的设置文本类型,获取或设置输出流的 HTTP MIME 类型。输出流的 HTTP MIME 类型。默认值为“text/html”。
MIME类型就是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
使用输出流输出一张图片的时候,比如做验证码图片的时候 如果在Firefox中直接浏览验证码是乱码,放在里面则不会
这时候就要事先指定Response.ContentType = “image/jpeg”;//设定MIME类型
response.setHeader(“Refresh”,”2;url=”http://www.baidu.com”); 页面的刷新
消息实体内容 通过输出流对象进行设置,用以下两个方法:
Response.getOutputStream() 字节输出流对象
Response.getWriter() 字符的输出流对象

2.1.1getOutputStream和getWriter方法的比较

(1)getOutputStream方法用于返回Servlet引擎创建的字节输出流对象,Servlet程序可以按字节形式输出响应正文。
(2)getWriter方法用于返回Servlet引擎创建的字符输出流对象,Servlet程序可以按字符形式输出响应正文。
(3)getOutputStream和getWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。要不会出现错误java.lang.IllegalStateException
(4)getOutputStream方法返回的是字节输出流对象的类型为ServletOutputStream,它可以直接输出字节数组中的二进制数据。
(5)getWriter方法将Servlet引擎的数据缓冲区包装成PrintWriter类型的字符输出流对象后返回,PrintWriter对象可以直接输出字符文本内容。
(6)Servlet程序向ServletOutputStream或PrintWriter对象中写入的数据将被Servlet引擎获取,Servlet引擎将这些数据当作响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端。
(7)Serlvet的service方法结束后,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭该输出流对象。
注:out.close();系统会自己释放,但一般写上

2.1.2选择getOutputStream和getWrite方法的要点

(1)PrintWriter对象输出字符文本内容时,它内部还是将字符串转换成了某种字符集编码的字节数组后再进行输出,使用PrintWriter对象的好处就是不用编程人员自己来完成字符串到字节数组的转换。
(2)使用ServletOutputStream对象也能输出内容全为文本字符的网页文档,但是,如果网页文档内容是在Servlet程序内部使用文本字符串动态拼凑和创建出来的,则需要先将字符文本转换成字节数组后输出。
(3)如果一个网页文档内容全部为字符文本,但是这些内容可以直接从一个字节输入流中读取出来,然后再原封不动地输出到客户端,那么就应该使用ServletOutputStream对象直接进行输出,而不要使用PrintWriter对象进行输出。

2.2、向客户端写入中文

2.2.1、使用OutputStream向客户端写入中文:

String data = “中国”;
OutputStream stream = response.getOutputStream();//获取一个向Response对象写入数据的流,当tomcat服务器进行响应的时候,会将Response中的数据写给浏览器
stream.write(data.getBytes(“UTF-8”));//此时在html页面会出现乱码,这是因为:服务器将”中国”按照UTF-8码表进行编码,得到对应的码值假设是98,99,服务器将码值发送给浏览器.浏览器默认按照GB2312进行解码,在GB2312码表中对应的字符已不是”中国”
正确代码如下:

response.setHeader("Content-type","text/html;charset=UTF-8");//向浏览器发送一个响应头,设置浏览器的解码方式为UTF-8
 String data = "中国";
 OutputStream stream = response.getOutputStream();
stream.write(data.getBytes("UTF-8"));

2.2.2使用PrintWriter向客户端写入中文:

PrintWriter writer = response.getWriter();
writer.write(“中国”);
//同样会出现乱码,这是因为我们将”中国”写入response对象时,tomcat服务器为了将数据通过网络传输给浏览器,必须进行编码,由于没有指定编码方式,默认采用ISO8859-1,当浏览器接收到数据后,根据GBK解码必然出现乱码
正确代码如下:

response.setCharacterEncoding("UTF_8");//设置Response的编码方式为UTF-8

response.setHeader("Content-type","text/html;charset=UTF-8");//向浏览器发送一个响应头,设置浏览器的解码方式为UTF-8,其实设置了本句,也默认设置了Response的编码方式为UTF-8,但是开发中最好两句结合起来使用 ,设置响应头,控制浏览器以指定的字符编码编码进行显示,
 //response.setContentType("text/html;charset=UTF-8");同上句代码作用一样
 PrintWriter writer = response.getWriter();
writer.write("中国");

在获取PrintWriter获取输出流之前使用”response.setCharacterEncoding(charset)”设置字符以什么样的编码输出到浏览器,如:response.setCharacterEncoding(“UTF-8”);设置将字符以”UTF-8”编码输出到客户端浏览器,然后再使用response.getWriter();获取PrintWriter输出流,这两个步骤不能颠倒

2.3、使用Response实现文件下载:

文件下载功能是web开发中经常使用到的功能,使用HttpServletResponse对象就可以实现文件的下载

文件下载功能的实现思路:

  1.获取要下载的文件的绝对路径
  2.获取要下载的文件名
  3.设置content-disposition响应头控制浏览器以下载的形式打开文件
  4.获取要下载的文件输入流
  5.创建数据缓冲区//缓冲区解释见下文
  6.通过response对象获取OutputStream流
  7.将FileInputStream流写入到buffer缓冲区
  8.使用OutputStream将缓冲区的数据输出到客户端浏览器

案例1

private void downloadFileByOutputStream(HttpServletResponse response){

     //1.获取要下载的文件的绝对路径

     String realPath = this.getServletContext().getRealPath("/download/1.JPG");

     //2.获取要下载的文件名

     String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);

     //3.设置content-disposition响应头控制浏览器以下载的形式打开文件

     response.setHeader("content-disposition", "attachment;filename="+fileName);

     //4.根据文件路径获取要下载的文件输入流

    InputStream in = new FileInputStream(realPath);

     int len = 0;

     //5.创建数据缓冲区

     byte[] buffer = new byte[1024];

     //6.通过response对象获取OutputStream流

     OutputStream out = response.getOutputStream();

     //7.将FileInputStream流写入到buffer缓冲区         while ((len = in.read(buffer)) > 0) {

     //8.使用OutputStream将缓冲区的数据输出到客户端浏览器

         out.write(buffer,0,len);

     }

     in.close();

 }
posted @ 2022-06-10 00:00  路暝月  阅读(25)  评论(0编辑  收藏  举报  来源