您当前的位置:首页 > 电脑百科 > 程序开发 > 框架

超级赞!SpringMVC中的请求参数的完美处理技巧

时间:2021-08-16 11:39:45  来源:  作者:想拥有一头秀发

本篇文章我们来学习一下SpringMVC中是如何处理请求中的参数的。

回想一下原生Servlet是如何处理请求参数的?我们需要使用HttpServletRequest调用getParameter方法进行获取,就像这样:

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取参数值
        String username = req.getParameter("username");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

下面来看看SpringMVC是如何处理这一需求的。

@RequestParam

在SpringMVC中,我们可以直接在方法上声明入参获取请求参数,比如:

@Controller
public class HelloController {

    @RequestMApping("/hello")
    public String hello(String username) {
        System.out.println(username);
        return "success";
    }
}

那在传递参数的时候参数名就必须指定为username,这样处理方法就能够直接获取到请求参数,当然了,这样获取有一个弊端,就是参数名被固定了,只能是username,我们可以在参数前添加@RequestParam注解来解决:

@RequestMapping("/hello")
public String hello(@RequestParam("user") String username) {
    System.out.println(username);
    return "success";
}

此时参数名就可以随意定义,转而由@RequestParam注解来指定需要接收的参数名。

当请求中未携带user参数时,程序就会出错:

Resolved exception caused by handler execution: org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'user' is not present

这是因为@RequestParam默认要求参数必须携带,否则就会报错,可以通过修改注解中的required属性值来解决这一个问题:

@RequestMapping("/hello")
public String hello(@RequestParam(value = "user",required = false) String username) {
    System.out.println(username);
    return "success";
}

此时无论是否携带user参数,程序都不会出错,当未携带user参数时,username值为null。

还可以通过配置defaultValue属性值来指定当参数未携带时的默认值:

@RequestMapping("/hello")
public String hello(@RequestParam(value = "user",required = false,defaultValue = "zhang") String username) {
    System.out.println(username);
    return "success";
}

此时当请求未携带user参数时,username值为 zhang 。

@RequestHeader

SpringMVC中也能非常方便地获取请求头中的信息,如:

@RequestMapping("/hello")
public String hello(@RequestHeader("User-Agent") String userAgent) {
    System.out.println(userAgent);
    return "success";
}

通过@RequestHeader注解即可轻松获取请求头信息,其value值为请求头的key,和@RequestParam注解类似,当试图去获取一个不存在的请求头时,程序便会报错:

@RequestMapping("/hello")
public String hello(@RequestHeader("test") String userAgent) {
    System.out.println(userAgent);
    return "success";
}

报错信息为:

Missing request header 'test' for method parameter of type String

所以也可以在注解中添加required属性来解决:

@RequestMapping("/hello")
public String hello(@RequestHeader(value = "test",required = false) String userAgent) {
    System.out.println(userAgent);
    return "success";
}

defaultValue属性也是一样的用法。

@RequestBody

在前后端分离的项目开发中,后端接收到的往往并不是一个直接的字符参数,而是一串JSON数据,那么该如何处理JSON类型的请求参数呢?

其实很简单,先接收到JSON参数,再通过一些第三方库将JSON解析成正常的属性值即可,而在SpringMVC中,可以直接使用@RequestBody注解来解决:

@RequestMapping("/hello")
public String hello(@RequestBody String json) {
    System.out.println(json);
    return "success";
}

通过这种方式能够获取到前端提交的JSON参数:

{"name:"张三","age":"20"}

你还可以直接将请求参数中的JSON串转换为Bean对象:

@RequestMapping("/hello")
public String hello(@RequestBody Person person) {
    System.out.println(person);
    return "success";
}

此时SpringMVC将按照参数名和Person对象中的属性名进行一一对应,并将参数值封装到Person中生成一个对象,这样便极大地方便了开发流程。

@CookieValue

通过@CookieValue注解可以很方便地获取到请求中的cookie信息:

@RequestMapping("/hello")
public String hello(@CookieValue("_ga") String ga) {
    System.out.println(ga);
    return "success";
}

同理,若是获取不存在的cookie,也会出现错误,解决方案和前面是一样的,就不再赘述了。

传入对象类型

当请求参数较为复杂时,比如一个对象,如果借助@RequestParam注解,就必须这样:

@RequestMapping("/hello")
public String hello(
    @RequestParam("name") String name,
    @RequestParam("age") Integer age,
    @RequestParam("sex") Character sex,
    @RequestParam("address") String address
    ) {
        System.out.println(name);
        System.out.println(age);
        System.out.println(sex);
        System.out.println(address);
        return "success";
    }

并且随着参数的增多,这种冗余的代码还要继续编写,为此,SpringMVC有一个更加优雅的解决方案,就是直接接收一个对象类型的参数,所以,要先将这些参数封装成一个对象:

@Data
@ToString
public class Person {
    private String name;
    private Integer age;
    private Character sex;
    private String address;
}

此时方法中只需接收一个Person类型的参数即可:

@RequestMapping("/hello")
public String hello(Person person) {
    System.out.println(person);
    return "success";
}

它同时还支持级联封装,如:

@Data
@ToString
public class Person {
    private String name;
    private Integer age;
    private Character sex;
    private Address address;
}

@Data
@ToString
public class Address {
    private String province;
    private String city;
}

现在Person对象中的地址属性仍然是一个对象,SpringMVC仍然能够将数据准确无误地封装到Person参数中,但请求参数在传递时就需要通过 . 来进行传送,比如:

http://localhost:8080/hello?name=zhangsan&sex=f&age=20&address.province=jiangxi&address.city=nanchang

需要注意的是请求参数中的参数名必须和对象中定义的属性名一致。

传入原生API

有时候一些需求也不得不使用到原生的API,比如设置cookie、session等,SpringMVC当然也考虑到了这一点,所以若是想使用原生的API,则直接写到方法的入参中即可,如:

@RequestMapping("/hello")
public String hello(HttpServletResponse response) {
    Cookie cookie = new Cookie("test", "test");
    response.addCookie(cookie);
    return "success";
}

想操作Session,就将HttpSession作为参数传入:

@RequestMapping("/hello")
public String hello(HttpSession session) {
    session.setAttribute("test","test");
    return "success";
}

SpringMVC支持以下九个ServletAPI的对象:

1.HttpServletRequest2.HttpServletResponse3.HttpSession4.JAVA.security.Principal5.Locale6.InputStream7.OutputStream8.Reader9.Writer

这九个对象都能够直接以参数的形式传入方法中。

解决乱码问题

如果在发送请求时携带的参数是中文的,就会产生乱码,在原生的Servlet开发中,我们通常使用:

request.setCharacterEncoding("UTF-8");

但这是用来解决POST请求乱码的,对于响应的乱码,应使用:

response.setContentType("text/html;charset=utf-8");

然而在SpringMVC中,我们通常不会使用到HttpServletRequest和HttpServletResponse对象,那么乱码问题该如何解决呢?

可以定义一个Filter过滤器,来拦截所有请求,并在过滤器中集中处理乱码的问题,SpringMVC已经考虑到了这一点,并为我们提供了一个专门解决乱码问题的过滤器CharacterEncodingFilter,只需在web.xml文件中进行配置:

<filter>
  <filter-name>characterEncodingFilter</filter-name>
  <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  <init-param>
    <param-name>encoding</param-name>
    <param-value>UTF-8</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>characterEncodingFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

注意:若项目中配置了多个Filter,则CharacterEncodingFilter一定要配置在其它Filter之前。

以上便是有关SpringMVC中处理请求参数的全部内容!



Tags:SpringMVC   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
本篇文章我们来学习一下SpringMVC中是如何处理请求中的参数的。回想一下原生Servlet是如何处理请求参数的?我们需要使用HttpServletRequest调用getParameter方法进行获取,就像...【详细内容】
2021-08-16  Tags: SpringMVC  点击:(70)  评论:(0)  加入收藏
背景:项目是老项目,而且比较旧为springmvc项目。项目使用的框架为公司内部自己开发,目前已经没有框架的源码可供修改,配置文件写在底层框架内,可以看到但修改不到。目的是为了实...【详细内容】
2021-08-11  Tags: SpringMVC  点击:(70)  评论:(0)  加入收藏
一、什么是springmvc?我们知道三层架构的思想,并且如果你知道ssh的话,就会更加透彻地理解这个思想,struts2在web层,spring在中间控制,hibernate在dao层与数据库打交道,而前面刚写...【详细内容】
2021-07-14  Tags: SpringMVC  点击:(93)  评论:(0)  加入收藏
前言学了一遍SpringMVC以后,想着做一个总结,复习一下。复习写下面的总结的时候才发现,其实自己学得并不彻底、牢固、也没有学全,视频跟书本是要结合起来一起,每一位老师的视频可...【详细内容】
2021-03-08  Tags: SpringMVC  点击:(193)  评论:(0)  加入收藏
对Java程序员来讲,做web开发最熟悉的框架莫过于SpringMVC了。之所以它能一统江湖,不是自己太优秀,而是对手太坑了,不知道大家还记不记得2017年左右Struts2爆出了一个大漏洞,自此...【详细内容】
2020-10-14  Tags: SpringMVC  点击:(66)  评论:(0)  加入收藏
Ajax 异步交互SpringMVC 默认用 MappingJackson2HttpMessageConverter 对 JSON 数据进行转换,需要加入 Jackson 的包;同时在 spring-mvc.xml 使用 <mvc:annotation-driven />....【详细内容】
2020-09-14  Tags: SpringMVC  点击:(75)  评论:(0)  加入收藏
MVC是英文Modle View Controller的简称,是一种软件设计典范,目的是将业务逻辑、数据、页面视图代码分离,达到增加开发效率、降低耦合度、代码更利于维护的目的。 Spring MVC是...【详细内容】
2020-08-06  Tags: SpringMVC  点击:(53)  评论:(0)  加入收藏
前言大家好,我是bigsai,今天我们学习SpringMVC的文件上传下载。文件上传和下载是互联网web应用非常重要的组成部分,它是信息交互传输的重要渠道之一。你可能经常在网页上传下...【详细内容】
2020-07-30  Tags: SpringMVC  点击:(57)  评论:(0)  加入收藏
今天就由本大佬(请原谅我使用了略微夸张的修辞手法)亲自带队,来为大家导游,带领大家探秘神奇的SpringMVC世界,重走一次HTTP请求处理之路,本次行程共计7站,约用时10分钟。 来来来,上...【详细内容】
2020-03-24  Tags: SpringMVC  点击:(110)  评论:(0)  加入收藏
这节介绍SpringMVC,SpringMVC是一种基于Java的实现MVC设计模式的请求驱动类型的轻量级Web框架。本章会介绍相关概念,流程,再从源码进行讲解。1. MVC&emsp;MVC(Model View Contr...【详细内容】
2020-01-07  Tags: SpringMVC  点击:(50)  评论:(0)  加入收藏
▌简易百科推荐
近日只是为了想尽办法为 Flask 实现 Swagger UI 文档功能,基本上要让 Flask 配合 Flasgger, 所以写了篇 Flask 应用集成 Swagger UI 。然而不断的 Google 过程中偶然间发现了...【详细内容】
2021-12-23  Python阿杰    Tags:FastAPI   点击:(6)  评论:(0)  加入收藏
文章目录1、Quartz1.1 引入依赖<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.2</version></dependency>...【详细内容】
2021-12-22  java老人头    Tags:框架   点击:(11)  评论:(0)  加入收藏
今天来梳理下 Spring 的整体脉络啦,为后面的文章做个铺垫~后面几篇文章应该会讲讲这些内容啦 Spring AOP 插件 (了好久都忘了 ) 分享下 4ye 在项目中利用 AOP + MybatisPlus 对...【详细内容】
2021-12-07  Java4ye    Tags:Spring   点击:(14)  评论:(0)  加入收藏
&emsp;前面通过入门案例介绍,我们发现在SpringSecurity中如果我们没有使用自定义的登录界面,那么SpringSecurity会给我们提供一个系统登录界面。但真实项目中我们一般都会使用...【详细内容】
2021-12-06  波哥带你学Java    Tags:SpringSecurity   点击:(18)  评论:(0)  加入收藏
React 简介 React 基本使用<div id="test"></div><script type="text/javascript" src="../js/react.development.js"></script><script type="text/javascript" src="../js...【详细内容】
2021-11-30  清闲的帆船先生    Tags:框架   点击:(19)  评论:(0)  加入收藏
流水线(Pipeline)是把一个重复的过程分解为若干个子过程,使每个子过程与其他子过程并行进行的技术。本文主要介绍了诞生于云原生时代的流水线框架 Argo。 什么是流水线?在计算机...【详细内容】
2021-11-30  叼着猫的鱼    Tags:框架   点击:(21)  评论:(0)  加入收藏
TKinterThinter 是标准的python包,你可以在linx,macos,windows上使用它,你不需要安装它,因为它是python自带的扩展包。 它采用TCL的控制接口,你可以非常方便地写出图形界面,如...【详细内容】
2021-11-30    梦回故里归来  Tags:框架   点击:(26)  评论:(0)  加入收藏
前言项目中的配置文件会有密码的存在,例如数据库的密码、邮箱的密码、FTP的密码等。配置的密码以明文的方式暴露,并不是一种安全的方式,特别是大型项目的生产环境中,因为配置文...【详细内容】
2021-11-17  充满元气的java爱好者  博客园  Tags:SpringBoot   点击:(25)  评论:(0)  加入收藏
一、搭建环境1、创建数据库表和表结构create table account(id INT identity(1,1) primary key,name varchar(20),[money] DECIMAL2、创建maven的工程SSM,在pom.xml文件引入...【详细内容】
2021-11-11  AT小白在线中  搜狐号  Tags:开发框架   点击:(29)  评论:(0)  加入收藏
SpringBoot开发的物联网通信平台系统项目功能模块 功能 说明 MQTT 1.SSL支持 2.集群化部署时暂不支持retain&will类型消 UDP ...【详细内容】
2021-11-05  小程序建站    Tags:SpringBoot   点击:(55)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条