springMVC 参数绑定的注解

2024-09-08 01:08

本文主要是介绍springMVC 参数绑定的注解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文介绍了用于参数绑定的相关注解。

绑定:将请求中的字段按照名字匹配的原则填入模型对象。

SpringMVC就跟Struts2一样,通过拦截器进行参数匹配。

代码在 https://github.com/morethink/MySpringMVC

URI模板变量

这里指uri template中variable(路径变量),不含queryString部分

@PathVariable

当使用@RequestMapping URI template 样式映射时, 即 someUrl/{paramId}, 这时的paramId可通过 @Pathvariable注解绑定它传过来的值到方法的参数上。

示例代码:

@RestController
@RequestMapping("/users")
public class UserAction {@GetMapping("/{id}")public Result getUser(@PathVariable int id) {return ResultUtil.successResult("123456");}}

上面代码把URI template 中变量 ownerId的值和petId的值,绑定到方法的参数上。若方法参数名称和需要绑定的uri template中变量名称不一致,需要在@PathVariable("name")指定uri template中的名称

请求头

@RequestHeader

@RequestHeader 注解,可以把Request请求header部分的值绑定到方法的参数上。

示例代码:

这是一个Request 的header部分:

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
Cache-Control:max-age=0
Connection:keep-alive
Host:localhost:8080
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36
@GetMapping("/getRequestHeader")
public Result getRequestHeader(@RequestHeader("Accept-Encoding") String encoding) {return ResultUtil.successResult(encoding);
}

上面的代码,把request header部分的 Accept-Encoding的值,绑定到参数encoding上。

@CookieValue

可以把Request header中关于cookie的值绑定到方法的参数上。

例如有如下Cookie值:
JSESSIONID=588DC770E582A3189B7E6210102EAE02
参数绑定的代码:

@RequestMapping("/getCookie")
public Result getCookie(@CookieValue("JSESSIONID") String cookie) {return ResultUtil.successResult(cookie);
}

即把JSESSIONID的值绑定到参数cookie上。

请求体

@RequestParam

  • 常用来处理简单类型的绑定,通过Request.getParameter() 获取的String可直接转换为简单类型的情况( String--> 简单类型的转换操作由ConversionService配置的转换器来完成);因为使用request.getParameter()方式获取参数,所以可以处理get 方式中queryString的值,也可以处理post方式中 body data的值;
  • 用来处理Content-Type: 为 application/x-www-form-urlencoded编码的内容,提交方式GET、POST
  • 该注解有两个属性: value、required; value用来指定要传入值的id名称,required用来指示参数是否必须绑定;

示例代码:

@GetMapping("/tesRequestParam")
public Result tesRequestParam(@RequestParam("username") String username) {return ResultUtil.successResult(username);
}

@RequestBody

该注解常用来处理Content-Type: 不是application/x-www-form-urlencoded编码的内容,例如application/json, application/xml等;

它是通过使用HandlerAdapter 配置的HttpMessageConverters来解析post data body,然后绑定到相应的bean上的。

因为配置有FormHttpMessageConverter,所以也可以用来处理 application/x-www-form-urlencoded的内容,处理完的结果放在一个MultiValueMap<String, String>里,这种情况在某些特殊需求下使用,详情查看FormHttpMessageConverter api;

示例代码:

@PostMapping("/tesRequestBody")
public Result tesRequestBody(@RequestBody User user) {return ResultUtil.successResult(user);
}

结果截图:

Content-Type:application/json

@RequestBody通过list接收对象数组

在我们传递对象的时候,无论Content-Typex-www-form-urlencoded还是application/json其实没有多大的关系,可是当我们需要传递对象数组的时候,表单编码就不行了,这时我们是可以采用json传递,然后后台使用@RequestBody注解,通过list接收来对象数组。

前端代码:

index.html

//打开页面时运行
$(document).ready(function () {var users = [];var user1 = {"username": "dd", "password": "123"};var user2 = {"username": "gg", "password": "123"};users.push(user1);users.push(user2);$.ajax({type: "POST",url: "users/saveUsers",timeout: 30000,dataType: "json",contentType: "application/json",data: JSON.stringify(users),success: function (data) {//将返回的数据展示成tableshowTable(data);},error: function () { //请求出错的处理$("#result").text("请求出错");}});
});

后台代码:

@PostMapping("saveUsers")
public Result saveUsers(@RequestBody List<User> users) {return ResultUtil.successResult(users);
}

结果截图:

表格展示数据

@SessionAttribute

该注解用来绑定HttpSession中的attribute对象的值,便于在方法中的参数里使用。该注解有value、types两个属性,可以通过名字和类型指定要使用的attribute 对象

示例代码:

@PostMapping("/setSessionAttribute")
public Result setSessionAttribute(HttpSession session, String attribute) {session.setAttribute("attribute", attribute);return ResultUtil.SUCCESS_RESULT;
}@GetMapping("/getSessionAttribute")
public Result getSessionAttribute(@SessionAttribute("attribute") String attribute) {return ResultUtil.successResult(attribute);
}

我们首先给session添加一个attribute,然后再取出这个attribute。

 

添加属性

得到属性

@ModelAttribute

@ModelAttribute标注可被应用在方法或方法参数上。

方法使用@ModelAttribute标注

标注在方法上的@ModelAttribute说明方法是用于添加一个或多个属性到model上。这样的方法能接受与@RequestMapping标注相同的参数类型,只不过不能直接被映射到具体的请求上。

在同一个控制器中,标注了@ModelAttribute的方法实际上会在@RequestMapping方法之前被调用。

以下是示例:

// Add one attribute
// The return value of the method is added to the model under the name "account"
// You can customize the name via @ModelAttribute("myAccount")@ModelAttribute
public Account addAccount(@RequestParam String number) {return accountManager.findAccount(number);
}// Add multiple attributes@ModelAttribute
public void populateModel(@RequestParam String number, Model model) {model.addAttribute(accountManager.findAccount(number));// add more ...
}

@ModelAttribute方法通常被用来填充一些公共需要的属性或数据,比如一个下拉列表所预设的几种状态,或者宠物的几种类型,或者去取得一个HTML表单渲染所需要的命令对象,比如Account等。

@ModelAttribute标注方法有两种风格:

  • 在第一种写法中,方法通过返回值的方式默认地将添加一个属性;
  • 在第二种写法中,方法接收一个Model对象,然后可以向其中添加任意数量的属性。

可以在根据需要,在两种风格中选择合适的一种。

一个控制器可以拥有多个@ModelAttribute方法。同个控制器内的所有这些方法,都会在@RequestMapping方法之前被调用。

@ModelAttribute方法也可以定义在@ControllerAdvice标注的类中,并且这些@ModelAttribute可以同时对许多控制器生效。

属性名没有被显式指定的时候又当如何呢?在这种情况下,框架将根据属性的类型给予一个默认名称。举个例子,若方法返回一个Account类型的对象,则默认的属性名为"account"。可以通过设置@ModelAttribute标注的值来改变默认值。当向Model中直接添加属性时,请使用合适的重载方法addAttribute(..)-即带或不带属性名的方法。

@ModelAttribute标注也可以被用在@RequestMapping方法上。这种情况下,@RequestMapping方法的返回值将会被解释为model的一个属性,而非一个视图名,此时视图名将以视图命名约定来方式来确定。

方法参数使用@ModelAttribute标注

标注在方法参数上的@ModelAttribute说明了该方法参数的值将由model中取得。如果model中找不到,那么该参数会先被实例化,然后被添加到model中。在model中存在以后,请求中所有名称匹配的参数都会填充到该参数中。

这在Spring MVC中被称为数据绑定,一个非常有用的特性,我们不用每次都手动从表格数据中转换这些字段数据。

@PostMapping
public Result saveUser(@ModelAttribute User user) {return ResultUtil.successResult(user);
}

以上面的代码为例,这个User类型的实例可能来自哪里呢?有几种可能:

  • 它可能因为@SessionAttributes标注的使用已经存在于model中
  • 它可能因为在同个控制器中使用了@ModelAttribute方法已经存在于model中,正如上一小节所叙述的
  • 它可能是由URI模板变量和类型转换中取得的
  • 它可能是调用了自身的默认构造器被实例化出来的

@ModelAttribute方法常用于从数据库中取一个属性值,该值可能通过@SessionAttributes标注在请求中间传递。在一些情况下,使用URI模板变量和类型转换的方式来取得一个属性是更方便的方式。

在不给定注解的情况下,参数是怎样绑定的?

通过分析AnnotationMethodHandlerAdapterRequestMappingHandlerAdapter的源代码发现,方法的参数在不给定参数的情况下:

  • 若要绑定的对象时简单类型:调用@RequestParam来处理的。
    这里的简单类型指Java的原始类型(boolean, int 等)、原始类型对象(Boolean, Int等)、String、Date等ConversionService里可以直接String转换成目标对象的类型。也就是说没有特别需求,不推荐使用@RequestParam
  • 若要绑定的对象时复杂类型:调用@ModelAttribute来处理的。也就是说如果不需要从model或者session中得到数据,@ModelAttribute可以不使用。

@RequestMapping支持的方法参数

下面这些参数Spring在调用请求方法的时候会自动给它们赋值,所以当在请求方法中需要使用到这些对象的时候,可以直接在方法上给定一个方法参数的申明,然后在方法体里面直接用就可以了。

  1. HttpServlet 对象,主要包括HttpServletRequest 、HttpServletResponse 和HttpSession 对象。 但是有一点需要注意的是在使用HttpSession 对象的时候,如果此时HttpSession 对象还没有建立起来的话就会有问题。
  2. Spring 自己的WebRequest 对象。 使用该对象可以访问到存放在HttpServletRequest 和HttpSession 中的属性值。
  3. InputStream 、OutputStream 、Reader 和Writer 。 InputStream 和Reader 是针对HttpServletRequest 而言的,可以从里面取数据;OutputStream 和Writer 是针对HttpServletResponse 而言的,可以往里面写数据。
  4. 使用@PathVariable 、@RequestParam 、@CookieValue 和 @RequestHeader 标记的参数。
  5. 使用@ModelAttribute 标记的参数。
  6. java.util.Map 、Spring 封装的Model 和ModelMap 。 这些都可以用来封装模型数据,用来给视图做展示。
  7. 实体类。 可以用来接收上传的参数。
  8. Spring 封装的MultipartFile 。 用来接收上传文件的。
  9. Spring 封装的Errors 和BindingResult 对象。 这两个对象参数必须紧接在需要验证的实体对象参数之后,它里面包含了实体对象的验证结果。

一个参数传多个值

在浏览器输入此URLhttp://localhost:8080/admin/login.action?username=geek&password=geek&password=geek

结果得到的对象为 : Manager{username='geek', password='geek,geek'}

参考文档:

  1. @RequestParam @RequestBody @PathVariable 等参数绑定注解详解
  2. SpringMVC之Controller常用注解功能全解析
  3. @ModelAttribute使用详解

这篇关于springMVC 参数绑定的注解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1146680

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�