(javaweb读书笔记系列之三)request和response

利用3到4天的时间,把servlet中的request和response视频看了一遍。看完之后,总结出来了一些知识点。

首先得知道这两个是什么东东,它们主要是用在servlet处理浏览器传来的请求的,究竟是怎么一回事呢?

1.服务器每次收到请求时,都会为这个请求开辟一个新的线程。

2.服务器会把客户端的请求数据封装到request对象中,request就是请求数据的载体!(可以理解为袋子)

3.服务器还会创建response对象,这个对象与客户端连接在一起,它可以用来向客户端发送响应。(可以理解为手机)


先来说说response吧。

回忆一下http协议!http协议中响应的内容包含哪些东西呢?

一:状态码:200表示成功、302表示重定向、404表示客户端错(访问的资源不存在)、500表示服务器端错

二:响应头:Content-Type、Refresh、Location等等,头就是一个键值对!可能会存在一个头(一个名称,一个值),也可能会存在一个头(一个名称,多个值!)

三:响应体:通常是html、也可以是图片!response有两个流,getOutputStream(字节)和getWriter(字符),但两个流不能同时使用!

1、解决用outputStream输出中文的乱码问题。       

1
2
3
4
5
//1.程序的数据以什么码表输出了,程序就要控制浏览器以什么码表打开
response.setHeader( "content-type" "text/html;charset=utf-8" );
String data= "中国" ;
OutputStream out=response.getOutputStream();
out.write(data.getBytes( "utf-8" ));

要注意:

1
"content-type" "text/html;charset=utf-8" 中的分号切不可写成逗号,不然浏览器会提示下载
1
2
3
4
5
//2.用HTML技术中的meta标签来模拟http响应头,用于控制浏览器的行为
String data= "中国人" ;
OutputStream out=response.getOutputStream();
out.write( "<meta http-equiv='content-type' content='text/html;charset=utf-8'>" .getBytes());
out.write(data.getBytes( "utf-8" ));

  2、用write流输出中文

1
2
3
4
//设置response中的码表
response.setCharacterEncoding( "utf-8" );
response.setContentType( "text/html;charset=utf-8" );
response.getWriter().write( "中国" );

  3、实现文件的下载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
String path= this .getServletContext().getRealPath( "/download/image1.jpg" );
String filename=path.substring(path.lastIndexOf( "\\" )+ 1 ); //取文件名的小技巧
response.setHeader( "content-disposition" , "attachment;filename=" +URLEncoder.encode(filename, "utf-8" ));
InputStream in =  null ;
OutputStream out =  null ;
in =  new  FileInputStream(path);
int  len= 0 ;
byte  buffer[]= new  byte [ 1024 ];
out=response.getOutputStream();
while ((len=in.read(buffer))> 0 ){
out.write(buffer, 0 ,len);
}
out.close();
in.close();

  4、控制浏览器定时刷新

1
2
response.setHeader( "refresh" "3" ); //3秒后刷新
response.setHeader( "refresh" , "3;url='index.jsp'" ); //3秒后跳到index.jsp

 还有一个请求重定向,这个放在后面跟请求转发放在一起说


 接下来说的就是request,封装了客户端所有的请求数据!(请求行、请求头、空行、请求体(GET没体))先来说说一些常用的方法吧。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
System.out.println(request.getRequestURI());
System.out.println(request.getRequestURL());
//URL和URI的区别:
//URI:统一资源标识符  exp:/day02/RequestDemo1
//URL:全球资源定位器  exp:http://localhost:8080/day02/RequestDemo1
System.out.println(request.getQueryString()); //获取参数信息(返回请求行中的参数)exp:   返回name=zengxiang
System.out.println(request.getRemoteAddr()); //返回发出请求的客户机IP地址
System.out.println(request.getRemoteHost()); //返回发出请求的客户机主机名
System.out.println(request.getMethod()); //返回请求方式POST、GET、PUT
 
//客户机带数据给servlet有两种方式:超链接和提交表单,下面是获取请求数据的几种方式
1 .String value = (String)request.getParameter( "name" );
2 .Enumeration e=request.getParameterNames();
   while (e.hasMoreElements()){
     String name=(String) e.nextElement();
     value=request.getParameter(name);
     System.out.println(name+ "=" +value);
   }
3 .String[] values=request.getParameterValues( "password" );
   for ( int  i= 0 ;values.length!= 0 &&i<values.length;i++){
     System.out.println(values[i]);
   } //切记判断传递过来的参数是否为空
4 .Map m=request.getParameterMap();
   User user= new  User();
   try {
         BeanUtils.populate(user,m); //用map集合数据填充bean
       } catch (Exception e1){
         e1.printStackTrace();
     }
   System.out.println(user);
5 .InputStream in=request.getInputStream(); //一般不采用此种方式去获取数据,文件上传需要这种方式
   int  len= 0 ;
   byte  buffer[]= new  byte [ 1024 ];
   while ((len=in.read(buffer))> 0 ){
     System.out.println( new  String(buffer, 0 ,len));
   }

请求转发和请求包含
    RequestDispatcher rd = request.getRequestDispatcher("/MyServlet");  

使用request获取RequestDispatcher对象,方法的参数是被转发或包含的Servlet的Servlet路径
    请求转发:rd.forward(request,response);
    请求包含:rd.include(request,response);

    有时一个请求需要多个Servlet协作才能完成,所以需要在一个Servlet跳到另一个Servlet!
    > 一个请求跨多个Servlet,需要使用转发和包含。
    > 请求转发:由下一个Servlet完成响应体!当前Servlet可以设置响应头!(留头不留体)
    > 请求包含:由两个Servlet共同未完成响应体!(都留)
    > 无论是请求转发还是请求包含,都在一个请求范围内!使用同一个request和response!


下面就是中文乱码的问题了,先来解释一下乱码的原因吧,在浏览器中接受一个数据(编码取决于在浏览器中的编码),在数据传给request时,按照request域中的码表(iso8859-1)翻译过来,这个“中国”就不是“中国”了,于是到了servlet中就出现乱码了。

通过浏览器带来数据的方式不同,解决方式也不一样。

一、解决get表单,超链接提交的乱码

1
2
3
String value=request.getParameter( "username" );
String value1= new  String(value.getBytes( "iso8859-1" ), "gbk" );
System.out.println(value1);

二、解决post表单提交的乱码

1
2
3
request.setCharacterEncoding( "gbk" );
String value1=request.getParameter( "username" );
System.out.println(value1);


区分两种域:

1
2
    request域:作用于请求范围,每个请求对应一个request域,相互独立
servletContext域:作用于WEB应用,所有请求都在一个context域,数据易覆盖


区分两个方法:

1
2
getAttribute():获取域中的数据
getParameter():获取客户机所提交的数据


WEB中各类地址的写法:首先以“/”开头,然后判断该地址是给谁用的,给服务器用,“/”代表当前WEB应用;给客户机浏览器用,“/”代表网站(包含多个web应用)例如:

1
2
3
4
5
6
1 .request.getRequestDispatcher( "/form1.html" ).forward(request, response);
2 .response.sendRedirect( "/day02/form1.html" );
3 . this .getServletContext().getRealPath( "/form1.html" );
4 . this .getServletContext().getResourceAsStream( "/form1.html" );
5 .<a href= "/day06/form1.html" >xx</a>
6 .<form action= "/day06/form1.html" ></form>

URL编码:
  表单的类型:Content-Type: application/x-www-form-urlencoded,就是把中文转换成%后面跟随两位的16进制。
  为什么要用它:在客户端和服务器之间传递中文时需要把它转换成网络适合的方式,方便传递参数。
  注意:

  * 它不是字符编码!
  * 它是用来在客户端与服务器之间传递参数用的一种方式!
  * URL编码需要先指定一种字符编码,把字符串解码后,得到byte[],然后把小于0的字节+256,再转换成16进制。前面再添加一个%。
  *
POST请求默认就使用URL编码!tomcat会自动使用URL解码!
  * URL编码:String username = URLEncoder.encode(username, "utf-8");
  * URL解码:String username = URLDecoder.decode(username, "utf-8");


重定向的特点就是:1.浏览器向服务器发出两个请求,意味着有两个response/request

2.浏览器地址栏会变化

> 请求转发是一个请求一次响应,而重定向是两次请求两次响应
    > 请求转发地址栏不变化,而重定向会显示后一个请求的地址
    > 请求转发只能转发到本项目其他Servlet,而重定向不只能重定向到本项目的其他Servlet,还能定向到其他项目
    > 请求转发是服务器端行为,只需给出转发的Servlet路径,而重定向需要给出requestURI,即包含项目名!
    > 请求转发和重定向效率是转发高!因为是一个请求!
      <> 需要地址栏发生变化,那么必须使用重定向!
      <> 需要在下一个Servlet中获取request域中的数据,必须要使用转发!


通俗一点理解就是:A找B借钱,B没钱,1.B找C去借钱,然后再给A,这是转发;2.B叫A自己找C借钱,这是重定向。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值