JavaWeb的Request对象

Request

1. 原理

1. 步骤

  1. tomcat服务器会根据请求URL中的资源路径,创建对应的Servletdemo的对象。其中URL的资源路径包括虚拟路径+Servlet资源路径
    eg:http://localhost/request/servletdemo1

  2. tomcat服务器会创建request对象和response对象,request对象中封装请求消息数据,此时response对象是没有内容的。

  3. tomcat服务器讲request和response两个对象作为参数传递给service方法,并调用service方法:

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		this.doGet(req,resp);
    }
  1. 程序猿(我们)通过request对象获取用户的请求消息,通过response对象设置响应消息。
  2. 服务器再给出浏览器做出响应之前,会从response对象中拿程序猿设置的响应消息数据。

2. 特别注意

  1. request对象和response对象是有服务器创建的,我们来使用他们。
  2. request对象是获取请求消息的,而response对象是设置响应消息的。

2. 继承的体系结构

ServletRequest ---------接口
|继承
HttpServletRequest-------接口
|实现
org.apache.catalina.connector.RequestFacade类(tomcat编写)打印结果

3. 主要功能

1. 获取请求消息数据

1.获取请求行数据

eg: GET / request / demo1 ? name = zhangsan HTTP /1.1

  1. 获取请求方式:GET
		String method = requset.getMethod();
  1. (非常重要) 获取 虚拟目录 :/requset
		String contextPath = request.getContextPath();
  1. 获取Servlet 路径 : /demo1
        String servletPath = request.getServletPath();
  1. 获取get方式的请求参数 : name = zhangsan
        String queryString = request.getQueryString();
  1. (非常重要) 获取请求 URI :/request/demo1

    URI:统一资源标识符(范围大)/request/demo1

		String requestURI = request.getRequestURI();
URL:统一资源定位符(范围小)http://localhost/request/demo1 
        StringBuffer requestURL = request.getRequestURL();
  1. 获取协议及版本 : HTTP /1.1
        String protocol = request.getProtocol();
  1. 获取客户端的IP地址
        String remoteAddr = request.getRemoteAddr();
2. 获取请求头数据
1. 方法
  1. 获取所有的请求头名称
        Enumeration<String> headerNames = req.getHeaderNames();
//        2.遍历
        while (headerNames.hasMoreElements()){
            String name = headerNames.nextElement();
            String value = req.getHeader(name);
            System.out.println(name+" "+value);
        }
  1. (非常重要) 通过请求头的名称获取请求头的值, 比较重要的如 user-agent 、 referer
        String header = req.getHeader("user-agent");//使用什么浏览器解析
		//chrome浏览器
		Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36
盗链问题

通过Referer可以获取请求的客户端的虚拟路径,从而解决盗链问题

        String referer = req.getHeader("referer");
      
        if (referer!=null){
            if (referer.contains("request")){
                resp.setContentType("text/html;charset=utf-8");
                resp.getWriter().write("正常访问");
            }else {
                resp.setContentType("text/html;charset=utf-8");
                resp.getWriter().write("盗链");
            }
        }
2. 2个tomcat

两个tomcat服务器进行通信,具体的一些细节如下面两张图
在这里插入图片描述
在这里插入图片描述

3. 获取请求体数据

请求体:只有在POST的请求方式下才有请求体。在请求体中封装了POST请求的请求参数。
步骤:(具体见response文章中的文件上传)

  1. 获取流对象
		获取字符输入流,只能操作字符数据
		BufferedReader br = req.getReader();
		
		获取字节输入流,可以操作所有类型数据
		ServletInputStream is = req.getInputStream();
  1. 从流对象中拿数据

2. 其他功能

获取请求参数通用方式

无论是get还是post请求方式都可以使用下列方法来获取请求参数,所以并不需要在doPost方法和doGet方法都写一样的代码。只需要在一个方法里直接调用另一个方法就可以了。

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }
1. 四种方法
  1. 根据参数名称获取参数值(text)
        String username = req.getParameter("username");
  1. 根据参数名称获取参数值的数组(CheckBox)
        String[] hobbies = req.getParameterValues("hobby");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }
  1. 获取所有请求的参数名称(有点像getheadNames)
        Enumeration<String> parameterNames = req.getParameterNames();
        while (parameterNames.hasMoreElements()){
            String name = parameterNames.nextElement();
            String value = req.getParameter(name);
            System.out.println(name+" "+value);
        }
  1. 获取所有参数的map集合
        Map<String, String[]> parameterMap = req.getParameterMap();
        for (String name : parameterMap.keySet()) {
            String[] values = parameterMap.get(name);
            for (String value : values) {
                System.out.println(name+" "+value);
            }
        }
2.中文乱码
  1. Get请求方式: tomcat方式已经将get方式的乱码问题全部解决
  2. POST请求方式: 会乱码
    解决:在获取参数前,设置request的编码为utf-8
		request.setCharacterEncoding("utf-8");
请求转发

一种在服务器内部的资源跳转方式(区别重定向)

步骤
  1. 通过request对象获取请求转发对象
		RequestDispatcher requestDispatcher = req.getRequestDispatcher("/requestDemo9");
  1. 使用RequestDIspatcher对象进行转发:
		requestDispatcher.forward(req,resp);

链式编程:

        req.getRequestDispatcher("/requestDemo9").forward(req,resp);
特点
  1. 浏览器地址栏路径不发生变化
  2. 只能转发到当前的服务器内部资源中
  3. 转发是一次请求
共享数据
域对象

一个有作用范围的对象,可以在范围内共享数据

request域

代表一次请求的范围,一般用于请求转发的多个资源中共享的数据
方法:

  1. 存储数据
		//demo8
		req.setAttribute(String name ,Object obj);
  1. 通过键获取值
		//demo9
		Object msg = req.getAttribute(String name);
  1. 通过键移除键值对
		void removeAttribute(String name);
获取ServletContext

具体见Response帖子中ServletContext

ServletContext servletContext = req.getServletContext();
输出:org.apache.catalina.core.ApplicationContextFacade@11396da6

4. 遇到的问题

1. JavaBean

1. 基本概念

BeanUtils工具类,通常用来简化数据封装。 但是如果需要用JavaBean的话,需要对类进行一定的要求:

  1. 类必须被public封装
public class User {}
  1. 必须提供空惨的构造器
public User() {
    }
  1. 成员变量必须使用private修饰
    private Integer id;
    private String username;
    private Integer salary;
    private String password;
    private String gender;

使用引用方法,避免在数据库中读出来的数据里出现类型不匹配,如读取的是Double,类定义的是double

  1. 提供公共的setter和getter方法(*非常重要)

    JavaBean获取成员变量是通过setter方法和getter方法截取
    通常先去掉get单词,然后再改变第一个首字母的大小写。如:getUsername()–> Username–>username

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

而下面这个即为ggender

    public void setggender(String gender){
        this.gender = gender;
    }
    public String getggender(){
        return this.gender;
    }
2. 常用方法

1.setProperty()
2.getProperty()
3.populate(Object obj,Map map):将map集合的键值对信息封装到对应的JavaBean对象中。

//        3.2 使用beanutils封装 用apache那个
        try {
            BeanUtils.populate(loginUser,map);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

如果没有使用正确的getter方法和setter方法,那么在使用populate(Object obj,Map map)时,很可能会出现Java对象的某些变量没有成功被赋值。
这里当时参考了这个blog的大佬才发现,附上地址:

https://blog.csdn.net/SWhard/article/details/49002857

2. rebuild

针对idea构建的项目出现的2个小问题

  1. 导包
    有的时候如果导入了一些包,注意idea导入包的名称最好为lib,有一次定义为libs,死活不成功。(回头再试试是否是这个原因,还是原因2)
  2. 复制文件
    javaweb项目很多时候需要复制一些图片或者视频文件到web路径下,
    eg:HTML页面超链接访问img文件下的67.jpg
<a href="/response/img/67.jpg">图片 </a>

复制了2张图片和一个视频到web下的img文件下
然而访问一直出现404错误,后来用Servlet访问出现500错误,才发现在output文件夹下的artifacts文件夹下并没有img\67.jpg
img下文件下并没有67.jpg
于是后来搜了一段时间,才又在一个大佬的blog下找到解决方法

https://blog.csdn.net/a755199443/article/details/89558696

其实在复制了一些文件到module中,有时候是需要rebuild到out文件夹里!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值