使用Java注解和反射實(shí)現(xiàn)JSON字段自動(dòng)重命名
不知道有沒(méi)有同學(xué)遇到過(guò)對(duì)接業(yè)務(wù)方代碼非常“獨(dú)具一格”(不符合通用規(guī)范且不愿意配合修改emmmm。。。),于是就只能“被迫”按他的格式來(lái),但是又不想因?yàn)樗牟灰?guī)范導(dǎo)致我們自己創(chuàng)建的接收對(duì)象也非常的“一言難盡”。。。今天這篇幫你解決這個(gè)問(wèn)題~(老規(guī)矩:附完整可執(zhí)行代碼)
先給初學(xué)Java的同學(xué)補(bǔ)下基礎(chǔ),涉及到一些實(shí)現(xiàn)這個(gè)功能需要的知識(shí)點(diǎn)(了解的朋友可以直接跳過(guò)~)
Java注解(Annotation)
Java注解(Annotation)是一種特殊的標(biāo)記,用于在Java代碼中提供元數(shù)據(jù)(Metadata)。
而元數(shù)據(jù)是描述數(shù)據(jù)的數(shù)據(jù),而在Java中,注解可以提供關(guān)于類(lèi)、方法、變量、參數(shù)、包等的附加信息。
類(lèi)似這樣~
注解不會(huì)直接影響代碼的執(zhí)行,但它們可以被編譯器或運(yùn)行時(shí)環(huán)境用來(lái)實(shí)現(xiàn)特定的處理或行為(這也是我們這篇文章用到他的原因)。
Java的反射(Reflection)
Java的反射(Reflection)是一種灰常~強(qiáng)大的機(jī)制,它允許程序在運(yùn)行時(shí)(Runtime)查詢(xún)、訪問(wèn)和修改它自身的結(jié)構(gòu)和行為(反射提供了一種動(dòng)態(tài)的訪問(wèn)和操作類(lèi)、接口、方法、構(gòu)造函數(shù)、字段等的能力,所以可以在對(duì)象未知的情況下對(duì)對(duì)象進(jìn)行操作)
org.json
org.json是一個(gè)在Java中用于處理JSON數(shù)據(jù)的庫(kù)(Java自帶的,類(lèi)似Gson或JSON-B),它提供了一系列的API來(lái)創(chuàng)建、解析和操作JSON對(duì)象,需要添加如下依賴(lài):
<dependency> <groupId>com.vaadin.external.google</groupId> <artifactId>android-json</artifactId> <version>0.0.20131108.vaadin1</version> <scope>compile</scope> </dependency>
@Target 注解
Java中的@Target
注解是一個(gè)元注解(meta-annotation),它用于指定其他注解可以應(yīng)用于哪些Java元素。@Target
本身不能直接用在除了注解定義之外的地方。使用@Target
可以提高注解的可用性和準(zhǔn)確性,確保注解被用在合適的上下文中。
好啦~用到的東西基本就是這些,正文開(kāi)始!>>>>>>>
處理步驟
- 定義注解:創(chuàng)建一個(gè)注解
@AutoRename
,用于標(biāo)記需要自動(dòng)重命名屬性的類(lèi)。
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) // 用于類(lèi) @Retention(RetentionPolicy.RUNTIME) // 運(yùn)行時(shí)保留 public @interface AutoRename { }
- 編寫(xiě)JSON轉(zhuǎn)換工具:實(shí)現(xiàn)一個(gè)工具類(lèi),用于處理JSON字符串,并根據(jù)注解自動(dòng)重命名屬性。
附完整代碼:
import org.json.JSONObject; import java.lang.reflect.Field; import java.util.Iterator; public class JsonAutoRenamer { public static <T> T fromJson(String json, Class<T> clazz) throws Exception { JSONObject jsonObject = new JSONObject(json); T instance = clazz.getDeclaredConstructor().newInstance(); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); String key = field.getName(); // 獲取駝峰式命名 String dataKey = key.replaceAll("([a-z0-9])([A-Z])", "$1_$2").toLowerCase(); // 轉(zhuǎn)換為下劃線分隔 Object value = jsonObject.has(dataKey) ? jsonObject.get(dataKey) : null; if (value != null) { // 根據(jù)字段類(lèi)型轉(zhuǎn)換值 Class<?> fieldType = field.getType(); if (fieldType == String.class) { field.set(instance, value.toString()); } else if (fieldType == int.class || fieldType == Integer.class) { field.set(instance, (Integer) value); } else if (fieldType == boolean.class || fieldType == Boolean.class) { field.set(instance, (Boolean) value); } else if (fieldType == double.class || fieldType == Double.class) { field.set(instance, (Double) value); } // ...其他類(lèi)型處理(如果有的話) } } return instance; } }
使用注解:將注解添加到你的數(shù)據(jù)對(duì)象類(lèi)上。
@AutoRename public class UserResponse { private String userName ; private Integer age ; public UserResponse() { } public UserResponse(String userName , Integer age) { this.userName = userName ; this.age = age ; } public String getUserName() { return userName ; } public void setUserName(String userName) { this.userName = userName ; } public Integer getAge() { return age ; } public void setAge(Integer age) { this.age = age ; } }
處理JSON字符串:在獲取接口返回的JSON字符串后,使用
JsonAutoRenamer
來(lái)處理字符串。
public class Main { public static void main(String[] args) { String json = "{"user_name":"John Doe","age":30}"; try { UserResponse userResponse = JsonAutoRenamer.fromJson(json, UserResponse.class); // 現(xiàn)在 userResponse 中的字段已經(jīng)被賦值 System.out.println("User Name: " + userResponse.getUserName()); System.out.println("Age: " + userResponse.getAge()); } catch (Exception e) { e.printStackTrace(); } } }
請(qǐng)注意,這個(gè)示例使用了Java自帶的org.json.JSONObject
來(lái)解析JSON字符串。JsonAutoRenamer
類(lèi)中的fromJson
方法會(huì)遍歷JSON對(duì)象中的每個(gè)鍵值對(duì),并使用反射來(lái)找到Java對(duì)象中對(duì)應(yīng)的字段,然后根據(jù)字段類(lèi)型將JSON值賦給Java字段。
我們看下執(zhí)行結(jié)果:
以上就是使用Java注解和反射實(shí)現(xiàn)JSON字段自動(dòng)重命名的詳細(xì)內(nèi)容,更多關(guān)于Java JSON字段重命名的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
TransmittableThreadLocal解決線程間上下文傳遞煩惱
這篇文章主要為大家介紹了TransmittableThreadLocal解決線程間上下文傳遞煩惱詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11MybatisPlus多表連接查詢(xún)的具體實(shí)現(xiàn)
MyBatis Plus是一款針對(duì)MyBatis框架的增強(qiáng)工具, 它提供了很多方便的方法來(lái)實(shí)現(xiàn)多表聯(lián)查,本文主要介紹了MybatisPlus多表連接查詢(xún)的具體實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2023-10-10Java調(diào)用DOS實(shí)現(xiàn)定時(shí)關(guān)機(jī)的實(shí)例
Java調(diào)用DOS實(shí)現(xiàn)定時(shí)關(guān)機(jī)的實(shí)例,需要的朋友可以參考一下2013-04-04Java數(shù)據(jù)結(jié)構(gòu)之順序表詳解
這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)之順序表詳解,線性表在邏輯上是線性結(jié)構(gòu),也就說(shuō)是連續(xù)的一條直線。但是在物理結(jié)構(gòu)上并不一定是連續(xù)的,線性表在物理上存儲(chǔ)時(shí),通常以數(shù)組和鏈?zhǔn)浇Y(jié)構(gòu)的形式存儲(chǔ),需要的朋友可以參考下2023-07-07MyBatis-Plus自定義SQL的詳細(xì)過(guò)程記錄
Java開(kāi)發(fā)使用mybatis-plus來(lái)執(zhí)行sql操作,往往比mybatis能夠省時(shí)省力,下面這篇文章主要給大家介紹了關(guān)于MyBatis-Plus自定義SQL的相關(guān)資料,需要的朋友可以參考下2022-02-02Java實(shí)現(xiàn)一個(gè)簡(jiǎn)單計(jì)算器
這篇文章主要介紹了Java實(shí)現(xiàn)一個(gè)簡(jiǎn)單計(jì)算器,文章我圍繞實(shí)現(xiàn)簡(jiǎn)單計(jì)算器的相關(guān)代碼展現(xiàn)全文,具有一定的參考價(jià)值,需要的小伙伴可以參考一下,2022-01-01簡(jiǎn)單的理解java集合中的HashSet和HashTree幾個(gè)重寫(xiě)方法
這篇文章主要介紹了簡(jiǎn)單的理解java集合中的HashSet和HashTree幾個(gè)重寫(xiě)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10Druid監(jiān)控分布式實(shí)現(xiàn)過(guò)程解析
這篇文章主要介紹了Druid監(jiān)控分布式實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11