'JSON'에 해당되는 글 3건

  1. 2017.09.13 JSON 문자열을 Map 으로 변환하기(Jackson 사용)
  2. 2011.08.19 ContentNegotiatingViewResolver 활용 : 하나의 RequestMapping 으로 JSP, JSON, JSONP 처리하기
  3. 2011.08.12 Java JSON 처리 라이브러리 Jackson JSON Processor #1 : Map, List 를 JSON String으로~ 5

JSON 문자열을 Map 으로 변환하기(Jackson 사용)


https://gturnquist-quoters.cfapps.io/api/random 여기에 있는 JSON을 읽어서 Map 으로 변환하고 이것저것 더 해보기


브라우저에서 위 URL 로 접속해 보면 JSON 문자열을 다음과 같다.

{
   type: "success",
   value: {
      id: 10,
      quote: "Really loving Spring Boot, makes stand alone Spring apps easy."
   }
}



요것을 처리하는 예제 코드

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTest {
	public static void main(String[] args)
            throws JsonParseException, JsonMappingException, MalformedURLException, IOException {

        ObjectMapper mapper = new ObjectMapper();

        // URL 에 있는 JSON String 을 Map으로 변환하기
        Map<String, Object> data = mapper.readValue(
                     new URL("https://gturnquist-quoters.cfapps.io/api/random"), 
                     new TypeReference<Map<String,Object>>(){});




        // {type=success, value={id=9, quote=So easy it is to switch container in #springboot.}}
        System.out.println(data);

        // {id=9, quote=So easy it is to switch container in #springboot.}
        System.out.println(data.get("value"));






        // Map을 JSON String 으로 변환
        // {"type":"success","value":{"id":9,"quote":"So easy it is to switch container in #springboot."}}
        System.out.println(mapper.writeValueAsString(data));


        // Map을 보기쉬운 JSON String 으로 변환
        /*
           {
              "type" : "success",
              "value" : {
                "id" : 9,
                "quote" : "So easy it is to switch container in #springboot."
              }
           }
        */
        System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(data));
    }
}


ContentNegotiatingViewResolver 활용 : 하나의 RequestMapping 으로 JSP, JSON, JSONP 처리하기

뭔가를 맨들다 보면 데이터를 가져와서 대부분 JSP 를 이용해서 랜더링을 하게 되지만 똑같은 데이터를 ajax 호출을 통해 json 형식으로 받고 싶은 경우도 종종 있다.

그리고 JSONP 형식으로 같은 도메인이 아닌 다른 도메인으로 데이터를 제공하고 싶은 경우도 있다.

고럴때 ContentNegotiatingViewResolver 를 활용하면 하나의 리퀘스트 핸들러를 맹글어 놓고 맨 뒤에 URL 만 살짝 바꾸면 URL 에 따라 다른 View 를 이용해서 랜더링 시킬 수 있다.

예를 들어 

http://127.0.0.1:8080/test/view                  요럴땐 jsp 로 랜더링
http://127.0.0.1:8080/test/view.json           요럴땐 json 형식으로 랜더링
http://127.0.0.1:8080/test/view.jsonp         요럴땐 jsonp 형식으로 랜더링~

또 약간의 노력을 더해주면 xml 형식이나 rss 형식으로도 랜더링 시킬 수 있다.

죠런 기능을 구현하기 위해서 ContentNegotiatingViewResolver 를 사용하도록 설정해 주고 필요에 따라 AbstractView 클래스를 구현해서 원하는 View를 맹글면 된다.



스프링 설정파일
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
	<!-- ViewResolver 우선순위 설정 -->
	<property name="order" value="1" />
	<property name="mediaTypes">
		<!-- 맵핑될 확장자 정의 -->
		<map>
			<entry key="json" value="application/json" />
			<entry key="jsonp" value="javascript/jsonp" />
		</map>
	</property>

	<property name="defaultViews">
		<list>
			<!-- JSON 요청을 처리할 뷰 -->
			<bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>
			
			<!-- JSONP 요청을 처리할 뷰 -->
			<bean class="stove99.views.JSONPView">
				<property name="contentType" value="javascript/jsonp"/>
			</bean>
		</list>
	</property>
	<property name="ignoreAcceptHeader" value="true" />
</bean>

<!-- 맵핑되는 확장자가 없을때 JSP 로 뷰 처리 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
	<property name="order" value="2" />
	<property name="prefix" value="/WEB-INF/views/"/>
	<property name="suffix" value=".jsp"/>
</bean>
mediaTypes에 정의된 entry 들은 URL 맨 뒤에 붙은 확장자와 mediaType 을 설정한다. 여기에서 설정된 mediaType 정보를 바탕으로 아래쪽 defaultViews 목록에 정의된 View 들 중에서 랜더링 가능한 View 를 찾아서 그 View 로 랜더링 시킨다. 뭐 설명이 허접하긴 하지만 내가 이해한 바로는 그렇다.



stove99.views.JSONPView 클래스 소스
package stove99.views;

import java.io.Writer;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.web.servlet.view.AbstractView;

public class JSONPView extends AbstractView{

	@Override
	protected void renderMergedOutputModel(Map<String, Object> model, 
                                               HttpServletRequest request,
                                               HttpServletResponse response) throws Exception {
		String callback = request.getParameter("callback");
		ObjectMapper om = new ObjectMapper();
		String json = om.writeValueAsString(model);
		
		Writer out = response.getWriter();
		out.append(callback).append("(").append(json).append(")");
	}
}


컨트롤러 소스
package stove99.controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/test/*")
public class TestController {

	@RequestMapping
	public void view(ModelMap model) {
		Map<String, String> data = new HashMap<String, String>();
		data.put("data1", "value1");
		data.put("data2", "value2");
		data.put("data3", "value3");

		model.addAttribute("model", data);
	}
}

테스트 결과 화면

JSP 로 랜더링


JSON 으로 랜더링


JSONP로 랜더링


ContentNegotiatingViewResolverTest.war


Java JSON 처리 라이브러리 Jackson JSON Processor #1 : Map, List 를 JSON String으로~

Java 에서 JSON 을 처리하기 위한 라이브러리는 많이 있겠지만 요즘은 사람들이 Jackson 라이브러리를 많이 쓰는것 같다.

프로젝트 홈페이지(http://jackson.codehaus.org/)에 가보면 "High-performance JSON processor!" 요런 문구가 제일 상단에 떡 있는걸 봐서는 성능도 좋은것 같다!  

일단 그냥 써보자. 계속 쓰다보면 잘 알게 된다.

먼저 라이브러리를 써묵기 위해서 jar 파일을 받아야 한다. 프로젝트 홈페이지 다운로드 메뉴(http://wiki.fasterxml.com/JacksonDownload)로 가서  

쭉 있는것들중에 core-aslmapper-asl 을 다운로드 받아 클래스 패스가 참조하는 폴더에 복사해 주면된다.

웹 프로젝트 같은 경우 WEB-INF/lib 디렉토리에 복사하면 되긋다~

메이븐 프로젝트일 경우는 간단히  pom.xml 에
<dependency>
	<groupId>org.codehaus.jackson</groupId>
	<artifactId>jackson-mapper-asl</artifactId>
	<version>1.8.5</version>
</dependency>
를 추가해 주면 사용할 수 있다.

지금 현재 최신 버전이 1.8.5 이기 때문에 version 란에다 1.8.5를 적어준 것이고 나중에 또 업데이트가 될것이니

 http://mvnrepository.com/artifact/org.codehaus.jackson/jackson-mapper-asl 여기에서 확인해 보고 최신버전으로 바꿔주면 될것이다.


간단한 샘플을 보자.
// 맵에 데이터들이 들어가 있는 형태
Map dummyData1 = new HashMap();
dummyData1.put("value1", "값1");
dummyData1.put("value2", "값2");

ObjectMapper om = new ObjectMapper();

try {	
	System.out.println(om.defaultPrettyPrintingWriter().writeValueAsString(dummyData1));
} catch (JsonGenerationException e) {	
	e.printStackTrace();
} catch (JsonMappingException e) {	
	e.printStackTrace();
} catch (IOException e) {	
	e.printStackTrace();
}
출력결과
{  "value1" : "값1",  "value2" : "값2"}
Jackson 라이브러리로 하는 짓들의 대부분은 ObjectMapper 라는 클래스의 인스턴스 생성을 한다음에 한다.

생성된 고것을 가지고 Json 문자열을 객체로 변환한다던가 객체를 JSON 문자열로 변환한다던가 한다. 뭐 다른 쓸만한 것도 많을 것이다.
뭐 아직 많이 모르니깐~

아무튼 Map 이나 List에 들어가 있는 데이터들을 쪽바로 잘 변환해 준다.

물론 getter 와 setter 메소드 시리즈가 있는 도메인 오브젝트,
예를 들어 User, Account 뭐 이런 종류의 오브젝트도 writeValueAsString 메소드의 파라메터로 넣으면 잘 변환된다.


아무튼~ 각설하고~ List 인 경우도 한번 해보자

// List 에 맵이 들어가 있는 형태
List dummyData2 = new ArrayList();
Map m = new HashMap();
m.put("value1", "값1");
m.put("value2", "값2");
dummyData2.add(m);

m = new HashMap();
m.put("value1", "값3");
m.put("value2", "값4");
dummyData2.add(m);

ObjectMapper om = new ObjectMapper();

try {	
	System.out.println(om.defaultPrettyPrintingWriter().writeValueAsString(dummyData2));
} catch (JsonGenerationException e) {	
	e.printStackTrace();
} catch (JsonMappingException e) {	
	e.printStackTrace();
} catch (IOException e) {	
	e.printStackTrace();
}
출력결과
[ {  "value1" : "값1",  "value2" : "값2"}, {  "value1" : "값3",  "value2" : "값4"} ]
역시 기대했던 대로 잘 변환된다. 

위의 샘플들은 오브젝트를 String으로 변환하는 샘플이고 String 으로 변환활 필요가 없으면(웹요청처리, JSON 파일로 저장하는 경우)  ObjectMapper 클래스의 writeValue() 메소드를 이용해 OutputStream이나 Writer 에 Stream으로 출력해 버려도 된다.
ObjectMapper om = new ObjectMapper();

om.writeValue(response.getWriter(), dummyData);
prev 1 next