HttpServlet



HttpServlet详解


一、请求和响应对象概述(**)
            HTTP协议包含请求和响应部分。
            HttpServletRequest就代表着请求部分
            HttpServletResponse就代表着响应部分


            学好的关键:HTTP协议。


二、HttpServletResponse详解(*****)
              2.1输出中文数据(字符流与字节流)              
              
                      字节流:
                            // 以字节流默认的本地GBK编码输出中文数据,没有乱码  
                            String s = "幸福是神马 ";
                            ServletOutputStream out = response.getOutputStream();
                            out.write(s.getBytes());
                            
                            // 以字节流用UTF-8编码输出中文数据,有乱码  
                            out.write("中文".getBytes("UTF-8"));
                            解决办法:
                                    方式一:更改浏览器的查看编码(不可取)      
                                                                 
                                    注:  方式二、三、四都是一样的,即通知浏览器,使用的码表
                                    方式二:response.setHeader("Content-Type", "text/html;charset=UTF-8");
                                    方式三:response.getOutputStream().write("<meta http-equiv='Content-Type'           
                                                   content='text/html;charset=UTF-8'>".getBytes("UTF-8"));
                                   *方式四:response.setContentType("text/html;charset=UTF-8");
                                   
                      字符流:
                            Servlet中的字符流默认查ISO-8859-1(SUN的Servlet规范要求的)
                            更改这个默认的编码的方式: response.setCharacterEncoding("UTF-8");
                            
                            //不要忘记通知浏览器的编码
                            response.setCharacterEncoding("UTF-8");
                            
                            方式1:response.setHeader("Content-Type", "text/html;charset=UTF-8");
                            方式2:response.setContentType("text/html;chatset=UTF-8");
                            
                            PrintWriter out = response.getWriter();
                            out.write(s);
                                                           
                            在字符流输出中文数据时:response.setContentType("text/html;charset=UTF-8");
                                有两个作用:通知字符流以UTF-8编码输出
                                                      通知客户端以UTF-8解码显示
                            注:  输出整数,转换成字符串形式,即可,比如98无论查哪个码表都是b          
              
              2.2控制不要缓存
                            response.setHeader("Expires", "-1");
                            response.setHeader("Cache-Control", "no-cache");
                            response.setHeader("Pragma", "no-cache");
              
              2.3控制缓存时间
                       // 缓存1小时
                            response.setDateHeader("Expires", System.currentTimeMillis()+60*60*1000);
                        
              2.4动态生成随机验证码图片(见例子Demo)
              
              2.5定时刷新
                           // 定时刷新自身页面
                           方式1: response.setHeader("Refresh", "1");
                           方式2: response.setIntHeader("Refresh", 1);
                           
                           // 定时刷新到其他页面
                           response.setHeader("Refresh", "3;URL=/day06/index.html");
                                  
              2.6文件下载(中文文件名的文件下载)(见例子Demo)
                                          
              2.7HttpServletResponse细节:
                          字节流和字符流不能同时使用,互斥的。
                          通过字符流或字节流输出的数据并不是直接打给浏览器的。而是把数据写到response对象的缓存中的。
                                服务器从缓存中取出数据,按照HTTP协议的响应格式输出给浏览器。

                          如果你调用的response的输出流没有主动关闭,服务器会替你关的。

                
                          



三、HttpServletRequest详解 (*****)
          代表着客户端的请求。要客户的信息只要找这个对象即可,该对象由容器创建。
          学习关键:时刻记住HTTP协议的请求部分的具体内容。

              3.1常用简单方法
                        **********************************************************************************************
                        // 获取URL: 协议 + 主机 + 端口  
                        // 资源的地址:http://localhost:8080/day07/servlet/RequestDemo1
                        String url = request.getRequestURL().toString();
                        
                        // 获取URI: 请求的资源地址: /day07/servlet/RequestDemo1
                        String uri = request.getRequestURI();


                        // 获取get方式的请求参数字符串: 
                        // /day07/servlet/RequestDemo1?username=asd&password=123
                        // 得到:  username=asd&password=123  注: 若为post方式,则为null
                        String qs = request.getQueryString();
                        
                        // 获得主机地址
                        String remoteAddr = request.getRemoteAddr();
                        
                        // 获取客户机的端口号  注: 不是服务器使用的端口号,客户机使用的端口号是随机的(>1024)
                        int remotePort = request.getRemotePort();
                        
                        // 获取请求方式  注: 根据浏览器的不同,返回值的字母大小写不同,若要判断,须忽略大小写
                        String method = request.getMethod();                        
                        **********************************************************************************************
                            
              3.2获取请求消息头
                        **********************************************************************************************
                        // 获取指定的头的值: 如头:Accept-Encoding
                        String value = request.getHeader("Accept-Encoding");


                        // 获取重名的头的值: 如头:User-Agent
                        Enumeration e  = request.getHeaders("User-Agent");
                        while(e.hasMoreElements()){
                                    String value = (String) e.nextElement();
                                    out.write(value);
                        }
                              
                        // 获取所有的请求头名和头值  注: 即模拟Httpwatch中Stream中的请求部分
                        Enumeration e = request.getHeaderNames();
                        while(e.hasMoreElements()){
                                    String headerName = (String) e.nextElement();
                                    String headerValue = request.getHeader(headerName);
                                    out.write(headerName + "\t" + headerValue + "<br/>");
                        }
                        **********************************************************************************************
                           
              3.3获取请求参数(内省)(注: 请求正文即请求参数 见httpwatch)
                        **********************************************************************************************
                        // 获取指定单一参数的值 : 注: 不能获取重名的参数的值,只显示第一次的值
                        String username = request.getParameter("username");
                        
                        // 获取指定重名参数的值
                        String usernames[] = request.getParameterValues("username");
                        for(String s : usernames)
                                    System.out.println(s);
                                
                        // 获取所有的参数和取值
                        Enumeration e = request.getParameterNames();   // 获取所有的请求参数名
                        while(e.hasMoreElements()){
                                    String paramName = (String) e.nextElement();
                                    String values[] = request.getParameterValues(paramName);
                                    System.out.println(paramName + "----" + Arrays.asList(values));
                        }
                        
                        // BeanUtils内省框架获取请求参数,封装到JavaBean中
                        User user = new User();
                        System.out.println("封装前:" + user);                       
                        try {
                                    BeanUtils.populate(user, request.getParameterMap());
                        } catch (Exception e) {
                                    e.printStackTrace();
                        }                   
                        System.out.println("封装后:" + user);         
                        
                        // 以流的方式获取请求正文
                        ServletInputStream in = request.getInputStream();
                        int len = 0;
                        byte b[] = new byte[1024];
                        while((len = in.read(b)) != -1){
                                System.out.println(new String(b,0,len));
                        }
                        in.close();
                        **********************************************************************************************
              
              3.4常用表单数据的获取
                      表单输入域类型:
                            radio checkbox,即使表单中有对应名称输入域,如果一个不选择,则什么数据不会带给服务器。(注意空指针异常)
                            如果选择了其中的一个或多个,则把他们的value的取值提交给服务器。
                            如果选择了其中的一个或多个,他们又没有value取值,则提交给服务器的值是on.
                      请求参数的编码:
                            浏览器当前使用什么编码,就以什么编码提交请求参数。
                                  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
                          request.setCharacterEncoding(编码):
                                  通知程序,客户端提交的数据使用的编码。但是只对POST请求方式有效(注意与response区分)                       
                          如果是get请求提交数据,编码就是ISO-8859-1;   
                          Tips:目前采用POST提交方式。
                          Get方式:  字符转码:new String("中文".getBytes("ISO-8859-1"),"UTF-8");
                                             采取全站中文编码过滤器方式即可


              3.5域对象:
                          ServletRequest也是一个域对象(内部维护了一个Map<String,Object>)
                                  Object getAttribute(Stirng name):  (注意区分:request.getParameter(String name))
                                  void setAttribute(String name,Object value):
                                  void removeAttribute(String name):

              3.6请求转发和重定向
                请求转发借助于RequestDispatcher
                如何得到RequestDispatcher对象:
                      方式一:ServletContext.getRequestDispatcher(目标资源的URI);
                      方式二:ServletRequest.getRequestDispatcher(目标资源的URI);
                      区别:
                        方式一中的目标资源的URI必须以"/"开头,否则报错,此"/"就表示的是当前应用(绝对路径表示法)
                        方式二中的目标资源的URI如果以"/"开头,就表示的是当前应用(绝对路径表示法)。如果不以"/"开头,就表示相对路径。
                    

            3.7转发和重定向细节(实际开发中知道一个原则) (了解原则)
                          请求转发:由源组件转发到目标组件时,容器会清空源组件输出的数据。
                          因此,用户只会看到目标组件输出的页面结果。但是,响应头信息是不清空的。

                          编码原则:不要在转发前后向页面输出数据,也不要关闭输出流。(做无用功)

 区别: 转发,服务器的行为,发出了1次请求,地址栏不变;

                                    重定向: 浏览器的行为,发出了2次请求,地址栏改变;

                        
                        
            3.8包含:(动态包含)(了解原则)
                          由源组件包含到目标组件时,容器会清空目标组件的头。因此,源组件设置的头才有效。
                          但是,响应体信息是不清空的。
                          编码原则:不要在目标组件中设置响应头。(做无用功)                          
                          RequestDispatcher rd = request.getRequestDispatcher("/servlet/RequestDemo2");
                          rd.include(request, response);
                          
                          
                          
                          
                          
                          





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值