每日一课程序员Java学习笔记

Servlet第四篇【request对象常用方法、应用】

2018-02-04  本文已影响68人  Java3y

什么是HttpServletRequest

HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。

简单来说,要得到浏览器信息,就找HttpServletRequest对象

HttpServletRequest常用方法

获得客户机【浏览器】信息

获得客户机请求头

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


HttpServletRequest应用

防盗链

什么是防盗链呢?比如:我现在有海贼王最新的资源,想要看海贼王的要在我的网页上看。现在别的网站的人看到我有海贼王的资源,想要把我的资源粘贴在他自己的网站上。这样我独家的资源就被一个CTRL+C和CTRL+V抢走了?而反盗链就是不能被他们CRTL+C和CRTL+V

image image image

        //获取到网页是从哪里来的
        String referer = request.getHeader("Referer");

        //如果不是从我的首页来或者从地址栏直接访问的,
        if ( referer == null || !referer.contains("localhost:8080/zhongfucheng/index.jsp") ) {

            //回到首页去
            response.sendRedirect("/zhongfucheng/index.jsp");
            return;
        }

        //能执行下面的语句,说明是从我的首页点击进来的,那没问题,照常显示
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().write("路飞做了XXXXxxxxxxxxxxxxxxxx");

image

\

image image image image image

表单提交数据【通过post方式提交数据】


<form action="/zhongfucheng/Servlet111" method="post">
    <table>
        <tr>
            <td>用户名</td>
            <td><input type="text" name="username"></td>
        </tr>
        <tr>
            <td>密码</td>
            <td><input type="password" name="password"></td>
        </tr>
        <tr>
            <td>性别</td>
            <td>
                <input type="radio" name="gender" value="男">男
                <input type="radio" name="gender" value="女">女
            </td>
        </tr>
        <tr>
            <td>爱好</td>
            <td>
                <input type="checkbox" name="hobbies" value="游泳">游泳
                <input type="checkbox" name="hobbies" value="跑步">跑步
                <input type="checkbox" name="hobbies" value="飞翔">飞翔
            </td>
        </tr>
        <input type="hidden" name="aaa" value="my name is zhongfucheng">
        <tr>
            <td>你的来自于哪里</td>
            <td>
                <select name="address">
                    <option value="广州">广州</option>
                    <option value="深圳">深圳</option>
                    <option value="北京">北京</option>
                </select>
            </td>
        </tr>
        <tr>
            <td>详细说明:</td>
            <td>
                <textarea cols="30" rows="2" name="textarea"></textarea>
            </td>
        </tr>
        <tr>
            <td><input type="submit" value="提交"></td>
            <td><input type="reset" value="重置"></td>
        </tr>
    </table>


        //设置request字符编码的格式
        request.setCharacterEncoding("UTF-8");

        //通过html的name属性,获取到值
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String gender = request.getParameter("gender");

        //复选框和下拉框有多个值,获取到多个值
        String[] hobbies = request.getParameterValues("hobbies");
        String[] address = request.getParameterValues("address");

        //获取到文本域的值
        String description = request.getParameter("textarea");

        //得到隐藏域的值
        String hiddenValue = request.getParameter("aaa");

        ....各种System.out.println().......

image image

超链接方式提交数据

常见的get方式提交数据有使用超链接,sendRedirect()

格式如下:


    sendRedirect("servlet的地址?参数名="+参数值 &"参数名="+参数值);


    <a href="/zhongfucheng/Servlet111?username=xxx">使用超链接将数据带给浏览器</a>


        //接收以username为参数名带过来的值
        String username = request.getParameter("username");
        System.out.println(username);

image image image

解决中文乱码问题

细心的朋友会发现,我在获取表单数据的时候,有这句代码request.setCharacterEncoding("UTF-8");,如果没有这句代码,会发生什么事呢?我们看看。

image image image image

        request.setCharacterEncoding("UTF-8");
        String name = request.getParameter("name");

image image

        //此时得到的数据已经是被ISO 8859-1编码后的字符串了,这个是乱码
        String name = request.getParameter("username");

        //乱码通过反向查ISO 8859-1得到原始的数据
        byte[] bytes = name.getBytes("ISO8859-1");

        //通过原始的数据,设置正确的码表,构建字符串
        String value = new String(bytes, "UTF-8");

上面的代码有些难理解,我画张图说明一下:

image image

    <Connector port="8080" protocol="HTTP/1.1" 
               connectionTimeout="20000" 
               redirectPort="8443" URIEncoding="utf-8"/>

image

    <Connector port="8080" protocol="HTTP/1.1" 
               connectionTimeout="20000" 
               redirectPort="8443" useBodyEncodingForURI="true" />


        request.setCharacterEncoding("UTF-8");
        String name = request.getParameter("name");

image

实现转发

之前讲过使用response的sendRedirect()可以实现重定向,做到的功能是页面跳转,使用request的getRequestDispatcher.forward(request,response)实现转发,做到的功能也是页面跳转,他们有什么区别呢?现在我先来说下转发


        //获取到requestDispatcher对象,跳转到index.jsp
        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/index.jsp");

        //调用requestDispatcher对象的forward()实现转发,传入request和response方法
        requestDispatcher.forward(request, response);

image

        //以username为关键字存zhongfucheng值
        request.setAttribute("username", "zhongfucheng");

        //获取到requestDispatcher对象
        RequestDispatcher requestDispatcher = request.getRequestDispatcher("/Servlet222");

        //调用requestDispatcher对象的forward()实现转发,传入request和response方法
        requestDispatcher.forward(request, response);


        //获取到存进request对象的值
        String userName = (String) request.getAttribute("username");

        //在浏览器输出该值
        response.getWriter().write("i am :"+userName);

image

转发的时序图

image

请求转发的细节


        OutputStream outputStream = response.getOutputStream();
        outputStream.write("--------------------------------------------".getBytes());

        //关闭流,确保让数据到浏览器中
        outputStream.close();

        //跳转
        request.getRequestDispatcher("/Foot").forward(request, response);

image

转发和重定向的区别

实际发生位置不同,地址栏不同

用法不同

很多人都搞不清楚转发和重定向的时候,资源地址究竟怎么写。有的时候要把应用名写上,有的时候不用把应用名写上。很容易把人搞晕。记住一个原则:给服务器用的直接从资源名开始写,给浏览器用的要把应用名写上

能够去往的URL的范围不一样

传递数据的类型不同

跳转的时间不同


转发和重定向使用哪一个?

根据上面说明了转发和重定向的区别也可以很容易概括出来。转发是带着转发前的请求的参数的。重定向是新的请求

典型的应用场景:

  1. 转发: 访问 Servlet 处理业务逻辑,然后 forward 到 jsp 显示处理结果,浏览器里 URL 不变
  2. 重定向: 提交表单,处理成功后 redirect 到另一个 jsp,防止表单重复提交,浏览器里 URL 变了

RequestDispatcher再说明

RequestDispatcher对象调用forward()可以实现转发上面已经说过了。RequestDispatcher还有另外一个方法include(),该方法可以实现包含,有什么用呢?

我们在写网页的时候,一般网页的头部和尾部是不需要改变的。如果我们多个地方使用Servlet输出网头和网尾的话,需要把代码重新写一遍。而使用RequestDispatcher的include()方法就可以实现包含网头和网尾的效果了

image

        request.getRequestDispatcher("/Head").include(request, response);

        response.getWriter().write("--------------------------------------------");

        request.getRequestDispatcher("/Foot").include(request, response);

image

如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章的同学,可以关注微信公众号:Java3y

上一篇 下一篇

猜你喜欢

热点阅读