String[] 转 HashSet 和 List + ObjectMapper类的使用实现json的正反序列化

在做Java Web项目对外提供API的时候,比如Spring项目中,我们通常借助Controller来实现方法级别的Restful风格的接口的包装,当然有方法,就得有参数,参数有两类,一是请求的参数,一是返回的参数


请求的参数我们可以显示的声明出来,比如我们需要前端在查询的时候,传过来一个符合Mine对象格式的JSON串,我们可以定义方法如下


String[] 转 HashSet 和 List + ObjectMapper类的使用实现json的正反序列化_第1张图片


演示查询效果如下:


String[] 转 HashSet 和 List + ObjectMapper类的使用实现json的正反序列化_第2张图片



请求的参数我们也可以不声明出来,比如我们只规定前端发过来一个请求就行,关于请求的内容,我们在方法里面进行校验,如果通过了我们就反序列化为对象,方法如下


	@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;
	}


String[] 转 HashSet 和 List + ObjectMapper类的使用实现json的正反序列化_第3张图片



演示查询的效果如下(和上面的请求参数一样,不一样的是URI):


String[] 转 HashSet 和 List + ObjectMapper类的使用实现json的正反序列化_第4张图片


后台输出request对象中的参数map集合信息如下


String[] 转 HashSet 和 List + ObjectMapper类的使用实现json的正反序列化_第5张图片



如何做到的呢?



一、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项目的话,只需要添加如下依赖


String[] 转 HashSet 和 List + ObjectMapper类的使用实现json的正反序列化_第6张图片




二、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)



String[] 转 HashSet 和 List + ObjectMapper类的使用实现json的正反序列化_第7张图片




(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)运行测试方法

String[] 转 HashSet 和 List + ObjectMapper类的使用实现json的正反序列化_第8张图片

五、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;
	}

}



完整测试控制台效果展示如下:



String[] 转 HashSet 和 List + ObjectMapper类的使用实现json的正反序列化_第9张图片



你可能感兴趣的:(Java,Web,Java,Spring-Boot)