'Spring'에 해당되는 글 7건

  1. 2011.08.19 ContentNegotiatingViewResolver 활용 : 하나의 RequestMapping 으로 JSP, JSON, JSONP 처리하기
  2. 2011.08.03 <context:property-placeholder/> 를 사용할때 property file의 encoding 지정하기

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


<context:property-placeholder/> 를 사용할때 property file의 encoding 지정하기


config.property
#한글로 된 프로퍼티값
attach.path=c:\첨부파일\ 
 위처럼 property 파일에 있는 값들중 한글값은 제대로 받아지지 않는다.



 뭐 이것저것 받을 수 있는 방법이야 많겠지만 많은 방법들 중 한가지로 요렇게도 할 수 있다.
<bean id="fileEncoding" class="java.lang.String">
	<constructor-arg value="UTF-8"/>
</bean>
 
<context:property-placeholder location="classpath:config.properties" file-encoding="fileEncoding"/>


file-encoding="UTF-8" 요렇게만 하면 될줄 알았는데 그렇게 설정하니 No bean named 'UTF-8' is defined 라나 뭐라나~

어렴풋이 대략 찾아보니 버그라고 쫑알쫑알 거리는 사람들이 있던데 버근지 원래 저래 하면 안되는건지 나는 잘 모르겠다.

더 찾아 보기도 귀찮고~~~



원래는
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
	<property name="locations" value="classpath:config.properties"/>
	<property name="fileEncoding" value="UTF-8"/>
</bean>
요렇게 썼었는데 <context:property-placeholder/> 이게 왠지 더 있어 보이고 한 라인으로 끝낼 수 있을것 같아서 바꿨는데

file-encoding="UTF-8" 이게 안되서 설정을 위한 라인수가 더 길어져 버렸다~
 
prev 1 2 next