JAVA EE-REQUEST&RESPONSE

JAVA EE-REQUEST&RESPONSE

人生下来不是为了拖着锁链,而是为了展开双翼。 —— 雨果

Response对象

Response对象,用于生成http响应信息. 对于开发人员来讲,就是 向response 对象中添加信息即可.

  • 响应首行
HTTP/1.1  200 OK
        void setStatus(int sc) 
        void setStatus(int sc, String sm) Deprecated(过时)
        void sendError(int sc) 
        void sendError(int sc, String msg) 
  • 响应头
键:值
        void setHeader(String name, String value)  设置键值对.
                void setDateHeader(String name, long date) 设置键值对.
                void setIntHeader(String name, int value)  设置键值对.
        void addHeader(String name, String value) 添加键值对.
            void addDateHeader(String name, long date)添加键值对.
            void addIntHeader(String name, int value) 添加键值对.
  • 响应空行
  • 响应正文
需要给浏览器的资源
            getWriter(); 字符流.
            getOutputStream() 字节流

Response对象的几种事例

  • 例1: 手动向浏览器 发送404错误状态码.
  • 例2: 访问BServlet,3秒后浏览器自动跳转到传智首页.
    用于模拟响应头的
  • 例3: 手动做重定向效果.
  • 例4: 向浏览器输出文字(字节流,中文)
  • 例5: 向浏览器输出文字(字符流,中文)
    //结论:
    //1 输出中文建议使用字符流
    //2 解决字符流乱码 使用setContentType放可以同时设置编码解码两端的码表.
    //3 注意: 码表的设置一定放到输出之前
    //4 注意: 字符流与字节流不能同时使用
  • 例6: 向浏览器输出图片.(由servlet输出).
  • 例7: 文件下载(向浏览器输出内容)

使用Response发送错误信息

public class AServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.sendError(404,"找到也不告诉你!");

    }

}

跳转


public class BServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
            //添加响应头=> Refresh

        response.addHeader("Refresh", "3;url=http://localhost:8080");
        // 让页面有倒计时的效果
        response.getWriter().write("您将在3秒后跳转!" +
                "");

    }

}

重定向

public class CServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        /*//1 添加302状态码   =>  告诉浏览器需要重定向
            response.setStatus(302);
        //2 添加Location响应头 => 高速浏览器重定向到哪里
            response.setHeader("Location", "http://localhost:8080");*/

        //该方法是对上面两行代码的封装 
        response.sendRedirect("http://localhost:8080");
    }

}

解决浏览器端的乱码问题

public class DServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //控制解码码表
        response.setHeader("Content-Type", "text/html;charset=GBK");
        //控制编码码表
        response.getOutputStream().write("黑马".getBytes("GBK"));

    }

}
public class EServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //2 设置解码码表 => 与setContentType效果一样,自动查找设置的码表,将解码码表设置一致 
        response.setHeader("Content-Type", "text/html;charset=GBK");
        //1 设置编码码表
        //response.setCharacterEncoding("GBK");
        //可以使用19行代替17行的代码.同时setContentType方法如果发现你填写码表,那么会同时自动设置编码码表
        //response.setContentType("text/html;charset=GBK");

        //3 输出
        response.getWriter().write("黑马");


        //结论:
            //1 输出中文建议使用字符流
            //2 解决字符流乱码 使用setContentType放可以同时设置编码解码两端的码表.
            //3 注意: 码表的设置一定放到输出之前
            //4 注意: 字符流与字节流不能同时使用
    }

}

JAVA EE-REQUEST&RESPONSE_第1张图片
发给客户端图片

public class FServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //判断是否有查看的权限

            // 1 获得图片的输入流
        InputStream is = getServletContext().getResourceAsStream("/WEB-INF/xxx1.jpg");
            // 2 获得输出到浏览器的输出流
        OutputStream os = response.getOutputStream();
            // 3 两个流对接
        byte[] buffer = new byte[1024];
        int len = -1;

        while((len = is.read(buffer))!=-1){
            os.write(buffer,0,len);
            os.flush();
        }

        os.close();
        is.close();

    }

}

传送文件

public class GServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //0 原则: 凡是响应正文中需要输出内容, 一定要设置content-type头
        ServletContext sc = getServletContext();
        String type = sc.getMimeType("abc.exe");
        response.setContentType(type);

        //0 设置响应头=> 提示用户保存名称   =>  Http协议不支持中文码表=> %E5%C3 => URLEncoder.encode("apache-汤姆-6.0.35.exe","UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode("apache-汤姆-6.0.35.exe","UTF-8"));
        // 1 获得文件的输入流
    InputStream is = getServletContext().getResourceAsStream("/WEB-INF/apache-tomcat-6.0.35.exe");
        // 2 获得输出到浏览器的输出流
    OutputStream os = response.getOutputStream();
        // 3 两个流对接
    byte[] buffer = new byte[1024];
    int len = -1;

    while((len = is.read(buffer))!=-1){
        os.write(buffer,0,len);
        os.flush();
    }

    os.close();
    is.close();

    }

}

Request对象

Request对象的方法

Request

    HTTP请求协议:
        请求首行            请求方式  请求路径  协议/版本号
            String getMethod()  获得请求方式
            request.getContextPath(): /day08-request 获得项目路径
            String getServletPath() 
            request.getQueryString(): name=tom?age=19  获得请求路径中的参数
            request.getRequestURI(): /day08-request/AServlet  获得当前访问的相对路径,相对主机路径
            request.getRequestURL(): http://localhost:8080/day08-request/AServlet 获得当前访问的绝对路径
            request.getServletPath(): /AServlet 获得servlet路径
            String getScheme()  获得协议协议
        请求头             键:值
             request.getContentLength(): -1 返回正文内容长度
             request.getContentType(): null 返回正文内容类型
             request.getLocale(): zh_HANS_CN  获得accept-language:zh_CN
             request.getServerName(): localhost 获得主机名称
             request.getServerPort(): 8080 获得访问端口号


             String getHeader(String name) 根据键获得值(值只有一个)
                     long getDateHeader(String name)
                     int getIntHeader(String name) 
             Enumeration getHeaderNames()  获得所有请求头的名字
             Enumeration getHeaders(String name)  根据键获得值(值有多个)



        请求空行            
        请求正文            post请求才有=> 请求参数 => name=tom&age=18
                 String getParameter(String name) 根据参数键获得参数值
                 Map<String,String[]> getParameterMap() 返回封装参数的Map
                 Enumeration getParameterNames() 获得所有参数的键
                 String[] getParameterValues(String name)  根据参数键获得参数值(值有多个)

        网络编程
        request.getRemoteAddr(): 192.168.13.102
        request.getRemoteHost(): 192.168.13.102
        request.getRemotePort(): 53479

取出所有的参数

public class BServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
            // 1 获得 所有参数的键
            Enumeration en = request.getParameterNames();
            // 2 遍历所有键
            while(en.hasMoreElements()){
                String key = en.nextElement();
                //根据键 获得值
                String value = request.getParameter(key);

                System.out.println(key+"==>"+value);
            }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // 1 获得 所有参数的键
        Enumeration en = req.getParameterNames();
        // 2 遍历所有键
        while(en.hasMoreElements()){
            String key = en.nextElement();
            //根据键 获得值
            String value = req.getParameter(key);

            System.out.println(key+"==>"+value);
        }   
    }

}

解决乱码问题

public class CServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
            String name = request.getParameter("name");
            System.out.println(name);
            //1 将乱码使用latin码表 编码回字节数组
            byte[] bytes= name.getBytes("ISO-8859-1");
            //2 将字节用UTF-8码表 解码回中文
            String name2 = new String(bytes, "UTF-8");
            System.out.println(name2);


    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse resp)
            throws ServletException, IOException {
        //post解决乱码,只要在调用获得参数方法前.设置解码码表即可
        request.setCharacterEncoding("UTF-8");

        String name = request.getParameter("name");
        System.out.println(name);
    }

}
![这里写图片描述](http://img.blog.csdn.net/20160918214841183)

转发逻辑
在DServlet中处理逻辑,在JSP中现实给浏览器

public class DServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
            System.out.println("我来处理业务逻辑");
            String name = "肉丝";//假设该值是从数据库中取出来.要将该值交给EServlet显示
            //将name变量放入request域
            request.setAttribute("name", name);

            //转发(山寨,帮助我们理解转发原理)
            /*EServlet eservlet = new EServlet();
            eservlet.service(request, response);*/

            response.getWriter().write("DServlet hello!");

            //转发
            request.getRequestDispatcher("/EServlet").forward(request, response);

    }

}
public class EServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        System.out.println("我来负责输出显示!");
        String name = (String) request.getAttribute("name");


        System.out.println("EServlet:"+name);

        response.getWriter().write("EServlet hello!");
    }

}

JAVA EE-REQUEST&RESPONSE_第2张图片
包含逻辑

public class FServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
            response.setContentType("text/html;charset=utf-8");

            response.getWriter().write("这是第一部分!
"
); //包含 request.getRequestDispatcher("/GServlet").include(request, response); response.getWriter().write("这是第二部分!
"
); } }
public class GServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.getWriter().write("这是相同的部分!
"
); } }

JAVA EE-REQUEST&RESPONSE_第3张图片
Request的其他功能

  1. 请求转发/请求包含

    请求转发:
    一个servlet里面处理逻辑, 将处理结果交给下一个Servlet(JSP)负责显示.

    操作(代码):
    request.getRequestDispatcher(“/EServlet”).forward(request,response);

    问题: 将转发与重定向做对比,有什么异同?

    1.浏览器一共发送了几个请求?
            重定向: 两次请求
            转发: 一次请求
    
    2.浏览器的地址发生变化吗?
            重定向:  会发生变化
            转发:  不会发生变化
    
    3.会改变请求方式吗?
            重定向:  未必.重定向的第2次请求一定是get.
            转发:  不会.    
    4.request域可不可以共享数据?
            重定向:  不可以,因为会产生两个request对象.
            转发:  可以. 因为是在一个请求范围内.使用的是同一个request对象.
    

    注意:
    servlet 向 jsp转发. servlet专注于逻辑处理。 JSP专注于显示处理结果。 不要在应该处理逻辑的地方做显示操作。也就是说在servlet中
    不要使用字符流或字节流做任何输出的动作(不能添加响应正文)。 可以添加响应头。

    转发的Servlet不可以向response的正文中添加任何内容.但是可以向响应头添加内容.
    

    //——————————————————————————————————————————————

    请求包含
    一般请求包含不会在两个servlet中进行.都是在两个jsp中进行.
    当在多个页面总有需要重复显示的内容. 我们可以把这段内容封装到一个jsp中. 以后凡是要显示这段重复的内容时,只需要把封装的jsp包含进来即可.

    操作(代码):
    request.getRequestDispatcher(“/XXX”).include(request,response);

//—————————————————————————————————-

  1. Request域
    request域就是一个放在request对象中的map.

    request域范围:
    与request对象的声明周期是一样的. 请求到达服务器时,request对象创建, 当服务器响应浏览器之后, request对象销毁.

    request域通常在请求转发时使用, servlet处理结果,将结果放置到request域中,带给jsp显示.

    setAttribute(key,value)
    getAttribute(key)
    removeAttribute(key)
    getAttributeNames()
    

    //——————————————————————————————————

什么时候用转发?
servlet负责处理逻辑, jsp用于显示. 需要共享数据,一定要使用转发. 使用重定向会使数据丢失.

什么时候用重定向?
1. 当需要跳转到站内,并且地址栏要求发生变化时,使用重定向.前提是不需要共享数据.
2. 当需要跳转到站外时,一定只能使用重定向.

你可能感兴趣的:(Java-EE)