在所有的 Web 类应用中,参数的绑定都是一个非常重要的话题,本章中,就来看看 Jersey 中的参数绑定方式。
绑定路径参数
在 Jersey 中,使用 @PathParam 完成路径参数绑定:
package com.example.jerseydemo.parameterbinding;import javax.ws.rs.GET;import javax.ws.rs.Path;import javax.ws.rs.PathParam;import javax.ws.rs.Produces;import javax.ws.rs.core.MediaType;@Path("/pathparam") // 基路径@Produces(value = MediaType.APPLICATION_JSON)public class TestService {/*** 映射 url中的路径参数* @param id* @return*/@GET@Path("/test1/{id}")public String testPathParam(@PathParam("id") String id){return id;}/*** 映射多个路径参数* @param key* @param value* @return*/@GET@Path("/test2/{key}/{value}")public String testPathParam2(@PathParam("key") String key, @PathParam("value") String value){return key+":"+value;}}
映射普通请求参数
在实际开发中,类似对资源的查询等操作,需要通过获取请求中的查询参数内容。Jersey 提供了 @QueryParam 注解完成参数绑定。
package com.example.jerseydemo.parameterbinding;import javax.ws.rs.GET;import javax.ws.rs.Path;import javax.ws.rs.QueryParam;/*** @author hanliukui* @Date 2021/4/3 14:43*/@Path("/queryparam")public class QueryParamService {/*** 映射 普通参数传参* @param param1* @param param2* @return*/@GET@Path("/test1")public String queryParam1(@QueryParam("aa") String param1,@QueryParam("bb") String param2 ){return "param1:"+param1+",param2:"+param2;}}

映射表单提交参数
使用表单提交是互联网应用再常见不过的方式,在 SpringMVC 中,提供了各种牛逼的能力来把表单中的数据映射到方法的参数,模型中,但是在这块上,Jersey 同样很强大,但是稍微使用复杂一点。要演示表单提交参数绑定,我们先创建一个简单的 Employee 类:
@Setter@Getter@NoArgsConstructor@AllArgsConstructorpublic class Employee {private Long id;private String name;private int age;}
需求:根据提交的数据创建一个 Employee 对象。
/*** 映射表单提交参数,要求请求是POST,PUT,并且编码格式必须是x-www-form-urlencoded** @param name* @param age* @return*/@PUT@Path("/form")@Produces(MediaType.APPLICATION_JSON)public Employee formParam(@FormParam("name") String name, @FormParam("age") int age) {return new Employee(1L, name, age);}
普通值绑定
第一种方式,在 Jersey 中,提供了一个 @FormParam 注解来完成表单中内容到参数的绑定(API 文档解释,是绑定一个请求实体中的表单参数到资源方法参数 Binds the value(s) of a form parameter contained within a request entity body to a resource method parameter)。
注意几个点:
1、@FormParam 注解只能接受 x-www-form-urlencoded 编码格式的 form 表单提交,这个是必要条件;
2、@FormParam 注解能够完成的绑定类型有:
- 简单类型;
绑定到一个对象,要求这个对象的类有一个接受单个 String 类型的构造器;
class Employee {private Long id;private String name;private int age;public Employee() {}// 单个 String 类型的构造器public Employee(String name) {this.name = name;}...}
绑定到一个对象,要求这个对象的类有一个 valueOf(String) 或者 fromString(String) 的静态的构建方法,比如
public static Employee valueOf(String name){return new Employee(name);}
提供一个 ParamConverterProvider(这个后面讲 Provider);
- 可以绑定到一个 List,Set 上面,例如:
@POST@Path("/hobby")@Produces(MediaType.APPLICATION_JSON)public Employee formParam(@FormParam("hobby") Set<String> hobbies) {System.out.println(hobbies);return new Employee();}
那么,使用 POST param/hobby?hobby=java&hobby=haha&hobby=hehe 就可以完成 Set 的绑定(注意表单编码格式一定是 x-www-form-urlencoded)。
另外,@FormParam 可以配合一个 @DefaultValue 标签来设置默认值,简单演示:
@PUT@Path("/form")@Produces(MediaType.APPLICATION_JSON)public Employee formParam(@FormParam("name") String name,@DefaultValue("18") @FormParam("age") int age) {return new Employee(1L, name, age);}
当 @FormParam 绑定失败即可使用 @DefaultValue 设置的值。
绑定到对象
在 SpringMVC 中,我们更常见的是直接把请求参数绑定到一个我们需要的模型或者 VO 中。在 Jersey 中,使用 @FormParam 注解无法完成,可以使用 @BeanParam 和 @FormParam 配合使用:
首先修改 Employee 对象:
@Setter@Getter@NoArgsConstructor@AllArgsConstructorpublic class Employee {private Long id;@FormParam("name")private String name;@FormParam("age")private int age;}
注意,我们把 @FormParam 标签移动到了 Employee 的对应属性上。当然在实际开发中,更多应该是在 VO 对象类中;
/*** 直接映射到模型,要求请求是POST,PUT,并且编码格式必须是x-www-form-urlencoded** @param e* @return*/@POST@Path("/formpojo")@Produces(MediaType.APPLICATION_JSON)public Employee formPojoParam(@BeanParam Employee e) {e.setId(2L);return e;}
然后,再使用 Jersey 提供了 @BeanParam 注解,完成请求参数到自定义模型的绑定。
注意,在自定义模型中,不光可以使用 @FormParam ,可以使用 @XXXParam ,比如前面提到过的 @PathParam 。
直接获取表单内容
前面介绍过使用 @FormParam 和 @BeanParam 来获取表单中的数据,下面再介绍一种通过直接获取表单内容的方式:
/*** 使用MultivaluedMap直接获取POST表单编码格式必须是x-www-form-urlencoded的表单内容** @param fs* @return*/@POST@Path("/formui2")public String formPojoParam(MultivaluedMap<String, String> fs) {System.out.println(fs);return "success";}
那么获取到的 MultivaluedMap 类型中,就包含了表单里面所有的参数内容。
映射请求头参数
从请求头中获取一些参数,比如请求头中自定义的 token 等信息,可以直接使用 Jersey 提供的 @HeaderParam 注解完成:
/*** 通过@HeaderParam获取请求头内容*/@GET@Path("/head")public String headParam(@HeaderParam("token") String token) {System.out.println(token);return "success";}
那么在请求的时候,我们可以在头信息中添加:
就可以正常看到后台把 token 绑定到 token 参数中。需要注意的是, @DefaultValue 标签都是可以和这些 @XXXParam 配合使用的,并且也可以添加到需要绑定的模型属性上的。
绑定矩阵参数
矩阵参数听着很奇怪,其实很简单,比如我们在做分页的时候,可以使用类似这样的请求:/resource;pageSize=10;currentPage=2
注意,这个请求并不是普通的参数提交方式,按照普通的方式,应该是:/resource?pageSize=10&tPage=2
注意查看两者的区别。
那么使用矩阵参数有什么好处呢?在 REST 架构中,矩阵参数可以把这些参数一起看做一个资源,意思就是上面的两个连接中,第一个 URI 可以看做第二页,每页 10 条 resource 资源,把这个整体作为一个资源去看待;又比如这样一个资源:/players/ladder;level=king
就可以看成天梯中等级为王者的玩家,把这个概念直接作为一个资源整体看待。
理解了矩阵参数,Jersey 提供了 @MatrixParam 标签来完成矩阵参数的绑定:
/*** 从请求路径中分离出key=value的值** @param currentPage* @param pageSize* @param keyword* @return*/@GET@Path("/matrix")public String matrix(@MatrixParam("currentPage") int currentPage, @MatrixParam("pageSize") int pageSize,@MatrixParam("keyword") String keyword) {System.out.println("currentPage:" + currentPage);System.out.println("pageSize:" + pageSize);System.out.println("keyword:" + keyword);return "success";}
那么,当我们做出请求

就可以正确的分别解析出其中的 pageSize,currentPage 和 keyword 参数。但是需要注意一点,Jersey 只能解析出处于最后一个路径中的矩阵参数。
至此,Jersey 提供的最基本的几种请求参数绑定方式介绍完毕,下一结介绍 @Context 注解的使用。

