request_response详解

Request 对象详解

       

         客户端想服务器发送请求时,服务器会将所有的请求封装在HttpServletRequest对象中,我们通过这个对象获取客户端一些有用的数据。


request使用:
       request对象常用API

/*
 * 演示Request常用API
 */

public class RDemo01 extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequestreq,HttpServletResponse resp)
    throws ServletException,IOException {
            String uri = req.getRequestURI();    //获取请求的url,相于相对访问路径
            String url = req.getRequestURL().toString();  //获取请求的url,相当于绝对访问路径
            String query = req.getQueryString();    //获取请求参数
            String remoteAddr = req.getRemoteAddr(); //获取客户端的IP地址
            String localAddr = req.getLocalAddr();  //获取服务器端的IP地址
            String method = req.getMethod();      //获取请求方式
            String servletPath =req.getServletPath();  //获取servlet的映射路径
            String contextPath =req.getContextPath(); //获取站点的虚拟目录
            //向浏览器输出,即response表示每个浏览器,从response对象中获取的输出流自然指向每个浏览器
            PrintWriter pw = resp.getWriter();
            //获取请求头信息
            resp.setContentType("text/html;charset=UTF-8");
            String acceptEncoding = req.getHeader("Accept-Encoding");     
            //输出
            pw.write(url+"<br/>");
            pw.write(uri+"<br/>");
            pw.write(query+"<br/>");
            pw.write(remoteAddr+"<br/>");
            pw.write(localAddr+"<br/>");
            pw.write(method+"<br/>");
            pw.write(servletPath+"<br/>");
            pw.write(contextPath+"<br/>");
            pw.write(acceptEncoding+"<br/>");    

    
    }
}
获取页面表单提交的信息:

public class RDemo02 extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
    @Override
    protected void doPost(HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException {
            /*
             * req.getParameter("name");
             *在不清楚参数名字的情况下
             *可以 通过以下方式获取表单提交的数据
             */
            
            req.setCharacterEncoding("UTF-8");
            Enumeration<String> enums =req.getParameterNames();
            while(enums.hasMoreElements()){
                    String name =enums.nextElement();
                    String value ="";
                    String[] values =req.getParameterValues(name);
                    for(String s :values){
                        value+=s;
                    }
                    System.out.println(name+"..."+value);                
            }                
    }
}


表单乱码的原因和解决办法:
              表单提交的时候是用UTF-8或者GBK编码的,但是Tomcat默认的解码方式为:ISO8859-1编码
                例如:哈-> %AB%CD%EF -->doPost()


解决办法如下:
        1,修改web服务器的解码方式为UTF-8修改tomcat/conf目录下server.xml   <Connector /> 中添加属性 URIEncoding="UTF-8"。
                   缺点:在开发过程中,一般不建议修改服务器文件

       2,把ISO8859-1编码转换成byte[]数组,然后在用UTF-8的编码方式把byte数组构造成字符串。
    
       3,设置解码方式为UTF-8,request.setCharacterEncoding("UTF-8");   该方式只适用于POST请求的数据时位于请求体中的,而GET方式的请求数据是位于请求行的,这时

只能用第二种方式。


        BeanUtil工具类作用是封装到JavaBean对象的属性中,需要导入二个jar包,commons-beanutils-1.8.0.jar和commons-longging.jar。会自动把String类型转成基本类型和对应的包装类型,即String->int或者Integer



request域对象

request.setAttribute("NAME",name);
request.setAttribute("SAL",sal);
//定位到要转发的路径,这里的/表示web应用的根目录
RequestDispatcher rd = request.getRequestDispatcher("/Demo04B");
//转发到另一个servlet
rd.forward(request,response);


在Demo04B中doGet()方法可以获取传过来的域对象

String name = (String) request.getAttribute("NAME");
String sal = (String) request.getAttribute("SAL");



转发是服务器内部的事,与客户端无关,位于WEB-INF这个私有目录下的资源,可以用转发来访问。

转发的细节:
           1,要转发必须得用RequestDispatcher.forward()方法。

           2,如果想response对象中输出内容,但该内容没有真正输出到浏览器,即还在缓存中,

这是要转发,原缓存区中内容会被清空,不会输出到浏览器,最终结果是转发到 

                 目标资源。

           3,当内容输出到浏览器中,response对象生命周期已经结束,现在要转发,

 response对象已经不存在,所以会报错为了节约HTTP请求数,可以考虑转发。




response 对象
    response 对象用于服务器将数据发送到客户端

     setStatus();         设置响应码

     setHeader();         设置响应头

     getOutputStream();   以字节的方式输出内容到浏览器
 
     getWriter();         以字符的方式输出内容到浏览器


以字符流输出到浏览器中文乱码问题
          
 resp.setContentType("text/html;charset=UTF-8");


             指浏览器和服务器都用UTF-8方式编码


以字节流输出到浏览器中文乱码问题:
          
resp.getOutputStream().write("呵呵".getBytes("UTF-8"));

没指定bytes参数时使用gb2312方式编码的,然后输出到浏览器

       

<span style="font-size:14px;">  resp.setConteneType("text/html;charset=UTF-8");
</span>

这行代码是指定浏览器用什么方式解码服务器发来的数据。


下载文件代码:

public class RPDemo01 extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req,HttpServletResponse resp)throws ServletException, IOException {
        
        //设置响应头    要求浏览器以下载的方式打开资源  
        resp.setCharacterEncoding("UTF-8");
        String filename = URLEncoder.encode("广州地铁规划图.jpg","UTF-8");
        resp.setHeader("content-disposition","attachment;filename="+filename);  //火狐浏览器编码失败
        //以流的方式,将文件输出到浏览器中
        InputStream is = this.getClass().getClassLoader().getResourceAsStream("../../images/广州地铁规划图.jpg");
        OutputStream os = resp.getOutputStream();
        byte[] buf = new byte[1024];
        int len = 0;
        while((len = is.read(buf))>0){
            os.write(buf, 0, len);
        }
        os.close();
        is.close();
    }
}


ServletContext用来传输数据的一个例子

public class RPDemo02A extends HttpServlet{
    @Override
    protected void doPost(HttpServletRequest req,HttpServletResponse resp)throws ServletException, IOException {    
       try {
                User u = new User();
                //设置浏览器传输过来的数据用UTF-8解码
                req.setCharacterEncoding("UTF-8");
                Enumeration enums =req.getParameterNames();
                while(enums.hasMoreElements()){
                    String name = (String)enums.nextElement();
                    String[] value =req.getParameterValues(name);
                    BeanUtils.setProperty(u, name, value);
                }
                ServletContext context =this.getServletContext();
                context.setAttribute("USER",u);
                resp.sendRedirect(req.getContextPath()+"/RPDemo02B");
            } catch (Exception e) {
                
                e.printStackTrace();
            }
        }
        
}



public class RPDemo02B extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req,HttpServletResponse resp)throws ServletException, IOException {
            ServletContext context =this.getServletContext();
            
            User u = (User) context.getAttribute("USER");
            if(u != null){
                resp.setContentType("text/html;charset=UTF-8");
                PrintWriter pw =resp.getWriter();
                pw.write(u.getUsername()+"<br/>");
                pw.write(u.getPassword()+"<br/>");
                //重定向到ok.html页面
                resp.sendRedirect(req.getContextPath()+"/ok.html");
            }
        }
        
}





以下代码生成一个验证码:



/**
 * 生成一个随机验证码图片,不缓存,且嵌入到表单中
 * 本例会用于Java中的GUI编程
 */
public class RPDemo03 extends HttpServlet {
    public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException {
        //禁止浏览器缓存Demo08这个web页面
        response.setDateHeader("expires",-1);
        response.setHeader("cache-control","no-cache");
        response.setHeader("pragma","no-cache");
        int width = 80;
        int height = 30;
        //在内存中创建一个长80,宽30,的RGB格式的图片
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        //获取向图片上输出内容的画笔
        Graphics g = image.getGraphics();
        //设置字体
        g.setFont(new Font("宋体",Font.ITALIC,26));
        //输出30条干扰线段
        Random r = new Random();
        for(int i=1;i<=10;i++){
            //定位坐标
            int x1 = r.nextInt(width);
            int y1 = r.nextInt(height);
            int x2 = r.nextInt(width);
            int y2 = r.nextInt(height);
            //设置线段的颜色
            g.setColor(Color.WHITE);
            //画线段
            g.drawLine(x1,y1,x2,y2);
        }
        //设置字体颜色
        g.setColor(new Color(111,222,97));
        //向图片输出字符串
        
        g.drawString(WebUtil.getRandom(),10,20);
        //将内存中的图片,以指定的格式,输出到浏览器中
        ImageIO.write(image,"JPG",response.getOutputStream());
    }
}


class WebUtil{
    private WebUtil(){}
    public static String getRandom(){
        String random = "";
        String str = "0123456789";
        int size = str.length();
        Random r = new Random();
        for(int i=1;i<=4;i++){
            int num = r.nextInt(size);
            random += str.charAt(num)+"";
        }
        return random;
    }
}



重定向:
       response.sendRedirect(url);


 重定向下,request对象不可用,使用ServletContext域对象。

          1,ServletContext域对象是部署web应用时创建。
          2,Tomcat中一个应用都有自己独立的ServletContext对象。
          3,一个web应用的所有资源,都共享ServletContext对象。
          4,由Servlet引擎负责创建ServletContext对象。
          5,当服务器停止时才会销毁ServletContext对象,注意浏览器关闭ServletContext不会销毁。


你可能感兴趣的:(request_response详解)