스프링 2.5.6 버전에서는 Ajax를 사용 하려면
View 인터페이스를 구현해서 별도의 Ajax전용 View
만들어서 사용 해야 했습니다.
솔직히 Ajax에 지원에 대해서 많이 미흡했습니다.
이유인즉 기술력 문제는 아니고 스프링 진영에서
Ajax가 J2EE스펙이 아니기 때문이라고
SpringSource 웹 사이트에서 본적이 있습니다.
하지만 Spring 3.0이 나오면서 파워풀한 기능이
추가 되었습니다. 그중에서 Spring3.0 기반에서
Ajax 구현 방법에 대해서 말씀 드리겠습니다.

* web.xml

          <servlet>
<servlet-name>springDispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/spring/application/spring.mvc.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>springDispatcher</servlet-name>
<url-pattern>*.json</url-pattern>
</servlet-mapping>

"servlet-mapping" 맵핑 태그에 보면 두개를 설정 했습니다.
하나는 View 호출을 위한 "*.htm",다른 하나는 "*.json"
입니다. 예를 들어서 입력 화면을 호출할때는
확장명이 "htm"으로 호출 하고 값을 입력 하고
넘길때는 "json"으로 호출 합니다.

* Controller

          @Controller
public class HelloWorldController {
@RequestMapping("/helloWorld")
public ModelAndView helloWorld() {
ModelAndView mav = new ModelAndView();
System.out.println("===================");
mav.setViewName("/helloWorld");
return mav;
}

@RequestMapping("/ajax")
public Map get() {
System.out.println("===get");
Map map = new HashMap();
map.put("key","value");
return map;
}
}


* spring.mvc.xml

          

<!-- annotation config -->
<context:annotation-config />
<context:component-scan package="org.beyondj2ee">
<context:include-filter type="regex" expression=".*Controller" />
</context:component-scan>

<!-- handler mapping -->
<bean id="handlerMapping"
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />

<!-- view resolver -->
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="atom" value="application/atom+xml" />
<entry key="html" value="text/html" />
<entry key="json" value="application/json" />
</map>
</property>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/jsp" />
<property name="suffix" value=".jsp" />
</bean>
</list>
</property>
<property name="defaultViews">
<list>
<bean
class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
<property name="prefixJson" value="true" />
</bean>
</list>
</property>
</bean>


스프링 MVC 설정을 합니다.
나머지 부분은 spring2.5.6에 나온 것들이라 생략 하겠습니다.
"view resolver" 파트르를 보면 뷰에 대해서 chain을
형성 합니다.
먼저 "htm"으로 오면 response의 content type을
"text/html" 응답 합니다. "json"은 "application/json"
content type으로 응답 합니다.
스프링 "DispatcherServlet"은 모든 MVC process를
관장 하는데 먼저 "defaultViews"를 찾아서
해당 viewName이 없을 경우 리턴 합니다.
만약 viewName이 있을경우 "viewResolvers"
property에 선언된 순서로 찾아 갑니다.
예를 들어서
"http://localhost:8080/org-beyondj2ee-web/helloWorld.htm"
을 하면 처리하는 메서드에서 viewName을 가지고 있기
때문에 "InternalResourceViewResolver"로 빠지게 되고
"http://localhost:8080/org-beyondj2ee-web/ajax.json"
으로 호출하면 리턴 메서드가 없기 때문에
"MappingJacksonJsonView"로 빠지게 되어 있습니다.
Controller의 설정과 무관하게 decoupling 되게
구성이 되어 있습니다.
아... 주석 플러그인이 자꾸 XML이 깨지네요
죄송 합니다. 안깨지는 플러그인좀 있으면
추천좀 해주세요 ㅠ.ㅠ

* 퍼온글 http://beyondj2ee.egloos.com/293294


출처 - http://dev-world.springnote.com/pages/6358467


===================================================================================


spring 3.0으로 플젝을 준비하고있는데 restful과 json을 주로 사용하게될듯해서 이런저런걸 해보았는데
삽질을통해 나온 예제를 올립니다.
물론 지금까지 습득한 지식의 한도내에서의 내용입니다. ㅎㅎ

view 모델을 json으로 받을 수 있는 방법은 MessageConverters를 사용하거나.
view 를 org.springframework.web.servlet.view.json.MappingJacksonJsonView 로 할수있다.
그리고 org.springframework.web.servlet.view.ContentNegotiatingViewResolver를 통해 다른 포맷의 뷰와 함께 사용할수있다. 확장자를 통해서..

일단 올릴 예제는 MessageConverters를 사용한거와 MappingJacksonJsonView를 사용한 예제를 올리겠습니다.

1. MessageConverters 를 사용해서 json view 구현

web.xml
      
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.st</url-pattern> 
</servlet-mapping>
 
확장자를 .st로 했습니다. 

dispatcher-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">
 
<context:component-scan base-package="com.ajax" />   
    <bean id="handlerMapping"     class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" p:alwaysUseFullPath="true" />
      
 <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" p:alwaysUseFullPath="true">
  <property name="messageConverters">
  <list>
  <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
  </list>
  </property>
 </bean>
 
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/checkloginid/"></property>
<property name="suffix" value=".jsp" />
</bean>
  
</beans>

컨트롤로 클래스 자동스캔을 사용했습니다. <context:component-scan base-package="com.ajax" />   
handermapping를 DefaultAnnotationHandlerMapping과 AnnotationMethodHandlerAdapter 를 사용했습니다. 여기에서 messageConverter를 등록할 때는 AnnotationMethodHandlerAdapter 해줘야하기때문에
AnnotationMethodHandlerAdapter 에 MappingJacksonHttpMessageConverter messageConverters를 설정했습니다. json으로

Controller 클래스 

@Controller
public class LoginController {
@RequestMapping(value="/checkloginids/{loginId}" , method=RequestMethod.GET)
@ResponseBody
public Map checklogins(@PathVariable String loginId){
 
Map<String, String> map=new HashMap<String, String>();
map.put("firstname", "이");
map.put("secondname", "정x"); 
 
return map;
}
        @RequestMapping("/listtypeModelAndView") 
@ResponseBody
public  Model listtypeModelAndView(Model model){
System.out.println("listtypeModelAndView");
String[] s=null;
s=new String[4];
s[0]="1";
s[1]="2";
s[2]="3";
s[3]="4";
String[] s1=new String[4];
s1[0]="11";
s1[1]="21";
s1[2]="31";
s1[3]="41";
List<String[]> listuserInfo=new ArrayList<String[]>();
listuserInfo.add(s);
listuserInfo.add(s1);
List<Map> listjob=new ArrayList<Map>();
Map<String, String> map=new HashMap<String, String>();
map.put("firstname", "이");
map.put("secondname", "정x"); 
listjob.add(map); 
  
model.addAttribute("userInfo", listuserInfo); 
model.addAttribute("jobInfo", listjob); 
//결과  {"userInfo":[["1","2","3","4"],["11","21","31","41"]],"jobInfo":[{"secondname":"\uc815\ud658","firstname":"\uc774"}]}
return model;
}
}

@ResponseBody 를 해주는데 @ResponseBody는 
이 애노테이션이 붙은 파라미터에는 HTTP 요청이 본문 body부분이 그대로 전달된다. 일반적인 GET/POST의 요청 파라미터라면 @ResponseBody를 사용할 일이 없을 것이다. 반면 xml이나 json 기반의 메시지를 사용하는 요청의 경우에는 이방법이 매우 유용하다.
AnnotationMethodHandlerAdapter에는 HttpMessageConverter 타입의 메시지 변환기가 여러개 등록되어 있다. @ResponseBody가 붙은 파라미터가 있으면 HTTP요청의 미디어 타입과 파라미터의 타입을 먼저 확인한다. 메시지 변환기 중에서 해당 미디어 타입과 파라미터 타입을 처리할 수 있는 것이 있다면, HTTP 요청의 본문부분을 통째로 변환해서 지정된 메소드 파라미터로 전달해준다. -토비의 스프링 3  page-1153

리턴해주는 type이나 방법을 몇가지로 해봤는데 model로 하는게 가장 유용할 것 같다.


jsp 파일

 <script src="http://code.jquery.com/jquery-1.4.4.js"></script>
 <script src="js/json2.js"></script>
<script type="text/javascript">
$(document).ready(function() {
printResult = function(data){
var result = 
"Json-Result:"
+ "\n" + JSON.stringify(data);
alert(data);
document.write(result);
};
 
//$.getJSON('checkloginids/hosincool.st', 
//$.getJSON('listtype.st',
//$.getJSON('listtypeModelAndView.st',
$.getJSON('string.st',
function(data){
printResult(data);
$('#firstname').html(data.firstname);
$('#secondname').html(data.secondname);
});
});
</script>


2. MappingJacksonJsonView 를 사용한 json view 구현

dispacher-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">
       
<bean id="jsonController" class="com.ajax.JsonController" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean id="jsonReport" class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>
 
</beans>


Controller 클래스

@Controller
public class JsonController {

@RequestMapping("/jsonReport") 
public ModelAndView jsonReport(){
 
List<Map<String, String>> pageRanks=new ArrayList<Map<String,String>>();
Map map=new HashMap<String, String>();
map.put("1", "하나");
Map map1=new HashMap<String, String>();
map1.put("2", "둘");
Map map2=new HashMap<String, String>();
map2.put("3", "셋");
map2.put("3", "넷");
map2.put("3", "뭐지");
map2.put("name", map1); 
pageRanks.add(map1);
pageRanks.add(map2);
return new ModelAndView("jsonReport","report",pageRanks);
}
@RequestMapping("/jsonReport2") 
public ModelAndView jsonReport2(){
    
Map map1=new HashMap<String, String>();
map1.put("job_name", "what!");
map1.put("office_name", "xxxxㅌ");
Map map2=new HashMap<String, String>();
map2.put("name", "바람소리");
map2.put("tel", "010-000000");
map2.put("id", "vishvoice");
map2.put("age","30");
 
/**
 * 아래처럼 addObject("","");이렇 해주면 json {userInfo:{'',''},jobinfo:{'',''}}
 * 이렇게 나온다.
 * 허나 ModelAndView로 하지 않고.. Map 타입으로하면 userInfo와 jobinfo 두개를 줄수있는 방법을
 * 못 찾았다.
 */
ModelAndView modelAndView=new ModelAndView("jsonReport");
modelAndView.addObject("userInfo", map2);
modelAndView.addObject("jobinfo", map1);
return modelAndView;
}
}

view를 MappingJacksonJsonView로 했기 때문에 view id를 ModelAndView modelAndView=new ModelAndView("jsonReport");이렇게 해주면 된다.

jsp
 
<script src="http://code.jquery.com/jquery-1.4.4.js"></script>
 <script src="js/json2.js"></script>
<script type="text/javascript">
$(document).ready(function() {
printResult = function(data){
var result = 
"Json-Result:"
+ "\n" + JSON.stringify(data);
alert(result);
};
 
$.getJSON('down/jsonReport2', 
function(data){
printResult(data);
$('#firstname').html(data.firstname);
$('#secondname').html(data.secondname);
});
});
</script>

이거 외에 위에서 말했듯 ContentNegotiatingViewResolver를 통해 확장자를 통한 다양한 포맷형식을 처리하는 방법도 있습니다.
그건 다음에 시간이 되면 올리겠습니다.


출처 - http://windvoice.tistory.com/51


===================================================================================


json사용 ContentNegotiatingViewResolver 에서 Converter로

json 을 사용하기 위해 ContentNegotiatingViewResolver 을 사용하였다 .

확장자 json 을 통해 호출하면 결과값이 잘 떨어진다  *.do 에서

json 을 받기 위해 /* 변경해야 했으며 이 방식 Restful 방식에 어울리는듯 하다 .

[spring-context.xml]

<bean class=”org.springframework.web.servlet.view.ContentNegotiatingViewResolver”>

<property name=”mediaTypes”>

<map>

<entry key=”json” value=”application/json” />

</map>

</property>

<property name=”defaultViews”>

<list>

<bean class=”org.springframework.web.servlet.view.json.MappingJacksonJsonView”/>

</list>

</property>

<property name=”order” value=”1″ />

<property name=”ignoreAcceptHeader” value=”true” />

</bean>

[web.xml]

<servlet-mapping>

<servlet-name>spring</servlet-name>

<url-pattern>/*</url-pattern>

</servlet-mapping>

결국 기존의 것에서 가장 작은 변화를 주고 json 을 처리하는것은 Converter 를

이용하는것이었다 . jacksonMessageConverter 와 @ResponseBody 를 이용하면 된다 .

controller 에서는 ModelAndView 대신 원하는 형식의 VO 객체를 리턴하거나 Map 을이용해

객체처럼 구성해 리턴해도 된다.

<bean class=”org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter”>

<property name=”messageConverters”>

<list>

<ref bean=”jacksonMessageConverter”/>

</list>

</property>

</bean>

<bean class=”org.springframework.http.converter.json.MappingJacksonHttpMessageConverter” />

@RequestMapping(“/jsonTest”)

@ResponseBody

public List jsonTest(){

}


출처 - http://devwa.com/?p=169



Posted by linuxism
,