本文预计需要10分钟阅读
专题简介
SpringBoot之路专题是一个记录本人在使用Spring和SpringBoot相关技术中所遇到的问题和要解决的问题。每用到一处知识点,就会把这处知识补充到Github一个对应的分支上。会以专题的方式,力争每一篇博客,由浅入深,把每个知识点讲解到实战级别,并且分析Spring源码。整个项目会以一个开发一个博客系统为最终目标,每一个分支都记录着一步一步搭建的过程。与大家分享,代码会同步发布到这里。
本节简介
在上一节http://www.jianshu.com/p/ecf712f4399f 介绍了基础的参数绑定使用方式。本节将介绍进阶的一些知识点,包括具体的@RequestParam
参数设置和自定义参数绑定支持。
package com.beenoisy.springboot.way.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController// 1
@RequestMapping(value = "article") // 2
public class ArticleController {
@RequestMapping(method = RequestMethod.GET) // 3
public Map<String, String> getArticle(
@RequestParam("id") int id// 4
) {
Map<String, String> result = new HashMap<>(); // 5
result.put("title", "this is article of id " + id); // 5
result.put("content", "this is article of id " + id); // 5
return result;
}
}
上一节的代码中,4
这一步对参数int id
加上了@RequestParam("id")
注解,使其可以对url中名为id的query进行映射。@RequestParam
还提供了更多的参数可供选择,其完整的参数签名如下:
@RequestParam(
value = "id", // 1
required = true, // 2
defaultValue = "0", // 3
name = "id" // 4
) int id
- 要绑定的请求参数名
- 是否必选
- 默认值(
required
为false
时生效) -
value
的别名,含义和value
一致
自定义参数绑定
讲一个具体的场景,比如,我们需要分页获取一个数据,每次都需要传pageNo和pageSize两个参数,某种程度上来讲,是一种浪费。可否自己定义一个参数解析器,对page
类型的参数进行解析呢?
需要自己定义一个convert并将其加入到spring容器中。
首先,实现pager源码:
package com.beenoisy.springboot.way.common.config.converter;
public class Pager {
private int pageNo;
private int pageSize;
public Pager(int pageNo, int pageSize) {
this.pageNo = pageNo;
this.pageSize = pageSize;
}
public int getPageNo() {
return pageNo;
}
public int getPageSize() {
return pageSize;
}
@Override
public String toString() {
return "Pager{" +
"pageNo=" + pageNo +
", pageSize=" + pageSize +
'}';
}
}
可以看出,pager只是一个普通java类(pojo),并没有什么特殊的设置。
下面来看convert代码:
package com.beenoisy.springboot.way.common.config.converter;
import org.springframework.core.convert.converter.Converter;
/**
* pager object, format as :"pageNo,pageSize"
* Created by jacks808@163.com on 16/9/15.
*/
public class PagerConverter implements Converter<String, Pager> {// 1
public static final int PAGE_SIZE = 20;
@Override
public Pager convert(String s) {
// 没有给正确的参数则取第一页
if (s == null || s.length() == 0) {
return new Pager(0, PAGE_SIZE);
}
String[] pagerSplit = s.split(",");
if (pagerSplit.length != 2) {
throw new IllegalStateException("can't parse '" + s + "' to pager, please input pager as pageNo,pageSize");
}
try {
int pageNo = Integer.parseInt(pagerSplit[0]);
int pageSize = Integer.parseInt(pagerSplit[1]);
return new Pager(pageNo, pageSize); // 2
} catch (NumberFormatException e) {
throw new IllegalStateException("can't parse '" + s + "' to pager, please input pager as pageNo,pageSize");
}
}
}
- 实现converter接口,这个接口包含了convert方法。Converter的参数签名中,有两个泛型参数,<FROM, TO>第一个参数是原参数,通常均为String,第二个参数就是目标参数类型,这里为Pager
- 进行一些参数处理后,返回pager对象。
配置类:
package com.beenoisy.springboot.way.common.config.converter;
import com.beenoisy.springboot.way.common.config.converter.support.PagerConverter;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* Created by jacks808@163.com on 16/9/15.
*/
@Configuration
public class ConvertConfig extends WebMvcConfigurerAdapter {
@Override
public void addFormatters(FormatterRegistry registry) {// 1
registry.addConverter(new PagerConverter());// 2
}
}
- 覆盖
addFormatters
方法 - 将自己实现的convert加入到registry中。
Controller使用时的代码:
package com.beenoisy.springboot.way.controller;
import com.beenoisy.springboot.way.common.config.converter.support.Pager;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value = "article")
public class ArticleController {
@RequestMapping(method = RequestMethod.GET)
public String getArticles(
@RequestParam("pager") Pager pager// 1
) {
int pageNo = pager.getPageNo();
int pageSize = pager.getPageSize();
return "pageNo is: " + pageNo + ", pageSize is: " + pageSize;
}
}
- 直接使用pager对象作为参数,这时springmvc\spring boot会自动调用已经加在配置里的pagerConverter进行参数绑定。
运行截图
这了pager
参数为1,5
按照解析规则,会把1
解析为page No,5
解析为page size。
最后,源码放在这里:
https://github.com/jacks808/spring-boot-way/tree/08-customer-param-binding
如果文章内容对你有帮助,欢迎在github上star或点赞。