JSon 데이터 의 중복 참조 / 반복 참조 ($ref)
9358 단어 수필
인용 하 다.
묘사 하 다.
"$ref":".."
상급
"$ref":"@"
현재 대상
"$ref":"$"
루트 개체
"$ref":"$.children.0"
경로 기반 참조, root. getChildren (). get (0) 에 해당 합 니 다.
1. 무엇이 JSon 의 중복 인용 과 순환 인용 입 니까?
아래 코드 에서 우 리 는 같은 대상 을 한 집합 에 두 번 추가 한 다음 에 FastJSon 을 사용 하여 집합 을 JSon 문자열 로 변환 합 니 다.저희 가 기대 한 결 과 는 아마... [{"name": "test"}, {"name": "test"} 를 얻 었 습 니 다. [{"name": "test"}, {"$ref": "$[0]"}]. 백 엔 드 언어 에 서 는 정상적으로 해석 할 수 있 지만 앞 뒤 데이터 의 상호작용 과 관련 될 때 전단 언어 는 정확하게 해석 할 수 없 으 며 중복 인용 을 취소 해 야 합 니 다. 변환 할 때 인용 검 사 를 닫 을 수 있 습 니 다.
[{"name": "test"}, {"$ref": "$[0]"}: 현재 집합 한 두 번 째 요 소 는 첫 번 째 요소 와 같 음 을 나타 내 며 첫 번 째 요 소 를 참조 합 니 다.
$ref: 현재 요 소 는 다른 요 소 를 참조 합 니 다 $[0]: 현재 집합 한 0 번 요소 참조
//
@Test
public void test1() {
//
ArrayList ones = new ArrayList<>();
//
One one = new One();
one.setName("test");
//
ones.add(one);
ones.add(one);
// FastJson Json
String json = JSON.toJSONString(ones);
System.out.println(json); // Json :[{"name":"test"},{"$ref":"$[0]"}]
}
//
@Test
public void test1() {
//
ArrayList ones = new ArrayList<>();
//
One one = new One();
one.setName("test");
//
ones.add(one);
ones.add(one);
// FastJson Json
String json = JSON.toJSONString(ones, SerializerFeature.DisableCircularReferenceDetect);
System.out.println(json); // Json :[{"name":"test"},{"name":"test"}]
}
순환 인용 은 실제 개발 에서 사 용 될 수 있 습 니 다. 예 를 들 어 캐릭터 기반 접근 제어 에서 사용자, 역할, 권한 등 세 가지 간 의 다 중 대응 관계 와 관련 될 수 있 습 니 다. 이때 실체 류 를 사용 하여 세 가지 간 의 대응 관 계 를 구축 할 때 순환 인용 을 사용 합 니 다. 한 사용 자 는 여러 개의 역할 을 가 질 수 있 고 한 캐릭터 는 여러 사용자 에 게 둘러싸 일 수 있 습 니 다.한 캐릭터 도 여러 가지 권한 을 가 질 수 있 고 한 가지 권한 도 여러 캐릭터 에 의 해 가 질 수 있다.
//
@Test
public void test3() {
Map map1 = new HashMap();
map1.put("test1", "Map1 ");
Map map2 = new HashMap();
map2.put("test2", "Map2 ");
//
map1.put("Map1 Map2", map2);
map2.put("Map2 Map1", map1);
// FastJson Json
String json = JSON.toJSONString(map1);
// {" map2":{"map2":"test2"," map1":{"$ref":".."}},"map1":"test1"}
System.out.println(json);
}
//
@Test
public void test4() {
Map map1 = new HashMap<>();
map1.put("map1", "test1");
Map map2 = new HashMap<>();
map2.put("map2", "test2");
//
map1.put(" map2", map2);
map2.put(" map1", map1);
// SerializerFeature: ;DisableCircularReferenceDetect:
String json = JSON.toJSONString(map1,SerializerFeature.DisableCircularReferenceDetect);
// java.lang.StackOverflowError
System.out.println(json);
}
2. JSon 의 중복 인용 과 순환 인용 문 제 를 어떻게 해결 합 니까?
데 이 터 를 제 이 슨 데이터 로 변환 할 때 는 반복 적 으로 인 용 된 검 측 을 닫 아 제 이 슨 데이터 의 인용 기 호 를 제거 하고 실제 대상 데 이 터 를 사용 하여 표시 할 수 있 습 니 다. 그러나 순환 적 인 인용 을 만 났 을 때 계속 인용 이 순환 에 들 어가 면 순서 가 무 너 져 스 택 메모리 가 넘 치 는 오류 가 발생 할 수 있 습 니 다.
따라서 FastJSon 의 순환 참 조 는 일반적인 상황 에서 기본 적 인 열 림 검사 상 태 를 유지 해 야 하기 때 문 입 니 다. 순환 참조 와 관련 이 있 으 면 분리 해서 저장 합 니 다.
다음은 캐릭터 기반 접근 제어 종 사용자 와 캐릭터 실체 류 간 의 대응 관 계 를 사용 하여 인용 문제 의 해결 (간단 한 대응 관계) 을 보 여 줍 니 다.
//
public class User implements Serializable {
private String username; //
private String password; //
private List roles; //
}
//
public class Role implements Serializable {
private String roleName; //
private List users; //
}
@Test
public void test() {
//
Use user = new Use("jack", "123"); //
Role role = new Role(" "); //
//
List roles = new ArrayList<>(); //
roles.add(role);
user.setRoles(roles);
List
순환 인용 으로 인해 인용 기호 와 스 택 메모리 가 넘 치 는 문제 의 근본 원인 은 (User 와 Role 을 열 로) 입 니 다. user 대상 은 roles 집합 을 참조 하고 roles 집합 중의 role 대상 은 user 대상 을 참조 합 니 다. 변환 과정 은 다음 과 같 습 니 다.
사용자 대상 을 먼저 변환 합 니 다. 그리고 roles 집합 을 전환 하여 roles 집합 중의 role 대상 을 전환 합 니 다. role 대상 이 user 대상 을 인 용 했 기 때문에 user 대상 을 다시 전환 합 니 다. 1 ~ 3 단계 반복. 위 에서 알 수 있 듯 이 문 제 는 세 번 째 인용 에 나타 나 며, 동시에 JSon 데이터 의 변환 은 대상 의 속성 에 따라 변 환 됩 니 다. 따라서 우 리 는 세 번 째 단계 에서 role 대상 을 전환 할 때 role 이 현상 에 대한 user 인용 을 무시 하면 현재 대상 에 대한 인용 과 순환 에 들 어가 지 않도록 하 는 인용 관 계 를 사용 할 수 있 습 니 다.
대상 속성 을 무시 하고 JSon 데이터 변환 을 할 때 변환 하지 않 는 방법:
1. @ JSONfield 주석 (정적)
//
public class User implements Serializable {
private String username; //
private String password; //
private List roles; //
}
//
public class Role implements Serializable {
private String roleName; //
@JSONField(serialize = false) // , 。
private List users; //
}
@Test
public void test() {
//
Use user = new Use("jack", "123"); //
Role role = new Role(" "); //
//
List roles = new ArrayList<>(); //
roles.add(role);
user.setRoles(roles);
List
2. 필 터 를 사용 하여 변환 할 속성 을 지정 합 니 다 (동적)
필터 (Simple Property PreFilter) 를 정의 합 니 다. JSon 변환 이 필요 한 실체 클래스 의 이름 을 지정 합 니 다. 이렇게 하면 FastJSon 변환 대상 을 사용 할 때 필터 에서 지정 한 속성 만 변환 할 수 있 으 며 지정 한 자동 무시 가 없습니다.
메모: 이 방식 은 동적 으로 변환 할 대상 속성 을 지정 하지만 서로 다른 속성 이름 이 같 을 수 없 도록 요구 합 니 다.
@Test
public void test() {
//
Use user = new Use("jack", "123"); //
Role role = new Role(" "); //
//
List roles = new ArrayList<>(); //
roles.add(role);
user.setRoles(roles);
List
Simple Property PreFilter 의 구조 함수 의 매개 변 수 는 가 변 매개 변수 유형 으로 매개 변 수 를 직접 전달 할 수도 있 고 전환 해 야 할 속성 을 String [] 배열 에 저장 한 다음 에 배열 을 전달 할 수도 있 습 니 다.
public SimplePropertyPreFilter(String... properties){
this(null, properties);
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
자바 디지털 처리 클래스 상용 방법 집합오늘 은 자바 의 디지털 처리 류 와 관련 된 내용 을 배 웠 습 니 다. 그 중에서 흔히 볼 수 있 는 방법 이 많 습 니 다. DecimalFormat 의 format () 과 apply Format () 방법 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.