TL;DR
@JsonRawValue
다음과 같은 JSON 데이터를 tbl_json_raw_value
테이블의 json
열에 저장하고 있습니다.
{
"name": "iroiro",
"version_code": 1,
"majority": [
"Java", "Kotlin", "Spring", "Javascript", "Swift", "Node.js", "Android", "Cpp", "iOS"
]
}
여기서 json
열의 stringified된 JSON 데이터를 아래와 같이 응답하고 싶은 경우가 있을 겁니다.
{
"status": 200,
"json_data": {
"name": "iroiro",
"version_code": 1,
"majority": [
"Java",
"Kotlin",
"Spring",
"Javascript",
"Swift",
"Node.js",
"Android",
"Cpp",
"iOS"
]
}
}
샘플 코드 작성
컨트롤러
우선 단순히 tbl_json_raw_value
테이블의 json
열의 값을 읽어와 json_data
프로퍼티 하위에 담아 응답하는 Controller를 생성해서 잘 되는지 테스트 해 봅시다.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/iroiro")
public class IroiroRestController {
@Autowired
IroiroJsonRepository jsonRepository;
@GetMapping("json")
public ResponseEntity<IroiroJsonResponse> getJson(@RequestParam Long idx) {
// DB에서 데이터 획득
IroiroJsonDao dao = jsonRepository.findById(idx).orElse(null);
// 바디 생성
IroiroJsonResponse body = new IroiroJsonResponse();
// 바디 데이터 입력
body.setCode(1234);
if(dao != null) {
body.setData(dao.getJson());
}
// 응답에 바디 실어서 응답
return new ResponseEntity<>(body, HttpStatus.OK);
}
}
DAO
DB 접근 DAO 클래스도 하나 만들어줍니다.
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Table(name = "json")
@Entity
public class IroiroJsonDao {
@Id
@Column(name = "idx", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long idx;
@Column(name = "json", nullable = false)
private String json;
}
Repository
JpaRepository 인터페이스에 위에서 만든 DAO를 매핑합니다
public interface IroiroJsonRepository extends JpaRepository<IroiroJsonDao, Long> {
}
VO
아래는 HttpEntity의 데이터에 해당하는 응답 객체 클래스입니다.
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class IroiroJsonResponse {
private Integer status;
private String jsonData;
}
테스트 결과
스프링 서버를 구동 후 컨트롤러에 요청을 하게 되면 아래와 같은 현상이 나타나게 됩니다.
{
"status": 200,
"json_data": "{\"name\":\"iroiro\",\"version_code\":1,\"majority\":[\"Java\",\"Kotlin\",\"Spring\",\"Javascript\",\"Swift\",\"Node.js\",\"Android\",\"Cpp\",\"iOS\"]}"
}
DB의 json
열의 값을 단순한 String으로 판단했고 추가로 몇몇 특수 문자는 이스케이프 처리 되었습니다. 원래 의도는 IroiroJsonResponse
의 jsonData
항목에 Object
형태로 응답 하고 싶었던 것입니다.
@JsonRawValue
이 때 IroiroJsonResponse
의 jsonData
필드에 @JsonRawValue (com.fasterxml.jackson.annotation.JsonRawValue)
어노테이션을 추가해주면 String 데이터를 JSON으로 직렬화 하여 별도의 VO를 생성하지 않고 응답을 할 수 있습니다.
// JsonRawValue import
import com.fasterxml.jackson.annotation.JsonRawValue;
public class IroiroJsonResponse {
private Integer status;
// @JsonRawValue 어노테이션을 추가해준다
@JsonRawValue
private String jsonData;
}
다른 방법으로는 직접 매퍼를 설계하거나 컨버터를 구현하는 방법 등이 있으나 제가 찾은 방법중에서는 이것이 가장 간단한 방법이었네요 😆
참고
'소프트웨어 > 웹' 카테고리의 다른 글
[Nginx] nginx 한글 깨짐 해결 (1) | 2023.11.29 |
---|---|
[Spring-Maven] Maven 빌드 시 JUnit Test 하지 않도록 설정하기 (0) | 2021.04.06 |
[Spring boot] VS Code Spring Boot Extension의 app이 안보이는 현상 해결 (8) | 2021.03.17 |
[Spring boot | thymeleaf] pom.xml의 데이터를 가져와서 화면에 할당하는 방법 (3) | 2020.08.25 |
[Spring boot] 에러 페이지 처리 (0) | 2020.08.21 |