request.getParameter()和request.getAttribute()比较

getParameter与getAttribute相同点

  1. 都是HttpServletRequest类中的方法
  2. 都是用来传递数据用的

getParameter与getAttribute不同点

  1. getParameter():
    1.1. 响应的是两个web组件之间为==链接(重定向)==关系时,类似get,post等方式传入的数据。
    1.2. 此种方法从Web客户端传到Web服务器端,代表HTTP请求数据。
    1.3. 返回String类型的数据。
    1.4. 只有get方法没有set方法。

  2. getAttribute():
    2.1. 响应的是两个web组件之间为转发关系时传入的数据。
    2.2. 服务端的转发源通过setAttribute()设置传递的参数,然后转发目的通过getAttribute()获取传递的参数,这样转发时数据就不会丢失,此种方法只是在web容器内部流转,也就是说必须在同一个request对象中使用才有效。
    2.3. 返回Object类型的数据。
    2.4. 既有get方法也有set方法。

举例说明

getParameter()

后端控制器内有一个接口/test/param-request,debug模式下启动项目

    @RequestMapping(value = "/param-request", method = RequestMethod.GET)
    public void paramRequest(HttpServletRequest request, HttpServletResponse response) {
     
        // id=123
        String id = request.getParameter("id");
        // values=a&values=b
        String[] parameterValues = request.getParameterValues("values");
        Map<String, String[]> parameterMap = request.getParameterMap();
        Enumeration<String> parameterNames = request.getParameterNames();

        Object name = request.getAttribute("name");
        Enumeration<String> attributeNames = request.getAttributeNames();

        System.out.println("param-request");
    }

通过postman对其发送请求
request.getParameter()和request.getAttribute()比较_第1张图片
通过下图所示可以看到,id等参数已经通过getParameter()拿到了,而getAttribute()并没有拿到name参数。
request.getParameter()和request.getAttribute()比较_第2张图片

getAttribute()

后端控制器内有一个接口/test/attr-request,debug模式下启动项目

    @RequestMapping(value = "/attr-request", method = RequestMethod.GET)
    public void attrRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     
        request.setAttribute("name", "小刚");
        request.getRequestDispatcher("/test/param-request").forward(request, response);

        System.out.println("attr-request");
    }

通过postman对其发送请求
request.getParameter()和request.getAttribute()比较_第3张图片
通过下图所示可以看到,attr-request接口内通过setAttribute()放入了一对属性,然后将请求转发给了param-request,getAttribute()可以拿到name参数。
request.getParameter()和request.getAttribute()比较_第4张图片

小插曲

在写接口对这两个方法进行测试的时候,发现一个奇怪的现象,在请求接口的时候发现返回的数据是404错误。

{
     
    "timestamp": "2020-06-25T05:12:50.661+0000",
    "status": 404,
    "error": "Not Found",
    "message": "No message available",
    "path": "/test/param-request"
}

一开始以为是自己的请求地址写错了,经过检查后发现,请求地址是正确的,而且实际上接口已经成功请求到了,只是前端返回的数据是404错误。
查看了几篇博客后,给出的答案大多就是 @Controller@RestController 导致的(具体可以看这篇博客https://blog.csdn.net/tanzhen1991910/article/details/82078206):

  1. @Controller 是视图解析器的,即Return返回的是视图,即jsp或者html页面的。spring对返回值映射时找不到对应的视图,所以会返回404错误。
  2. 如果返回数据json、xml等,需要在对应的方法上加上@ResponseBody注解,而@RestController则是@Controller和@ResponseBody两个注解的结合。

解决办法:

  1. 如果返回的是视图,即html、jsp等,使用@Controller即可,如果返回的是数据,即xml、json等,@Controller与@ResponseBody结合使用或者使用@RestController。
  2. 如果像我本次示例中这样,不想返回任何值,使用@Controller即可,但是参数值需要加上HttpServletResponse。

虽然问题解决了,但是对于为什么会出现这种问题的原因,网上给出的答案并不深入,我自己也没有做过多的了解,希望以后有机会了解源码的时候可以找出造成这个问题更深一步的原因。

小结

曾经刚接触javaWeb开发,使用servlet以及jsp的时候,倒是经常使用getParameter()以及getAttribute()方法,但是并没有过多的考虑过它俩之间的不同,如今,习惯了在框架下编码,反而对这两个方法越来越陌生了,在此将其记录下来,以便日后进行回顾温习!

你可能感兴趣的:(spring,Boot,java,spring,java)