복붙노트

[SPRING] Spring JSON은 Spring 프레임 워크가 3.0.2에서 3.2.0으로 업그레이드 될 때 문제를 일으킨다.

SPRING

Spring JSON은 Spring 프레임 워크가 3.0.2에서 3.2.0으로 업그레이드 될 때 문제를 일으킨다.

나는 Hibernate (NetBeans 6.9.1)와 함께 Spring 프레임 워크 버전 3.0.2를 사용하는 웹 애플리케이션으로 작업하고 있었다. 나중에 나는 이전 질문 중 하나에서 언급 한 것처럼 여러 파일을 업로드 할 때 문제를 일으키는 버그가 있음을 알게되었습니다.

나는 해결책을 얻으려고 고생했지만 성공하지 못했습니다. 따라서 Spring 버전을 3.2.0으로 업그레이드했습니다.

이전 버전 (3.0.2)에서는 AJAX가 Jackson 1.9.8 (다운로드 페이지)과 잘 작동했지만 이후 버전 (3.2.0)에서는 모든 것이 잘 작동하지만 AJAX 호출은 JavaScript 코드의 모든 부분에 오류를 경고합니다.

국가 선택 상자에서 국가 중 하나가 선택되면 한 곳에서 시나리오가 발생하고 DAO와 함께 스프링 컨트롤러에서 해당 상태 목록이 검색됩니다. Spring 컨트롤러에서 URL로 매핑되는 메소드는 다음과 같습니다.

@RequestMapping(value="ajax/GetStateList", method=RequestMethod.GET)
public @ResponseBody List<Object[]> getStateSelectBox(HttpServletRequest request)
{
    return cityService.getStateSelectBox(request.getParameter("countryId"));
}   

이 메서드는 국가 선택 상자에서 국가를 선택하면 호출됩니다. getStateSelectBox () 메소드는 DAO 클래스 중 하나에서 다음과 같이 정의됩니다.

@Service
@Transactional(readOnly = true, propagation=Propagation.REQUIRES_NEW)
public final class CityDAO implements CityService
{
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory)
    {
        this.sessionFactory = sessionFactory;
    }

    @SuppressWarnings("unchecked")
    public List<Object[]> getStateSelectBox(String id)
    {
        List<Object[]> list = sessionFactory.getCurrentSession()
                          .createQuery("select s.stateId, s.stateName from StateTable s where countryId.countryId=:id order by s.stateId")
                          .setParameter("id", Long.parseLong(id)).list();

       for(Object[]o:list)
       {
           System.out.println(o[0]+" : "+o[1]);
       }
       return list;
   }
}

foreach 루프는 데모 용으로, AJAX 요청에 의해 제공된 countryId에 해당하는 ID와 함께 모든 상태를 표시하지만 목록은 JSP로 반환되지 않습니다.

이 AJAX 요청을 보내는 데 사용 된 JavaScript 코드는 오류를 경고합니다. JSON 매핑에는 몇 가지 문제가있는 것으로 보입니다. 이전 버전의 Spring 프레임 워크 (3.0.2)에서도 동일한 작업이 진행되었습니다. 왜 이것이 3.2.0 인 Spring의 상위 버전에서 문제를 일으키는 지 모르겠습니다. 스프링 버전 3.2.0에 누락 된 부분이 있습니까?

자바 스크립트 코드를 확인해야 할 경우,이를 달성하기위한 전체 자바 스크립트 코드는 다음과 같습니다.

function getStates(countryId)
{
    if(countryId==""||countryId==null||countryId==undefined||isNaN(countryId))
    {
        var str="<select id='cmbStates' name='cmbStates' onchange='errorMessage(this.value);' class='validate[required] text-input'><option value=''>Select</option></select>";
        $('#stateList').html(str);
        alert("Please select an appropriate option.");
        return;
    }

    var div=document.createElement("div");
    div.id="temp";
    document.body.appendChild(div);

    $.ajax({
        datatype:"json",
        type: "GET",
        contentType: "application/json",
        url: "/wagafashion/ajax/GetStateList.htm",
        data: "countryId=" + countryId+"&t="+new Date().getTime(),
        success: function(response)
        {
            if(typeof response==='object'&&response instanceof Array)
            {                            
                var str="<select id='cmbState' name='cmbState' onchange='errorMessage(this.value);' class='validate[required] text-input'><option value=''>Select</option>";
                var l=response.length;

                for(var i=0;i<l;i++)
                {
                    str+="<option value='"+response[i][0]+"'>"+$('#temp').text(response[i][1]).html()+"</option>";
                }
                str+="</select>";
                $('#stateList').html(str); // select box is written to #stateList div
                $('#temp').remove();
            }
        },
        error: function(e)
        {
            alert('Error: ' + e);
        }
    });
}            

확실하게, 잭슨 라이브러리는 classpath에 있고 나는 서버 측에서 어떤 에러 나 예외도 얻지 못한다. AJAX 요청이 성공하고 Spring을 통해 DAO로 이동하고 List 유형 목록이 데이터베이스에서 검색되지만 JSP에 대한 JSON (자바 스크립트 배열에 매핑 될 수 있거나 매핑되어야 할 수 있음) . 아마도 이전 버전의 Spring에서는 그렇지 않은 JSON 매핑에 누락 된 것이있는 것으로 보입니다.

편집하다:

나는 두 가지 프레임 워크, 3.0.2 및 3.2.0에서 List 를 파싱하려고 시도했다.

List<Object[]> list = cityService.getStateSelectBox(request.getParameter("countryId"));
ObjectMapper objectMapper=new ObjectMapper();
try
{
    objectMapper.writeValue(new File("E:/Project/SpringHibernet/wagafashionLatest/temp.json"), list);
}
catch (IOException ex){}

temp.json 파일에는 다음 문자열이 들어 있습니다.

[[21,"Gujarat"],[22,"Maharashtra"],[23,"Kerala"],[24,"New Delhi"]]

두 경우 모두 (두 프레임 워크 모두 포함). 따라서 JSON 응답은 두 경우 모두 동일해야합니다.

temp.json 파일은 다음과 같이 deserialize 할 수도 있습니다.

try
{
    ObjectMapper mapper=new ObjectMapper();
    List<Object[]> list = mapper.readValue(new File("E:/Project/SpringHibernet/wagafashionLatest/temp.json"), new TypeReference<List<Object[]>>() {});

    for(Object[]o:list)
    {
        System.out.println(o[0]+" : "+o[1]);
    }
} 
catch (IOException ex) 
{

}

그것은 잘 작동하고 foreach 루프 List 형식의 목록을 반복합니다. 따라서이 문제는 Spring 프레임 워크 자체에 의해 발생할 수 있습니다. 그 밖에 필요한 것은 확실하지 않습니다. 왜 잭슨이 매핑하지 않습니까?

해결법

  1. ==============================

    1.저는 Spring 3.1.3을 사용하고 있습니다. 잭슨 매핑이 응답에서 루트 객체를 만들려고합니다. 이것은 Jackson2 매퍼와 함께 있습니다. 나는 나이 든 잭슨 매퍼와 함께 노력하지 않았다. Jackson을 업그레이드 한 경우에도 동일한 문제가 발생할 수 있습니다.

    저는 Spring 3.1.3을 사용하고 있습니다. 잭슨 매핑이 응답에서 루트 객체를 만들려고합니다. 이것은 Jackson2 매퍼와 함께 있습니다. 나는 나이 든 잭슨 매퍼와 함께 노력하지 않았다. Jackson을 업그레이드 한 경우에도 동일한 문제가 발생할 수 있습니다.

    과거에는 객체 배열이 다음과 같이 매핑되었습니다.

    [{name:'name1',id:4},{name:'name2',id:6}]
    

    이제는 자동 생성 된 객체 이름을 객체에 제공하고 있으므로 다음과 같이 반환됩니다.

    { objectArray: [{name:'name1',id:4},{name:'name2',id:6}]}
    

    따라서 응답 [0]을 직접 참조 할 수있는 대신 response.objectArray [0]을 참조해야합니다.

    어쨌든 JSON 응답이 형식을 다소 변경했을 가능성이 있습니다. 새로운 응답을보고 javascript에서 새로운 구조를 매핑하도록 변경 사항을 확인해야합니다.

  2. ==============================

    2.나는 Spring 포럼에서 같은 글을 가지고있다. 궁극적으로 저에게 효과적이었던 질문에 대한 답은 다음과 같이 dispatcher-servlet.xml 파일을 구성해야했습니다.

    나는 Spring 포럼에서 같은 글을 가지고있다. 궁극적으로 저에게 효과적이었던 질문에 대한 답은 다음과 같이 dispatcher-servlet.xml 파일을 구성해야했습니다.

    <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />
    
    <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
        <property name="favorPathExtension" value="false" />
        <property name="favorParameter" value="false" />
        <property name="ignoreAcceptHeader" value="false" />
        <property name="mediaTypes" >
            <value>
                atom=application/atom+xml
                html=text/html
                json=application/json
                *=*/*
            </value>
        </property>
    </bean>
    

    JSON은 Jackson 1.9.8 및 Spring 3.2.0에서 작동합니다. 이 질문에 대한 모든 답장에이 금액이 적립됩니다.

    이제 전체 dispatcher-servlet.xml 파일은 다음과 같이 보입니다.

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:p="http://www.springframework.org/schema/p"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
    
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
    
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    
    
        <context:component-scan base-package="controller" />
        <context:component-scan base-package="validatorbeans" />
    
        <mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />
        <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
            <property name="favorPathExtension" value="false" />
            <property name="favorParameter" value="false" />
            <property name="ignoreAcceptHeader" value="false" />
            <property name="mediaTypes" >
                <value>
                    atom=application/atom+xml
                    html=text/html
                    json=application/json
                    *=*/*
                </value>
            </property>
        </bean>
    
    
        <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
        <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
        <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
            <property name="mappings">
                <props>
                    <prop key="index.htm">indexController</prop>
    
                </props>
            </property>
        </bean>
    
        <bean id="viewResolver"
              class="org.springframework.web.servlet.view.InternalResourceViewResolver"
              p:prefix="/WEB-INF/jsp/"
              p:suffix=".jsp" />
    
        <bean name="indexController"
              class="org.springframework.web.servlet.mvc.ParameterizableViewController"
              p:viewName="index" />
    </beans>
    
  3. from https://stackoverflow.com/questions/14060314/spring-json-causes-problems-when-the-spring-framework-is-upgraded-from-3-0-2-to by cc-by-sa and MIT license