본문 바로가기

프레임워크/Struts2

struts2에서 json데이터 파싱

참고사이트 : http://json-lib.sourceforge.net/ , http://json.org/java/  , http://jquery.malsup.com/form/

위 사이트 말고도 여러 사이트가 있다. 알아서 참고하시길..

java에서의 json데이타 파싱은 일단 json라이브러리를 필요로 한다.(이런 라이브러리가 있는지 몰랐을때 그냥 문자열로 만들어버렸었다;;;;)

  • jakarta commons-lang 2.4
  • jakarta commons-beanutils 1.7.0
  • jakarta commons-collections 3.2
  • jakarta commons-logging 1.1.1
  • ezmorph 1.0.6

각 라이브러리의 버전차이에서 나는 오류가 있을지 모르지만 일단 제외시켰다.
꼭 저 위의 버전들을 받지 않아도 오류는 안나더라...

라이브러리설치가 끝나면 간단한 폼과 json데이타를 받을 스크립트 코딩(jquery), action클래스를 작성 한다.
DTO는 id, name 만 멤버로 가진다. 알아서 작성..;;
여기서는 단순하게 스크립트로 출력만 했다.

1. test.jsp
...
<script language="javascript">
// prepare the form when the DOM is ready
$(document).ready(function() {
    var options = {
        //target:        '#output1',   // target element(s) to be updated with server response
        beforeSubmit:  showRequest,  // pre-submit callback
        success:       showResponse  // post-submit callback
 
        // other available options: 
        url:    test.action         // override for form's 'action' attribute
        //type:      type        // 'get' or 'post', override for form's 'method' attribute 
        dataType:  'json'        // 'xml', 'script', or 'json' (expected server response type)
        //clearForm: true        // clear all form fields after successful submit
        //resetForm: true        // reset the form after successful submit
 
        // $.ajax options can be used here too, for example:
        //timeout:   3000
    };
 
    // bind form using 'ajaxForm'
    $('#myForm1').ajaxForm(options);
});
 
// pre-submit callback
function showRequest(formData, jqForm, options) {
    // formData is an array; here we use $.param to convert it to a string to display it
    // but the form plugin does this for you automatically when it submits the data
    var queryString = $.param(formData);
 
    // jqForm is a jQuery object encapsulating the form element.  To access the
    // DOM element for the form do this:
    // var formElement = jqForm[0];
 
    alert('About to submit: \n\n' + queryString);
 
    // here we could return false to prevent the form from being submitted;
    // returning anything other than false will allow the form submit to continue
    return true;
}
 
// post-submit callback
function showResponse(data)  {
    var outData = "";
    for(i = 0; i < data.outList.length; i++){
        outData += "id : " + data.outList[i].id + "<br>";
        outData += "name : " + data.outList[i].name + "<br>";
        outData += "-------------------------<br>";
    }
    $("#out").append(outData);
}
</script>
...
...
<s:form name="myForm1" id="myForm1">
id : <s:textfield name="id"/><br>
name : <s:textfield name="name"/><br>
<s:submit />
</s:form>
...
...
<div id="out"></div>

2. TestAction.java
package test;

import test.TestDTO;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class TestAction{
    private String id;
    private String name;
    private JSONObject jsonObject;

    public String execute() throws Exception {
        TestDTO testDto = new TestDTO();
        testDto.setId(id);
        testDto.setName(name);
        List<TestDTO> list = new ArrayList<TestDTO>();
        list.add(testDto);
        list.add(testDto);
        list.add(testDto);

        //json파싱부분
        JSONArray jsonArray = JSONArray.fromObject(list);
        Map<String, Object> jsonMap = new HashMap<String, Object>();
        jsonMap.put("outList", jsonArray);
        jsonObject = JSONObject.fromObject(jsonMap);

        return "success";
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id= id;
    }

    public String getName() {
        return name;
    }

    public void setName(String Name) {
        this.name= name;
    }

    public JSONObject getJsonObject() {
        return jsonObject;
    }

    public void setJsonObject(JSONObject jsonObject) {
        this.jsonObject = jsonObject;
    }
}

3. testResult.jsp(결과만 나올 페이지)
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<s:property value="jsonObject" escape="false"/>


4.struts.xml
<action name="test" action="test.TestAction">
    <result>testResult.jsp</result>
</action>


결과는 알아서 확인하시길...

응용할 수 있는 부분이 아주 많다.
단, 실제로 응용을 해보면서 발견하기 힘든 에러를 하나 발견했다. 익스플로러에서는 보이지 않고 파이어폭스에서만 보이는..비동기로 실행되기 때문에 그런거같다.

결론부터 말하자면 json파싱클래스에서 파싱을 진행할때 Date형식이 있으면 에러가 나온다는 것이다...;;
jsonConfig라는게 있기는한데 이 문제를 해결할 수 있을지는 모르겠다.
결국 String으로 변환해서 에러는 해결했지만 뭔가 방법이 있을거 같다.
아시는분 계시면 댓글좀....ㅎ;

<Date형식에 대한 에러내용>

net.sf.json.JSONException: java.lang.reflect.InvocationTargetException
	net.sf.json.JSONObject._fromBean(JSONObject.java:987)
	net.sf.json.JSONObject.fromObject(JSONObject.java:168)
	net.sf.json.AbstractJSON._processValue(AbstractJSON.java:265)
	net.sf.json.JSONObject._processValue(JSONObject.java:2808)
	net.sf.json.JSONObject.processValue(JSONObject.java:2874)
	net.sf.json.JSONObject.setInternal(JSONObject.java:2889)
	net.sf.json.JSONObject.setValue(JSONObject.java:1577)
	net.sf.json.JSONObject._fromBean(JSONObject.java:934)
	net.sf.json.JSONObject.fromObject(JSONObject.java:168)
	net.sf.json.AbstractJSON._processValue(AbstractJSON.java:265)
	net.sf.json.JSONArray._processValue(JSONArray.java:2514)
	net.sf.json.JSONArray.processValue(JSONArray.java:2539)
	net.sf.json.JSONArray.addValue(JSONArray.java:2526)
	net.sf.json.JSONArray._fromCollection(JSONArray.java:1057)
	net.sf.json.JSONArray.fromObject(JSONArray.java:123)
	net.sf.json.JSONArray.fromObject(JSONArray.java:105)
	action.map.MapIndexAction.execute(MapIndexAction.java:111)
	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	java.lang.reflect.Method.invoke(Unknown Source)
	com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:440)
	com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:279)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:242)
	com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:163)
	com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
	com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:249)
	org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
	com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
	com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:122)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
	com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:195)
	com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
	com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:195)
	com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
	com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:148)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
	org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:93)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
	org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:235)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
	com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:89)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
	com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:128)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
	org.apache.struts2.interceptor.ProfilingActivationInterceptor.intercept(ProfilingActivationInterceptor.java:104)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
	org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:267)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
	com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:126)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
	com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:138)
	com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
	com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:148)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
	org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
	com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:128)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
	com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:176)
	com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
	org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52)
	org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:468)
	org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:395)