在做Java Web项目对外提供API的时候,比如Spring项目中,我们通常借助Controller来实现方法级别的Restful风格的接口的包装,当然有方法,就得有参数,参数有两类,一是请求的参数,一是返回的参数
请求的参数我们可以显示的声明出来,比如我们需要前端在查询的时候,传过来一个符合Mine对象格式的JSON串,我们可以定义方法如下
演示查询效果如下:
请求的参数我们也可以不声明出来,比如我们只规定前端发过来一个请求就行,关于请求的内容,我们在方法里面进行校验,如果通过了我们就反序列化为对象,方法如下
@GetMapping("/query1")
public ResponseResult Query1(HttpServletRequest request) {
/**
* 公共接口类HttpServletRequest继承自ServletRequest.
* 客户端浏览器发出的请求被封装成为一个HttpServletRequest对象。
* 所有的信息包括请求的地址,请求的参数,提交的数据,上传的文件客户端的ip甚至客户端操作系统都包含在其内。
* HttpServletResponse继承了ServletResponse接口,并提供了与Http协议有关的方法,
* 这些方法的主要功能是设置HTTP状态码和管理Cookie。
*
* 拿到reques对象中请求的参数map集合,利用自定义的Json转换工具,实现参数反序列化成对象
*/
Map parMap = request.getParameterMap();
for (Map.Entry params : parMap.entrySet()) {
String key = params.getKey();
String val = params.getValue()[0];
System.err.println("参数名:" + key + ",参数值:" + val);
}
// 拿到参数map后,我们就可以根据参数map构建我们需要的类实例了,实现自定义对象的反序列化
System.err.println("=====================================");
Map jsonMap = new HashMap<>();
for (Map.Entry params : parMap.entrySet()) {
String key = params.getKey();
String val = params.getValue()[0];
String[] valArray = val.split(",");
if (key.equals("likes")) {
jsonMap.put(key, JsonConventUtils.strArrayTostrSet(valArray));
} else if (key.equals("nums")) {
jsonMap.put(key, JsonConventUtils.strArrayTointSet(valArray));
} else {
jsonMap.put(key, val);
}
}
String json = JsonConventUtils.mapTojson(jsonMap);
Mine mine = (Mine) JsonConventUtils.jsonToobject(json, Mine.class);
ResponseResult result = new ResponseResult(new ResultData<>(ResponseMessage.OK, mine));
return result;
}
演示查询的效果如下(和上面的请求参数一样,不一样的是URI):
后台输出request对象中的参数map集合信息如下
如何做到的呢?
一、Spring-Boot -- Pom依赖如下
4.0.0
com.appleyk
spring-boot-web
0.0.1-SNAPSHOT
Java-Web
war
org.springframework.boot
spring-boot-starter-parent
1.5.9.RELEASE
1.8
osgeo
Open Source Geospatial Foundation Repository
http://download.osgeo.org/webdav/geotools/
org.springframework.boot
spring-boot-starter-web
com.fasterxml.jackson.core
jackson-core
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-devtools
true
junit
junit
当然,如果是Spring项目的话,只需要添加如下依赖
二、Json转换工具类
JsonConventUtils.java
import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* Json转换工具类
* @author [email protected]
* @blob http://blog.csdn.net/appleyk
* @date 2018年3月29日-下午1:34:53
*/
public class JsonConventUtils {
/**
* JSON序列化工具
* ObjectMapper类是Jackson库的主要类。
* 它提供一些功能将转换成Java对象匹配JSON结构,反之亦然。
* 它使用JsonParser和JsonGenerator的实例实现JSON实际的读/写
*/
static ObjectMapper mapper = new ObjectMapper();
/**
* String数组转HashSet
*
* @param strArray
* @return
*/
public static HashSet strArrayTostrSet(String[] strArray) {
HashSet sets = new HashSet<>();
for (String str : strArray) {
sets.add(str);
}
return sets;
}
/**
* String数组转HashSet
*
* @param strArray
* @return
*/
public static HashSet strArrayTolongSet(String[] strArray) {
HashSet sets = new HashSet<>();
// 先转List -- 使用Java8特性 -- stream 配合 lamda表达式 -- 批量转化str数组 -->
// long数组
List list = Arrays.asList(strArray).stream().map(s -> Long.parseLong(s)).collect(Collectors.toList());
for (Long n : list) {
sets.add(n);
}
return sets;
}
/**
* String数组转HashSet
*
* @param strArray
* @return
*/
public static HashSet strArrayTointSet(String[] strArray) {
HashSet sets = new HashSet<>();
// 先转List -- 使用Java8特性 -- stream 配合 lamda表达式 -- 批量转化str数组 --> long数组
List list = Arrays.asList(strArray).stream().map(s -> Integer.parseInt(s))
.collect(Collectors.toList());
for (Integer n : list) {
sets.add(n);
}
return sets;
}
/**
* map 转 json字符串
* @return
*/
public static String mapTojson(Map, ?> map){
try {
return mapper.writeValueAsString(map);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
/**
* json字符串 转换 Java 对象
* @param json
* @param clazz
* @return
*/
public static Object jsonToobject(String json,Class clazz){
try {
Object object = mapper.readValue(json, clazz);
return object;
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 下面还可以自行添加其他序列化方法,省略.................
*/
}
三、本篇用到的pojo类Mine
Mine.java(实现序列化)
import java.io.Serializable;
import java.util.HashSet;
public class Mine implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
/*
* 用户ID
*/
private Long id;
/*
* 喜欢的球星
*/
private HashSet likes;
/*
* 喜欢球星的球衣号码
*/
private HashSet nums;
public Mine() {
likes = new HashSet<>();
nums = new HashSet<>();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public HashSet getLikes() {
return likes;
}
public void setLikes(HashSet likes) {
this.likes = likes;
}
public HashSet getNums() {
return nums;
}
public void setNums(HashSet nums) {
this.nums = nums;
}
@Override
public String toString(){
return "用户ID: "+id+",喜欢的球星有: "+likes+",球星的球衣号码有: "+nums;
}
}
四、Json转换工具单元测试一把
(1)
(2)
JsonConventTest.java
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import com.appleyk.pojo.Mine;
import com.appleyk.utils.JsonConventUtils;
/**
* Json转换根据测试
* @author [email protected]
* @blob http://blog.csdn.net/appleyk
* @date 2018年3月29日-下午1:49:24
*/
public class JsonConventTest {
@Test
public void Test() {
Map jsonMap = new HashMap<>();
Long id = 1001L;
String strlikes = "科比,詹姆斯,麦迪";
String strnums = "24,23,1";
/*
* 1. jsonMap添加第一个属性
*/
jsonMap.put("id", id);
/*
* 2.strlikes 转成 对应的 Hash,添加进jsonMap
*/
jsonMap.put("likes", JsonConventUtils.strArrayTostrSet(strlikes.split(",")));
/*
* 3.strnums 转成 对应的 Hash,添加进jsonMap
*/
jsonMap.put("nums", JsonConventUtils.strArrayTointSet(strnums.split(",")));
// map 转 json 串
String json = JsonConventUtils.mapTojson(jsonMap);
System.out.println(json);
System.out.println("上为map转成json字符串=======================下为json串序列化为对象");
// 反序列化Json串 --> User对象
Mine mine = (Mine) JsonConventUtils.jsonToobject(json, Mine.class);
System.out.println(mine);
}
}
(3)运行测试方法
五、Controller层完整代码
TestController.java
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.appleyk.pojo.Mine;
import com.appleyk.result.ResponseMessage;
import com.appleyk.result.ResponseResult;
import com.appleyk.result.ResultData;
import com.appleyk.utils.JsonConventUtils;
/**
*
* @author [email protected]
* @blob http://blog.csdn.net/appleyk
* @date 2018年3月29日-下午1:26:39
*/
@RestController // same as @Controller + @ResponseBody
@RequestMapping("/rest/v1.0.1/appleyk/test") // restful风格的api接口
public class TestController {
@GetMapping("/query1")
public ResponseResult Query1(HttpServletRequest request) {
/**
* 公共接口类HttpServletRequest继承自ServletRequest.
* 客户端浏览器发出的请求被封装成为一个HttpServletRequest对象。
* 所有的信息包括请求的地址,请求的参数,提交的数据,上传的文件客户端的ip甚至客户端操作系统都包含在其内。
* HttpServletResponse继承了ServletResponse接口,并提供了与Http协议有关的方法,
* 这些方法的主要功能是设置HTTP状态码和管理Cookie。
*
* 拿到reques对象中请求的参数map集合,利用自定义的Json转换工具,实现参数反序列化成对象
*/
Map parMap = request.getParameterMap();
for (Map.Entry params : parMap.entrySet()) {
String key = params.getKey();
String val = params.getValue()[0];
System.err.println("参数名:" + key + ",参数值:" + val);
}
// 拿到参数map后,我们就可以根据参数map构建我们需要的类实例了,实现自定义对象的反序列化
System.err.println("=====================================");
Map jsonMap = new HashMap<>();
for (Map.Entry params : parMap.entrySet()) {
String key = params.getKey();
String val = params.getValue()[0];
String[] valArray = val.split(",");
if (key.equals("likes")) {
jsonMap.put(key, JsonConventUtils.strArrayTostrSet(valArray));
} else if (key.equals("nums")) {
jsonMap.put(key, JsonConventUtils.strArrayTointSet(valArray));
} else {
jsonMap.put(key, val);
}
}
String json = JsonConventUtils.mapTojson(jsonMap);
Mine mine = (Mine) JsonConventUtils.jsonToobject(json, Mine.class);
ResponseResult result = new ResponseResult(new ResultData<>(ResponseMessage.OK, mine));
return result;
}
/**
* 不暴露HttpServletRequest,直接挂上Mine,由servlet自行匹配参数的类型并进行对象的反序列化
* @param mine
* @return
*/
@GetMapping("/query2")
public ResponseResult Query2(Mine mine) {
ResponseResult result = new ResponseResult(new ResultData<>(ResponseMessage.OK, mine));
return result;
}
}
完整测试控制台效果展示如下: