请求消息req

package servlet;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Enumeration;

@WebServlet("/reqdemo")
public class TestReqServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        System.out.println("get"+req);
        System.out.println(req.getMethod());
        System.out.println(req.getQueryString());   //获取get方式的请求参数


    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        System.out.println("post"+req); //postorg.apache.catalina.connector.RequestFacade@43c82cad
        System.out.println(req.getMethod());    //POST
        System.out.println(req.getContextPath());   ///812_req_war_exploded
        System.out.println(req.getServletPath());   ///reqdemo
        System.out.println(req.getRequestURI());    ///812_req_war_exploded/reqdemo
        System.out.println(req.getRequestURL());    //http://localhost:8080/812_req_war_exploded/reqdemo
        System.out.println(req.getProtocol());      //HTTP/1.1
        System.out.println(req.getRemoteAddr());    //0:0:0:0:0:0:0:1

        System.out.println(req.getQueryString());   //null

        //以上都是关于请求行的信息获取操作
        //test可知,默认的方式是get,如果表单的提交方式有设置为post,那么doGet方法体无视
        //如果从浏览器直接访问本Servlet,就是默认get
        //这样就很不安全,比如如果这个Servlet将参数获取并写入数据库,不停的攻击这个Servlet,就打爆了数据库.
        //所以要想一个方法,只有通过了一些判断才能访问这个Servlet

        //关于请求行有两个方法需要注意
        //getRequestURI();  也就是统一资源标识符
        //getRequestURL();  也就是统一资源定位符
        //范围大小: 资源标识符 > 资源定位符
        System.out.println("-----------------------------------------------------------------------------------------------------");


        //Enmeration<String> getHeadernames();
        Enumeration<String> headNames = req.getHeaderNames();   //获取该次请求的所有请求头key
        while(headNames.hasMoreElements()){
    
    
            String elementkey = headNames.nextElement();
            String elementvalue = req.getHeader("elementkey");//通过请求头的key,获取value
            System.out.println(elementkey+":"+elementvalue);
        }
        /*
        host:null
        connection:null
        content-length:null
        cache-control:null
        sec-ch-ua:null
        sec-ch-ua-mobile:null
        upgrade-insecure-requests:null
        origin:null
        content-type:null
        user-agent:null
        accept:null
        sec-fetch-site:null
        sec-fetch-mode:null
        sec-fetch-user:null
        sec-fetch-dest:null
        referer:null
        accept-encoding:null
        accept-language:null
        cookie:null
        */
        System.out.println(req.getHeader("user-agent")); //Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36
        System.out.println(req.getHeader("referer")); //http://localhost:8080/812_req_war_exploded/
        //以上就是请求头信息的获取
        //Enumeration<String>这个容器可以当做迭代器来使用
        //存放请求头的所有key的这么一个容器
        //他的对象有两个方法
        //hasMoreElements(); //判断当前指针之后还有没有存放对象
        //nextElement(); //将指针跳到下一个对象
        //后面对头的key熟悉之后
        //直接使用String getHeader(String key); 通过请求头的key,获取value
        //这里补充复习一个String的方法
        //String类型有一个方法:contains(),该方法是判断字符串中是否有子字符串。如果有则返回true,如果没有则返回false。这个方法是对getHeader获取的value的进一步使用必备方法
        System.out.println("-----------------------------------------------------------------------------------------------------");



        BufferedReader postInput = req.getReader();
        String line = null;
        while ((line = postInput.readLine())!= null){
    
    
            System.out.println(line);
        }
        //以上就是请求体的信息的获取
        //请求体是只有post方式才有的信息
        //Servlet中有两种容器可以存放请求体的信息
        //一种是字符流BufferedReader : 只能操作字符数据
                    //他的对象有readLine();方法可以获取指针当前行的String数据,并且执行完该方法一次就会将指针下移一次.
        //一种是字节流ServletInputStream : 能操作所有类型的数据
                    //针对的是文件上传的技术
        System.out.println("-----------------------------------------------------------------------------------------------------");


        //String getParameter(String name);  根据参数名称获取参数值
        //String[] getParameterValues(String name);  根据参数名称获取参数的值的数组
        //Enumerate<String> getParameterNames();  获取所有参数的name
        //Map<String, String[]> getParameterMap(); 获取所有参数的map集合

        //以上就是req的通用的获取参数的方式
        //相比于get方式的getQueryString();获取字符串
        //或者post方式的字符流方式获取请求体一行一行的字符串
        //通用方法直接利用元素的name属性获取对应的value或者values
        //这样一来get和post唯一的区别也就不存在了可以直接用this.doPost(req. resp);写在doGet里面,这样一来就不用写两份代码,得以简化开发.
        //这里有需要补充复习的两个方法,是关于Map的操作的
        //得到Map<String, String[]>的对象之后,可以用keySet();方法,获取Map中key的并封装成数组对象,利用foreach循环,单独的将各个key拿出来操作,Map<String, String[]>的对象还
        //有一个get(String key)方法,可以获取Map的各个value对象,再进行一层循环即可.

        //接下来就是中文乱码的问题
        //信息在不同平台之间跳转的时候,总难免考虑一个编码格式的问题
        //这里接受req的信息之前一般要先req的编码问题解决掉,                            可是,每一个Servlet都写这样的不烦吗,还有Servlet的一个安全访问问题,其实是同一个问题,如果在req到达Servlet之前,能够进行一些逻辑处理不就好了
        //setCharacterEncoding("utf-8");


        System.out.println("-----------------------------------------------------------------------------------------------------");


        /*
        * req一般是由浏览器出
        * 从服务器入
        * 也就是说
        * req的来源一般都是浏览器
        * 但是req就没有别的来源了吗
        * 能不能来自服务器呢?
        * 或者说req的终点就只是一个Servlet吗?
        *
        * Servlet中有一个工具对象叫做req转发器
        * RequestDispatcher
        * 可以由req的getRequestDispatcher(String path);方法获取
        * RequestDispatcher的对象创建出来之后,就可以使用他的forward(req, resp);方法将本地Servlet接受到的req给转发到别的地方处理
        *
        * 注意的是:
        * Servlet中的这种req转发器
        * 只能认识服务器的内部资源.也即是说不在服务器内部的资源是无法转发的
        * 还有就是浏览器本身只认识第一个接受我req的资源地址,后面间接接受我这次req的资源,浏览器表示与我何干.
        *
        * 这样一个问题就接踵而至
        * 就是浏览器我这一次req同时被你们这么多Servlet同时处理过
        * 那老子怎么接受你们的resp呢
        * 接受谁的好呢
        * 还有
        * 既然一次req的处理让多个Servlet分摊了
        * 那么,AServlet用不用告诉BServlet做了什么工作了呢
        * 也就是说,AServlet除了给BServlet转发了req之外,用不用还随之发送一些个信息呢
        *
        * */
        System.out.println("-----------------------------------------------------------------------------------------------------");


        /*要解决以上的两个问题
        * 首先就要理解什么是域对象 :  也就是一个保存信息的信息对象,同时可以被好多个进程处理,能处理这个信息对象的进程就组成一个域,在这个域总可以共享req的数据
        * 补充: 通过req还能直接获取另一个域对象(ServletContext), 这个域对象的范围就不仅仅是req一次的web资源,而是所有的资源.
        * req就是其中一种域对象
        * req除了本身从浏览器那里来的http请求信息,还能在服务器端开辟一块只有域内进程才能获取的数据存放空间
        *       void setAtribute(String name, Object object);   存储数据
        *       Object getAttribute(String name);   通过键获取值
        *       void removeAttribute(String name);  移除一个键值对
        * 那么问题就来了
        * 除了第一个Servlet,转发的Servlet还能接受http请求信息吗,还是只能要服务器端里数据空间的信息 (而这就是解开以上第一个问题的关键)
        * */

        System.out.println("-----------------------------------------------------------------------------------------------------");

        //req学到这里也算差不多了
        //但是还有两个问题没有答案
        //这里建议先去看一下最高层的域对象
        //ServletContext
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_45032905/article/details/121855468
今日推荐