AngularJS JSON Parsing 및 $$hashKey 오류 해결

AngularJS에서 객체를 JSON으로 변환하여 Spring 서버로 Ajax 전송할 때 발생하는 $$hashKey 관련 오류를 해결하는 방법입니다.

문제 상황

AngularJS의 ng-repeat 등에서 사용되는 객체에는 $$hashKey라는 내부 속성이 자동으로 추가됩니다. 이 속성이 서버로 전송되면 Jackson 등에서 파싱 오류가 발생할 수 있습니다.

해결 방법

// angular.toJson() 사용 - $$hashKey 자동 제거
angular.toJson(object);

Ajax 요청 시 적용

$http({
    method: "POST",
    url: "/api/save",
    data: angular.toJson(myObject),
    headers: {
        "Content-Type": "application/json"
    }
}).then(function(response) {
    console.log("성공");
});

JSON.stringify vs angular.toJson 차이

var obj = {name: "test", $$hashKey: "object:123"};

// JSON.stringify - $$hashKey 포함
JSON.stringify(obj);
// 결과: {"name":"test","$$hashKey":"object:123"}

// angular.toJson - $$hashKey 제외
angular.toJson(obj);
// 결과: {"name":"test"}

ng-repeat에서 track by 사용

<!-- $$hashKey 생성 방지 -->
<li ng-repeat="item in items track by item.id">
    {{item.name}}
</li>

<!-- 인덱스로 추적 -->
<li ng-repeat="item in items track by $index">
    {{item.name}}
</li>

Spring Controller에서 처리

// Jackson에서 알 수 없는 속성 무시
@JsonIgnoreProperties(ignoreUnknown = true)
public class MyDto {
    private String name;
    // getters, setters
}

// 또는 전역 설정
objectMapper.configure(
    DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false
);

angular.copy() 사용

// 깊은 복사로 $$hashKey 제거
var cleanObj = angular.copy(originalObj);

// 또는 배열의 경우
var cleanArray = angular.copy(originalArray);

수동으로 $$hashKey 제거

function removeHashKey(obj) {
    if (Array.isArray(obj)) {
        return obj.map(removeHashKey);
    }
    if (obj !== null && typeof obj === "object") {
        var result = {};
        for (var key in obj) {
            if (key !== "$$hashKey") {
                result[key] = removeHashKey(obj[key]);
            }
        }
        return result;
    }
    return obj;
}