2011-03-23 5 views
0

JSONP를 사용하여 Spring MVC에서 컨트롤러 서비스를 호출하고 있습니다. 콜백에 래핑 된 결과를 반환하는 사용자 지정 필터가 있습니다. 이 예제는 http://jpgmr.wordpress.com/2010/07/28/tutorial-implementing-a-servlet-filter-for-jsonp-callback-with-springs-delegatingfilterproxy/입니다. ContentNegotiatingViewResolver도 사용하고 있지만 결과는 콜백에서 XML을 계속 반환합니다. 왜 계속 그렇게 할거야?JSONP 및 사용자 정의 필터 Spring MVC 대신 XML 반환

jQuery1509349652162468509_1300839533498(<?xml version="1.0" encoding="UTF-8" standalone="yes"?><followResponse><id>0</id></followResponse>); 

서블릿-context.xml에

<beans:bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> 
     <beans:property name="order" value="1"/> 
     <beans:property name="mediaTypes"> 
      <beans:map> 
       <beans:entry key="json" value="application/x-json"/> 
       <beans:entry key="json" value="text/json"/> 
       <beans:entry key="json" value="text/x-json"/> 
       <beans:entry key="json" value="application/json"/> 
       <beans:entry key="xml" value="text/xml"/> 
       <beans:entry key="xml" value="application/xml"/> 
      </beans:map> 
     </beans:property> 
     <beans:property name="defaultViews"> 
      <beans:list> 
       <beans:bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/> 
       <beans:bean class="org.springframework.web.servlet.view.xml.MarshallingView"> 
        <beans:property name="marshaller"> 
         <beans:bean class="org.springframework.oxm.xstream.XStreamMarshaller" /> 
        </beans:property> 
       </beans:bean> 
      </beans:list> 
     </beans:property> 
    </beans:bean> 

답변

1

제 생각 엔 컨트롤러 메소드가 @ResponseBody를 사용하고 있고 돌아 오는 모델 객체가 Jaxb2 주석 (특히 @XmlRootElement)으로 마크 업됩니다.

나는 당신과 동일한 문제가있었습니다. 문제는 @ResponseBody가 ContentNegotiatingViewResolver를 우회하는 것입니다. ContentNegotiatingViewResolver의 메소드에 "resolveViewName"과 같은 몇 가지 중단 점을 추가하고 실제로 맞았는지 확인하여이를 확인할 수 있습니다.

현재 사용하고있는 해결 방법은 실제로 json 뷰를 선언하고 구체적으로 사용하는 것입니다.

당신은 당신의 XML이 뭔가를 추가해야합니다 :

<bean id="jsonView" class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/> 

당신은 다음뿐만 아니라이 같은 것을보고 목록 항목을 변경할 수 있습니다

<beans:ref bean="jsonView" /> 

컨트롤러 방법은 것 ModelAndView를 다음과 같이 반환하십시오.

@RequestMapping(value = "/{username}/get.json", method = RequestMethod.GET) 
public ModelAndView getUser(@PathVariable String username) { 
    User user = service.getUser(username); 
    return new ModelAndView("jsonView", "user", user); 
} 

아니면 그냥 다음과 같이 뷰를 반환 할 수 있습니다. 트링, 그리고 메소드 서명에 ModelMap를 선언 추가

@RequestMapping(value = "/{username}/get.json", method = RequestMethod.GET) 
public String getUser(@PathVariable String username, ModelMap model) { 
    User user = service.getUser(username); 
    model.addAttribute("user", user); 
    return "jsonView"; 
} 

희망이 도움이됩니다.

(참고 : 메모리에서이을 입력, 그래서 등, 구문 오류에 대한 가능성이있다) 나는 아직이 문제에 대한 더 우아한 해결책을 발견하지 않은

하지만 내가 할 경우, 나는 그것을 게시합니다 이리.

편집 :

시도 @ResponseBody를 제거. 이렇게하면 MessageConverters가 활성화되지 않고 ContentNegotiatingViewResolver가 트리거됩니다. 이 시점에서 뷰를 결정하는 확장 프로그램이어야합니다 (설정에 따라 다름).

@ResponseBody를 제거하는 것 외에는 변경할 필요가 없으며 반환 유형은 동일하게 유지 될 수 있습니다.

+0

이것은 JSONP 요청에 대한 해결 방법 이었습니까? –

+0

이것은 JSON을 일반적으로 반환하기위한 해결 방법입니다. 내 응용 프로그램에는 jstl 뷰를 사용하는 일반 컨트롤러가 있지만 XML 또는 JSON 형식의 데이터도 노출됩니다. @ResponseBody와 같이 pojo를 반환 할 때 모든 것이 잘 작동했지만, Jaxb 주석으로 마크 업 된 pojo를 반환하려고 시도했을 때, XML이 항상 반환 될 것이기 때문에 (확장자가 .json이고 ContentNegotiatingViewResolver가 확장을 선호하도록 적절하게 구성 되었기 때문에). 나는이 정보가 받아 들일만한 해결책에 가까워 질 수 있다고 생각했다. –

+0

이것으로부터 무엇이든 가져갈 수 있다면 @ResponseBody를 사용하면 ContentNegotiatingViewResolver를 우회하여 대신 등록 된 MessageConverters를 사용할 것입니다. 이 경우 적절한 변환기는 "accept"헤더에 의해 선택됩니다. 위에서 당신은 accept 헤더를 무시하고 있다고 언급했지만, 이는 AnnotationMethodHandlerAdapter에 의해 선택된 MessageConverters가 아니라 ContentNegotiatingViewResolver에만 해당됩니다. –

0

확인 요청의 수락 헤더.

+0

나는 그들을 무시하고 있습니다. 그들은 text/javascript를 원하는 것과는 다르다. –

0

내 블로그 게시물을 볼 수있어서 좋았어. :-D

종속성에 Jackson 매퍼 API를 추가 했습니까? Spring MVC 애플리케이션을 만들 때 기본적으로 존재하지 않을 것이다. 직접 추가해야하며 JSON에 대한 응답을 마샬링해야합니다.

+0

예 모두 올바르게 추가되었습니다. JSON과 XML은 반환 할 때 제대로 작동합니다. JSONP와 JQuery 일뿐입니다. 나는 이것이 Accept Headers와 관련이 있다고 생각하지만, 나는 생각했던 것을 무시하고있다. 네 좋은 솔루션. –

0

임시 솔루션은 XML을 사용하고 당분간 JSON으로 변환하는 JSON 파서를 사용하는 것이 었습니다. 그렇다면 XML로 파싱 한 다음 JSON으로 파싱하는 것이 좋겠지 만 지금은이 작업이 필요합니다.

String xml = new String(wrapper.getData()); 

      if(!StringUtils.isEmpty(xml)) 
      { 
       XMLSerializer xmlSerializer = new XMLSerializer(); 
       JSON json = xmlSerializer.read(xml); 
       out.write(json.toString().getBytes()); 
      } 

      out.write(new String(");").getBytes());