1. 程式人生 > >String[] 轉 HashSet 和 List + ObjectMapper類的使用實現json的正反序列化

String[] 轉 HashSet 和 List + ObjectMapper類的使用實現json的正反序列化

在做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<String, String[]> parMap = request.getParameterMap();
		for (Map.Entry<String, String[]> params : parMap.entrySet()) {
			String key = params.getKey();
			String val = params.getValue()[0];
			System.err.println("引數名:" + key + ",引數值:" + val);
		}

		// 拿到引數map後,我們就可以根據引數map構建我們需要的類例項了,實現自定義物件的反序列化
		System.err.println("=====================================");
		Map<String, Object> jsonMap = new HashMap<>();
		for (Map.Entry<String, String[]> 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依賴如下

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.appleyk</groupId>
	<artifactId>spring-boot-web</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>Java-Web</name>
	<packaging>war</packaging>
	<!-- 繼承官網最新父POM【假設當前專案不再繼承其他POM】 -->
	<!-- http://projects.spring.io/spring-boot/#quick-start -->
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version>
	</parent>
	<!-- 使用Java8,嘗試使用新特新【stream和lambda】 -->
	<properties>
		<java.version>1.8</java.version>
	</properties>
	<repositories>
		<repository>
			<id>osgeo</id>
			<name>Open Source Geospatial Foundation Repository</name>
			<url>http://download.osgeo.org/webdav/geotools/</url>
		</repository>
	</repositories>
	<!-- Starter POMs是可以包含到應用中的一個方便的依賴關係描述符集合 -->
	<!-- 該Starters包含很多你搭建專案, 快速執行所需的依賴, 並提供一致的, 管理的傳遞依賴集。 -->
	<!-- 大多數的web應用都使用spring-boot-starter-web模組進行快速搭建和執行。 -->
	<!-- spring-boot-starter-web -->
	<!-- 對全棧web開發的支援, 包括Tomcat和 spring-webmvc -->
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-core</artifactId>
		</dependency>
		<!-- Spring 單元測試 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<!-- 新增熱部署 devtools:監聽檔案變動 -->
		<!-- 當Java檔案改動時,Spring-boo會快速重新啟動 -->
		<!-- 最簡單的測試,就是隨便找一個檔案Ctrl+S一下,就可以看到效果 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<!-- optional=true,依賴不會傳遞 -->
			<!-- 本專案依賴devtools;若依賴本專案的其他專案想要使用devtools,需要重新引入 -->
			<optional>true</optional>
		</dependency>
		<!-- JUnit單元測試 -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
		</dependency>
	</dependencies>
</project>

當然,如果是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<String> * * @param strArray * @return */ public static HashSet<String> strArrayTostrSet(String[] strArray) { HashSet<String> sets = new HashSet<>(); for (String str : strArray) { sets.add(str); } return sets; } /** * String陣列轉HashSet<Long> * * @param strArray * @return */ public static HashSet<Long> strArrayTolongSet(String[] strArray) { HashSet<Long> sets = new HashSet<>(); // 先轉List<Long> -- 使用Java8特性 -- stream 配合 lamda表示式 -- 批量轉化str陣列 --> // long陣列 List<Long> list = Arrays.asList(strArray).stream().map(s -> Long.parseLong(s)).collect(Collectors.toList()); for (Long n : list) { sets.add(n); } return sets; } /** * String陣列轉HashSet<Long> * * @param strArray * @return */ public static HashSet<Integer> strArrayTointSet(String[] strArray) { HashSet<Integer> sets = new HashSet<>(); // 先轉List<Long> -- 使用Java8特性 -- stream 配合 lamda表示式 -- 批量轉化str陣列 --> long陣列 List<Integer> 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<String> likes;

	/*
	 * 喜歡球星的球衣號碼
	 */
	private HashSet<Integer> nums;

	public Mine() {
		likes = new HashSet<>();
		nums = new HashSet<>();
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public HashSet<String> getLikes() {
		return likes;
	}

	public void setLikes(HashSet<String> likes) {
		this.likes = likes;
	}

	public HashSet<Integer> getNums() {
		return nums;
	}

	public void setNums(HashSet<Integer> 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<String, Object> jsonMap = new HashMap<>();
		Long id = 1001L;
		String strlikes = "科比,詹姆斯,麥迪";
		String strnums = "24,23,1";

		/*
		 * 1. jsonMap新增第一個屬性
		 */
		jsonMap.put("id", id);

		/*
		 * 2.strlikes 轉成 對應的 Hash<String>,新增進jsonMap
		 */
		jsonMap.put("likes", JsonConventUtils.strArrayTostrSet(strlikes.split(",")));

		/*
		 * 3.strnums 轉成 對應的 Hash<Integer>,新增進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<String, String[]> parMap = request.getParameterMap();
		for (Map.Entry<String, String[]> params : parMap.entrySet()) {
			String key = params.getKey();
			String val = params.getValue()[0];
			System.err.println("引數名:" + key + ",引數值:" + val);
		}

		// 拿到引數map後,我們就可以根據引數map構建我們需要的類例項了,實現自定義物件的反序列化
		System.err.println("=====================================");
		Map<String, Object> jsonMap = new HashMap<>();
		for (Map.Entry<String, String[]> 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正反序列

在做Java Web專案對外提供API的時候,比如Spring專案中,我們通常藉助Controller來實現方法級別的Restful風格的介面的包裝,當然有方法,就得有引數,引數有兩類,一是請求的引數,

Json工具--使用1.x版本Jackson實現json序列序列

簡介:使用1.x版本(org.codehaus.jackson包下類)的Jackson實現了json的序列化和反序列化。 1.工具類程式碼: import com.fasterxml.jackson.annotation.JsonFormat; impor

實現json序列序列

之前一直用的是官網上的庫:http://www.json.org/java/index.html 個人體驗,這個庫的毛病挺多的,比如在將JSONObject轉換成String的過程中會產生大量的臨時性的String物件(因為沒用StringBuffer),更鬱悶的一個問題是,

javascript實現json序列序列功能

json的序列化和反序列化是我們常用的功能 序列化: 序列化:反序列化:eval將字串反序列化成物件 測試部分: 完整示例: 執行效果圖如下: 序列化方法:JSON.stringfy() 反序列化: 物件序列化是指將物件的狀態轉換為字串。 序列

alibaba下的fast json與字串String、陣列list的相互轉換

/**  * 實體類轉json  * JSONObject j1 = (JSONObject)JSONObject.toJSON(man1);  * json轉實體類  * Man man3 = JSONObject.parseObject(j

16、Collection介面及其子介面SetList(常用LinkedList,ArrayList,VectorStack)

16、Collection介面  Collection是最基本的集合介面,一個Collection代表一組Object,即Collection的元素(Elements)。一些Collection允許相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接繼

java將:String化為Date的工具

package com.yanshu.logback; import java.text.ParseException; import java.text.ParsePosition; import java.text.SimpleDateFormat; import ja

CCAI 2017 | 德國DFKI科技總監Hans Uszkoreit:如何用機器學習知識圖譜來實現商業智能

以下是Hans Uszkoreit的演講全文,AI科技大本營略做修改: 今天我將介紹目前人工智能的兩個主要方向,基於行為的學習和基於知識的學習;另外我會講一下商業智能以及工業4.0、開放數據與企業數據,以及開放的知識圖譜和企業知識圖譜;接著我會介紹文本分析的大數據方法、文本數據

spring+redis 實現快取 解決序列序列的問題

1.config.properties # Redis settings redis.host=127.0.0.1 redis.port=6379   #redis.pass=password redis.dbIndex=0   redis.expiration=3000 &

[Echarts視覺] 二.phpajax連線資料庫實現動態資料視覺

前一篇文章 "[Echarts視覺化] 一.入門篇之簡單繪製中國地圖和貴州地區" 主要是通過Echarts視覺化介紹入門知識、中國地圖和貴州地區各省份的資料分析,其中貴州地圖才是它的核心內容。這篇文章主要結合PHP、MySQL、JQuery和Ajax從資料庫中獲取資料,動態的

StaticFinal修飾屬性變數及初始

  1.static修飾一個屬性欄位,那麼這個屬性欄位將成為類本身的資源,public修飾為共有的,可以在類的外部通過test.a來訪問此屬性;在類內部任何地方可以使用.如果被修飾為private私有,那麼只能在類內部使用.

異常 Serializable介面無法實現 不能被序列

java.io.NotSerializableException: demo9.Student at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156) at java.io.Object

IDictionary 序列一定要實現實現了ISerializable介面的,子也必須有序列建構函式,否則反序列時會出錯。

//public class ThreadSafeDictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICloneable [Serializable] public class

Json序列ObjectMapper(自定義實現序列方法)

     對於伺服器端開發人員而言,呼叫第三方介面獲取資料,將其“代理”轉化並返給客戶端幾乎是家常便飯的事兒。    一般情況下,第三方介面返回的資料型別是json格式,而伺服器開發人員則需將json格式的資料轉換成物件,繼而對其進行處理並封裝,以返回給客戶端。  

spring+redis 實現快取 解決序列序列的問題

1.config.properties # Redis settings redis.host=127.0.0.1 redis.port=6379   #redis.pass=password redis.dbIndex=0   redis.expiration=3000

為什麼實體實現serializable介面 序列

最重要的兩個原因是:  1、將物件的狀態儲存在儲存媒體中以便可以在以後重新創建出完全相同的副本;  2、按值將物件從一個應用程式域傳送至另一個應用程式域。  實現serializable介面的作用是就是可以把物件存到位元組流,然後可以恢復。所以你想如果你的物件沒實現序列化怎

C# Json序列 數據協定型 無法反序列 由於未找到必需的數據成員

val object test 信息 span 屬性表 ble details space 背景今天在使用:C# Json 序列化與反序列化 反序列化的時候出現了以下的錯誤信息。System.Runtime.Serialization.SerializationExce

ASP.NET 中JSON序列序列

urn 序列 del nbsp parseint 代碼 href end user JSON是專門為瀏覽器中的網頁上運行的JavaScript代碼而設計的一種數據格式。在網站應用中使用JSON的場景越來越多,本文介紹ASP.NET中JSON的序列化和反序列化,主要對JSON

json/pickle- 序列序列

內部 int strong 回來 color lex 數據類型 硬盤 json json只能處理簡單的數據類型。列表,字典,字符串等。函數不行。用於不同語言之間的相互轉化。 編碼:把一個Python對象編碼轉換成Json字符串 json.dumps() 把內存的數據對象

Python學習心得(五) random生成驗證碼、MD5加密、pickle與json序列序列

用法 div com ict file imp randint csdn == # -*- coding:utf-8 -*- import random as rd #驗證碼 import hashlib as hsl #MD5加密 import pickle,json