You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Shaun Lim <sh...@gmail.com> on 2012/10/11 08:23:42 UTC

Struts2 REST plugin: Passing array in JSON

My entity class:

import java.util.ArrayList;


public class Test {
    private String name;
    private String description;
    private ArrayList<String> countries;

    public Test() {

    }

    public String getName() {
        return name;
    }

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

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public ArrayList<String> getCountries() {
        return countries;
    }

    public void setCountries(ArrayList<String> countries) {
        this.countries = countries;
    }
}

The JSON I'm trying to send:

{"countries": ["CA", "SG"], "description":"whee", "name": "foo"}

The error:

2345447 [http-bio-8080-exec-1] ERROR freemarker.runtime  - Method
public java.lang.String
org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
threw an exception when invoked on net.sf.json.JSONException: Error
while setting property=countries type interface java.util.List

Method public java.lang.String
org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
threw an exception when invoked on net.sf.json.JSONException: Error
while setting property=countries type interface java.util.List
The problematic instruction:
----------
==> ${msgs[0][0]} [on line 76, column 25 in
org/apache/struts2/dispatcher/error.ftl]
----------

Java backtrace for programmers:
----------
freemarker.template.TemplateModelException: Method public
java.lang.String
org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
threw an exception when invoked on net.sf.json.JSONException: Error
while setting property=countries type interface java.util.List
    at freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:130)
    at freemarker.ext.beans.SimpleMethodModel.get(SimpleMethodModel.java:138)
    at freemarker.core.DynamicKeyName.dealWithNumericalKey(DynamicKeyName.java:111)
    at freemarker.core.DynamicKeyName._getAsTemplateModel(DynamicKeyName.java:90)
    at freemarker.core.Expression.getAsTemplateModel(Expression.java:89)
    at freemarker.core.Expression.getStringValue(Expression.java:93)
    at freemarker.core.DollarVariable.accept(DollarVariable.java:76)
    at freemarker.core.Environment.visit(Environment.java:210)
    at freemarker.core.MixedContent.accept(MixedContent.java:92)
    at freemarker.core.Environment.visit(Environment.java:210)
    at freemarker.core.IfBlock.accept(IfBlock.java:82)
    at freemarker.core.Environment.visit(Environment.java:210)
    at freemarker.core.IfBlock.accept(IfBlock.java:82)
    at freemarker.core.Environment.visit(Environment.java:210)
    at freemarker.core.MixedContent.accept(MixedContent.java:92)
    at freemarker.core.Environment.visit(Environment.java:210)
    at freemarker.core.Environment.process(Environment.java:190)
    at freemarker.template.Template.process(Template.java:237)
    at org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:797)
    at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:519)
    at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
    at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:851)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:278)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:680)
Caused by: java.lang.NullPointerException
    at freemarker.ext.beans.SimpleMemberModel.unwrapArguments(SimpleMemberModel.java:85)
    at freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:106)
    ... 37 more

Setting "name" and "description" without attempting to pass in "countries"
work - the values are successfully mapped.

Using the following XML works too:

<com.foo.bar.entity.Test>
<countries>
<string>SG</string>
</countries>
<description>testt</description>
</com.foo.bar.entity.Test>

Re: Struts2 REST plugin: Passing array in JSON

Posted by Shaun Lim <sh...@gmail.com>.
Hi Chris,

It's just:

Method public java.lang.String
org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
threw an exception when invoked on net.sf.json.JSONException: Error while
setting property=arrayListStr type interface java.util.List

The program crapped out in JsonLibHandler..

Shaun

On Thu, Oct 11, 2012 at 12:48 PM, Chris Pratt <th...@gmail.com>wrote:

> I was more looking for the output of all the System.out.println's
>   (*Chris*)
> On Oct 11, 2012 12:40 PM, "Shaun Lim" <sh...@gmail.com> wrote:
>
> > By the way, mapping to a simple String[] works, but I'm finding it hard
> to
> > believe that the plugin does not know how to handle conversions to List..
> >
> > On Thu, Oct 11, 2012 at 11:54 AM, Shaun Lim <sh...@gmail.com>
> > wrote:
> >
> > > Method public java.lang.String
> > >
> >
> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
> > > threw an exception when invoked on net.sf.json.JSONException: Error
> while
> > > setting property=arrayListStr type interface java.util.List
> > >
> > >
> > > On Thu, Oct 11, 2012 at 11:19 AM, Chris Pratt <thechrispratt@gmail.com
> > >wrote:
> > >
> > >> What's the output of the run with this class & JSON?
> > >>   (*Chris*)
> > >>
> > >> On Thu, Oct 11, 2012 at 10:52 AM, Shaun Lim <sh...@gmail.com>
> > >> wrote:
> > >>
> > >> > Hi Chris,
> > >> >
> > >> > I did start off with a List<String> implementation but started
> > changing
> > >> > stuff around in futile attempts to get something working. Anyway I
> > tried
> > >> > your suggestion, and am still getting the same error:
> > >> >
> > >> > //I've a whole bunch of different fields here cause i was testing
> > >> various
> > >> > things, but "arrayListStr" follows your recommendation
> > >> >
> > >> > public class Test {
> > >> >     private String name;
> > >> >     private String description;
> > >> >     private List countries;
> > >> >
> > >> >     private String[] array;
> > >> >
> > >> >     private TestChild testChild;
> > >> >     private ArrayList arrayList;
> > >> >     private List<String> arrayListStr;
> > >> >
> > >> >     public Test() {
> > >> >         arrayList = new ArrayList();
> > >> >         arrayListStr = new ArrayList<String>();
> > >> >     }
> > >> >
> > >> >     public String getName() {
> > >> >         return name;
> > >> >     }
> > >> >
> > >> >     public void setName(String name) {
> > >> >         System.out.println("setting name");
> > >> >         this.name = name;
> > >> >     }
> > >> >
> > >> >     public String getDescription() {
> > >> >         System.out.println("getting desc");
> > >> >         return description;
> > >> >     }
> > >> >
> > >> >     public void setDescription(String description) {
> > >> >         System.out.println("settings description");
> > >> >         this.description = description;
> > >> >     }
> > >> >
> > >> >     public List getCountries() {
> > >> >         return countries;
> > >> >     }
> > >> >
> > >> >     public void setCountries(List countries) {
> > >> >         System.out.println("settings countries");
> > >> >         this.countries = countries;
> > >> >     }
> > >> >
> > >> >     public TestChild getTestChild() {
> > >> >         return testChild;
> > >> >     }
> > >> >
> > >> >     public void setTestChild(TestChild testChild) {
> > >> >         System.out.println("setting testchild");
> > >> >         this.testChild = testChild;
> > >> >     }
> > >> >
> > >> >     public String[] getArray() {
> > >> >         return array;
> > >> >     }
> > >> >
> > >> >     public void setArray(String[] array) {
> > >> >         System.out.println("setting arr");
> > >> >         this.array = array;
> > >> >     }
> > >> >
> > >> >     public ArrayList getArrayList() {
> > >> >         return arrayList;
> > >> >     }
> > >> >
> > >> >     public void setArrayList(ArrayList arrayList) {
> > >> >         System.out.println("setting arrlist");
> > >> >         this.arrayList = arrayList;
> > >> >     }
> > >> >
> > >> >     public List<String> getArrayListStr() {
> > >> >         return arrayListStr;
> > >> >     }
> > >> >
> > >> >     public void setArrayListStr(List<String> arrayListStr) {
> > >> >         System.out.println("setting arrliststr");
> > >> >         this.arrayListStr = arrayListStr;
> > >> >     }
> > >> > }
> > >> >
> > >> > And the JSON:
> > >> >
> > >> > {"testChild": {"description":"kid"},"description":"whee", "name":
> > >> > "foo","array":["CA","SG"],"arrayListStr":["CA","SG"]}
> > >> >
> > >> > Thanks for your help!
> > >> >
> > >> > Shaun
> > >> >
> > >> > On Wed, Oct 10, 2012 at 11:33 PM, Chris Pratt <
> > thechrispratt@gmail.com
> > >> > >wrote:
> > >> >
> > >> > > You *might* need to initialize the countries array.  I wouldn't be
> > >> > > surprised if internally the JSON library is doing a
> > >> > > getCountries().add("CA") and throwing a null pointer exception
> > because
> > >> > > getCountries is returning a null.
> > >> > >
> > >> > > Also, you should really be programming to interfaces, not
> > >> > implementations.
> > >> > > Define your methods to take and return the List<String> interface
> > >> instead
> > >> > > of the ArrayList<String> specific implementation and your programs
> > >> will
> > >> > be
> > >> > > much more flexible and reusable in the future.  See if this works
> > >> better:
> > >> > >   (*Chris*)
> > >> > >
> > >> > > public class Test {
> > >> > >     private String name;
> > >> > >     private String description;
> > >> > >     private List<String> countries;
> > >> > >
> > >> > >     public Test() {
> > >> > >        countries = new ArrayList<>();
> > >> > >     }
> > >> > >
> > >> > >     public String getName() {
> > >> > >         return name;
> > >> > >     }
> > >> > >
> > >> > >     public void setName(String name) {
> > >> > >         this.name = name;
> > >> > >     }
> > >> > >
> > >> > >     public String getDescription() {
> > >> > >         return description;
> > >> > >     }
> > >> > >
> > >> > >     public void setDescription(String description) {
> > >> > >         this.description = description;
> > >> > >     }
> > >> > >
> > >> > >     public List<String> getCountries() {
> > >> > >         return countries;
> > >> > >     }
> > >> > >
> > >> > >     public void setCountries(List<String> countries) {
> > >> > >         this.countries = countries;
> > >> > >     }
> > >> > > }
> > >> > >
> > >> > > On Wed, Oct 10, 2012 at 11:23 PM, Shaun Lim <
> > shaunthegreat@gmail.com>
> > >> > > wrote:
> > >> > >
> > >> > > > My entity class:
> > >> > > >
> > >> > > > import java.util.ArrayList;
> > >> > > >
> > >> > > >
> > >> > > > public class Test {
> > >> > > >     private String name;
> > >> > > >     private String description;
> > >> > > >     private ArrayList<String> countries;
> > >> > > >
> > >> > > >     public Test() {
> > >> > > >
> > >> > > >     }
> > >> > > >
> > >> > > >     public String getName() {
> > >> > > >         return name;
> > >> > > >     }
> > >> > > >
> > >> > > >     public void setName(String name) {
> > >> > > >         this.name = name;
> > >> > > >     }
> > >> > > >
> > >> > > >     public String getDescription() {
> > >> > > >         return description;
> > >> > > >     }
> > >> > > >
> > >> > > >     public void setDescription(String description) {
> > >> > > >         this.description = description;
> > >> > > >     }
> > >> > > >
> > >> > > >     public ArrayList<String> getCountries() {
> > >> > > >         return countries;
> > >> > > >     }
> > >> > > >
> > >> > > >     public void setCountries(ArrayList<String> countries) {
> > >> > > >         this.countries = countries;
> > >> > > >     }
> > >> > > > }
> > >> > > >
> > >> > > > The JSON I'm trying to send:
> > >> > > >
> > >> > > > {"countries": ["CA", "SG"], "description":"whee", "name": "foo"}
> > >> > > >
> > >> > > > The error:
> > >> > > >
> > >> > > > 2345447 [http-bio-8080-exec-1] ERROR freemarker.runtime  -
> Method
> > >> > > > public java.lang.String
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
> > >> > > > threw an exception when invoked on net.sf.json.JSONException:
> > Error
> > >> > > > while setting property=countries type interface java.util.List
> > >> > > >
> > >> > > > Method public java.lang.String
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
> > >> > > > threw an exception when invoked on net.sf.json.JSONException:
> > Error
> > >> > > > while setting property=countries type interface java.util.List
> > >> > > > The problematic instruction:
> > >> > > > ----------
> > >> > > > ==> ${msgs[0][0]} [on line 76, column 25 in
> > >> > > > org/apache/struts2/dispatcher/error.ftl]
> > >> > > > ----------
> > >> > > >
> > >> > > > Java backtrace for programmers:
> > >> > > > ----------
> > >> > > > freemarker.template.TemplateModelException: Method public
> > >> > > > java.lang.String
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
> > >> > > > threw an exception when invoked on net.sf.json.JSONException:
> > Error
> > >> > > > while setting property=countries type interface java.util.List
> > >> > > >     at
> > >> > > >
> > >>
> freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:130)
> > >> > > >     at
> > >> > > >
> > >> freemarker.ext.beans.SimpleMethodModel.get(SimpleMethodModel.java:138)
> > >> > > >     at
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> freemarker.core.DynamicKeyName.dealWithNumericalKey(DynamicKeyName.java:111)
> > >> > > >     at
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> freemarker.core.DynamicKeyName._getAsTemplateModel(DynamicKeyName.java:90)
> > >> > > >     at
> > >> > freemarker.core.Expression.getAsTemplateModel(Expression.java:89)
> > >> > > >     at
> > freemarker.core.Expression.getStringValue(Expression.java:93)
> > >> > > >     at
> > freemarker.core.DollarVariable.accept(DollarVariable.java:76)
> > >> > > >     at freemarker.core.Environment.visit(Environment.java:210)
> > >> > > >     at freemarker.core.MixedContent.accept(MixedContent.java:92)
> > >> > > >     at freemarker.core.Environment.visit(Environment.java:210)
> > >> > > >     at freemarker.core.IfBlock.accept(IfBlock.java:82)
> > >> > > >     at freemarker.core.Environment.visit(Environment.java:210)
> > >> > > >     at freemarker.core.IfBlock.accept(IfBlock.java:82)
> > >> > > >     at freemarker.core.Environment.visit(Environment.java:210)
> > >> > > >     at freemarker.core.MixedContent.accept(MixedContent.java:92)
> > >> > > >     at freemarker.core.Environment.visit(Environment.java:210)
> > >> > > >     at freemarker.core.Environment.process(Environment.java:190)
> > >> > > >     at freemarker.template.Template.process(Template.java:237)
> > >> > > >     at
> > >> > > >
> > >>
> org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:797)
> > >> > > >     at
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:519)
> > >> > > >     at
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
> > >> > > >     at
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
> > >> > > >     at
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
> > >> > > >     at
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
> > >> > > >     at
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
> > >> > > >     at
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
> > >> > > >     at
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
> > >> > > >     at
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
> > >> > > >     at
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
> > >> > > >     at
> > >> > > >
> > >> >
> > >>
> > org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:851)
> > >> > > >     at
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
> > >> > > >     at
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
> > >> > > >     at
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:278)
> > >> > > >     at
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
> > >> > > >     at
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300)
> > >> > > >     at
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
> > >> > > >     at
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
> > >> > > >     at java.lang.Thread.run(Thread.java:680)
> > >> > > > Caused by: java.lang.NullPointerException
> > >> > > >     at
> > >> > > >
> > >> > >
> > >> >
> > >>
> >
> freemarker.ext.beans.SimpleMemberModel.unwrapArguments(SimpleMemberModel.java:85)
> > >> > > >     at
> > >> > > >
> > >>
> freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:106)
> > >> > > >     ... 37 more
> > >> > > >
> > >> > > > Setting "name" and "description" without attempting to pass in
> > >> > > "countries"
> > >> > > > work - the values are successfully mapped.
> > >> > > >
> > >> > > > Using the following XML works too:
> > >> > > >
> > >> > > > <com.foo.bar.entity.Test>
> > >> > > > <countries>
> > >> > > > <string>SG</string>
> > >> > > > </countries>
> > >> > > > <description>testt</description>
> > >> > > > </com.foo.bar.entity.Test>
> > >> > > >
> > >> > >
> > >> >
> > >>
> > >
> > >
> >
>

Re: Struts2 REST plugin: Passing array in JSON

Posted by Chris Pratt <th...@gmail.com>.
I was more looking for the output of all the System.out.println's
  (*Chris*)
On Oct 11, 2012 12:40 PM, "Shaun Lim" <sh...@gmail.com> wrote:

> By the way, mapping to a simple String[] works, but I'm finding it hard to
> believe that the plugin does not know how to handle conversions to List..
>
> On Thu, Oct 11, 2012 at 11:54 AM, Shaun Lim <sh...@gmail.com>
> wrote:
>
> > Method public java.lang.String
> >
> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
> > threw an exception when invoked on net.sf.json.JSONException: Error while
> > setting property=arrayListStr type interface java.util.List
> >
> >
> > On Thu, Oct 11, 2012 at 11:19 AM, Chris Pratt <thechrispratt@gmail.com
> >wrote:
> >
> >> What's the output of the run with this class & JSON?
> >>   (*Chris*)
> >>
> >> On Thu, Oct 11, 2012 at 10:52 AM, Shaun Lim <sh...@gmail.com>
> >> wrote:
> >>
> >> > Hi Chris,
> >> >
> >> > I did start off with a List<String> implementation but started
> changing
> >> > stuff around in futile attempts to get something working. Anyway I
> tried
> >> > your suggestion, and am still getting the same error:
> >> >
> >> > //I've a whole bunch of different fields here cause i was testing
> >> various
> >> > things, but "arrayListStr" follows your recommendation
> >> >
> >> > public class Test {
> >> >     private String name;
> >> >     private String description;
> >> >     private List countries;
> >> >
> >> >     private String[] array;
> >> >
> >> >     private TestChild testChild;
> >> >     private ArrayList arrayList;
> >> >     private List<String> arrayListStr;
> >> >
> >> >     public Test() {
> >> >         arrayList = new ArrayList();
> >> >         arrayListStr = new ArrayList<String>();
> >> >     }
> >> >
> >> >     public String getName() {
> >> >         return name;
> >> >     }
> >> >
> >> >     public void setName(String name) {
> >> >         System.out.println("setting name");
> >> >         this.name = name;
> >> >     }
> >> >
> >> >     public String getDescription() {
> >> >         System.out.println("getting desc");
> >> >         return description;
> >> >     }
> >> >
> >> >     public void setDescription(String description) {
> >> >         System.out.println("settings description");
> >> >         this.description = description;
> >> >     }
> >> >
> >> >     public List getCountries() {
> >> >         return countries;
> >> >     }
> >> >
> >> >     public void setCountries(List countries) {
> >> >         System.out.println("settings countries");
> >> >         this.countries = countries;
> >> >     }
> >> >
> >> >     public TestChild getTestChild() {
> >> >         return testChild;
> >> >     }
> >> >
> >> >     public void setTestChild(TestChild testChild) {
> >> >         System.out.println("setting testchild");
> >> >         this.testChild = testChild;
> >> >     }
> >> >
> >> >     public String[] getArray() {
> >> >         return array;
> >> >     }
> >> >
> >> >     public void setArray(String[] array) {
> >> >         System.out.println("setting arr");
> >> >         this.array = array;
> >> >     }
> >> >
> >> >     public ArrayList getArrayList() {
> >> >         return arrayList;
> >> >     }
> >> >
> >> >     public void setArrayList(ArrayList arrayList) {
> >> >         System.out.println("setting arrlist");
> >> >         this.arrayList = arrayList;
> >> >     }
> >> >
> >> >     public List<String> getArrayListStr() {
> >> >         return arrayListStr;
> >> >     }
> >> >
> >> >     public void setArrayListStr(List<String> arrayListStr) {
> >> >         System.out.println("setting arrliststr");
> >> >         this.arrayListStr = arrayListStr;
> >> >     }
> >> > }
> >> >
> >> > And the JSON:
> >> >
> >> > {"testChild": {"description":"kid"},"description":"whee", "name":
> >> > "foo","array":["CA","SG"],"arrayListStr":["CA","SG"]}
> >> >
> >> > Thanks for your help!
> >> >
> >> > Shaun
> >> >
> >> > On Wed, Oct 10, 2012 at 11:33 PM, Chris Pratt <
> thechrispratt@gmail.com
> >> > >wrote:
> >> >
> >> > > You *might* need to initialize the countries array.  I wouldn't be
> >> > > surprised if internally the JSON library is doing a
> >> > > getCountries().add("CA") and throwing a null pointer exception
> because
> >> > > getCountries is returning a null.
> >> > >
> >> > > Also, you should really be programming to interfaces, not
> >> > implementations.
> >> > > Define your methods to take and return the List<String> interface
> >> instead
> >> > > of the ArrayList<String> specific implementation and your programs
> >> will
> >> > be
> >> > > much more flexible and reusable in the future.  See if this works
> >> better:
> >> > >   (*Chris*)
> >> > >
> >> > > public class Test {
> >> > >     private String name;
> >> > >     private String description;
> >> > >     private List<String> countries;
> >> > >
> >> > >     public Test() {
> >> > >        countries = new ArrayList<>();
> >> > >     }
> >> > >
> >> > >     public String getName() {
> >> > >         return name;
> >> > >     }
> >> > >
> >> > >     public void setName(String name) {
> >> > >         this.name = name;
> >> > >     }
> >> > >
> >> > >     public String getDescription() {
> >> > >         return description;
> >> > >     }
> >> > >
> >> > >     public void setDescription(String description) {
> >> > >         this.description = description;
> >> > >     }
> >> > >
> >> > >     public List<String> getCountries() {
> >> > >         return countries;
> >> > >     }
> >> > >
> >> > >     public void setCountries(List<String> countries) {
> >> > >         this.countries = countries;
> >> > >     }
> >> > > }
> >> > >
> >> > > On Wed, Oct 10, 2012 at 11:23 PM, Shaun Lim <
> shaunthegreat@gmail.com>
> >> > > wrote:
> >> > >
> >> > > > My entity class:
> >> > > >
> >> > > > import java.util.ArrayList;
> >> > > >
> >> > > >
> >> > > > public class Test {
> >> > > >     private String name;
> >> > > >     private String description;
> >> > > >     private ArrayList<String> countries;
> >> > > >
> >> > > >     public Test() {
> >> > > >
> >> > > >     }
> >> > > >
> >> > > >     public String getName() {
> >> > > >         return name;
> >> > > >     }
> >> > > >
> >> > > >     public void setName(String name) {
> >> > > >         this.name = name;
> >> > > >     }
> >> > > >
> >> > > >     public String getDescription() {
> >> > > >         return description;
> >> > > >     }
> >> > > >
> >> > > >     public void setDescription(String description) {
> >> > > >         this.description = description;
> >> > > >     }
> >> > > >
> >> > > >     public ArrayList<String> getCountries() {
> >> > > >         return countries;
> >> > > >     }
> >> > > >
> >> > > >     public void setCountries(ArrayList<String> countries) {
> >> > > >         this.countries = countries;
> >> > > >     }
> >> > > > }
> >> > > >
> >> > > > The JSON I'm trying to send:
> >> > > >
> >> > > > {"countries": ["CA", "SG"], "description":"whee", "name": "foo"}
> >> > > >
> >> > > > The error:
> >> > > >
> >> > > > 2345447 [http-bio-8080-exec-1] ERROR freemarker.runtime  - Method
> >> > > > public java.lang.String
> >> > > >
> >> > >
> >> >
> >>
> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
> >> > > > threw an exception when invoked on net.sf.json.JSONException:
> Error
> >> > > > while setting property=countries type interface java.util.List
> >> > > >
> >> > > > Method public java.lang.String
> >> > > >
> >> > >
> >> >
> >>
> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
> >> > > > threw an exception when invoked on net.sf.json.JSONException:
> Error
> >> > > > while setting property=countries type interface java.util.List
> >> > > > The problematic instruction:
> >> > > > ----------
> >> > > > ==> ${msgs[0][0]} [on line 76, column 25 in
> >> > > > org/apache/struts2/dispatcher/error.ftl]
> >> > > > ----------
> >> > > >
> >> > > > Java backtrace for programmers:
> >> > > > ----------
> >> > > > freemarker.template.TemplateModelException: Method public
> >> > > > java.lang.String
> >> > > >
> >> > >
> >> >
> >>
> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
> >> > > > threw an exception when invoked on net.sf.json.JSONException:
> Error
> >> > > > while setting property=countries type interface java.util.List
> >> > > >     at
> >> > > >
> >> freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:130)
> >> > > >     at
> >> > > >
> >> freemarker.ext.beans.SimpleMethodModel.get(SimpleMethodModel.java:138)
> >> > > >     at
> >> > > >
> >> > >
> >> >
> >>
> freemarker.core.DynamicKeyName.dealWithNumericalKey(DynamicKeyName.java:111)
> >> > > >     at
> >> > > >
> >> > >
> >> >
> >>
> freemarker.core.DynamicKeyName._getAsTemplateModel(DynamicKeyName.java:90)
> >> > > >     at
> >> > freemarker.core.Expression.getAsTemplateModel(Expression.java:89)
> >> > > >     at
> freemarker.core.Expression.getStringValue(Expression.java:93)
> >> > > >     at
> freemarker.core.DollarVariable.accept(DollarVariable.java:76)
> >> > > >     at freemarker.core.Environment.visit(Environment.java:210)
> >> > > >     at freemarker.core.MixedContent.accept(MixedContent.java:92)
> >> > > >     at freemarker.core.Environment.visit(Environment.java:210)
> >> > > >     at freemarker.core.IfBlock.accept(IfBlock.java:82)
> >> > > >     at freemarker.core.Environment.visit(Environment.java:210)
> >> > > >     at freemarker.core.IfBlock.accept(IfBlock.java:82)
> >> > > >     at freemarker.core.Environment.visit(Environment.java:210)
> >> > > >     at freemarker.core.MixedContent.accept(MixedContent.java:92)
> >> > > >     at freemarker.core.Environment.visit(Environment.java:210)
> >> > > >     at freemarker.core.Environment.process(Environment.java:190)
> >> > > >     at freemarker.template.Template.process(Template.java:237)
> >> > > >     at
> >> > > >
> >> org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:797)
> >> > > >     at
> >> > > >
> >> > >
> >> >
> >>
> org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:519)
> >> > > >     at
> >> > > >
> >> > >
> >> >
> >>
> org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
> >> > > >     at
> >> > > >
> >> > >
> >> >
> >>
> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
> >> > > >     at
> >> > > >
> >> > >
> >> >
> >>
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
> >> > > >     at
> >> > > >
> >> > >
> >> >
> >>
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
> >> > > >     at
> >> > > >
> >> > >
> >> >
> >>
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
> >> > > >     at
> >> > > >
> >> > >
> >> >
> >>
> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
> >> > > >     at
> >> > > >
> >> > >
> >> >
> >>
> org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
> >> > > >     at
> >> > > >
> >> > >
> >> >
> >>
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
> >> > > >     at
> >> > > >
> >> > >
> >> >
> >>
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
> >> > > >     at
> >> > > >
> >> >
> >>
> org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:851)
> >> > > >     at
> >> > > >
> >> > >
> >> >
> >>
> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
> >> > > >     at
> >> > > >
> >> > >
> >> >
> >>
> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
> >> > > >     at
> >> > > >
> >> > >
> >> >
> >>
> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:278)
> >> > > >     at
> >> > > >
> >> > >
> >> >
> >>
> org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
> >> > > >     at
> >> > > >
> >> > >
> >> >
> >>
> org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300)
> >> > > >     at
> >> > > >
> >> > >
> >> >
> >>
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
> >> > > >     at
> >> > > >
> >> > >
> >> >
> >>
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
> >> > > >     at java.lang.Thread.run(Thread.java:680)
> >> > > > Caused by: java.lang.NullPointerException
> >> > > >     at
> >> > > >
> >> > >
> >> >
> >>
> freemarker.ext.beans.SimpleMemberModel.unwrapArguments(SimpleMemberModel.java:85)
> >> > > >     at
> >> > > >
> >> freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:106)
> >> > > >     ... 37 more
> >> > > >
> >> > > > Setting "name" and "description" without attempting to pass in
> >> > > "countries"
> >> > > > work - the values are successfully mapped.
> >> > > >
> >> > > > Using the following XML works too:
> >> > > >
> >> > > > <com.foo.bar.entity.Test>
> >> > > > <countries>
> >> > > > <string>SG</string>
> >> > > > </countries>
> >> > > > <description>testt</description>
> >> > > > </com.foo.bar.entity.Test>
> >> > > >
> >> > >
> >> >
> >>
> >
> >
>

Re: Struts2 REST plugin: Passing array in JSON

Posted by Lukasz Lenart <lu...@apache.org>.
2012/10/11 Shaun Lim <sh...@gmail.com>:
> By the way, mapping to a simple String[] works, but I'm finding it hard to
> believe that the plugin does not know how to handle conversions to List..

Could you prepare a full Maven base example ?


Thanks in advance
-- 
Ɓukasz
+ 48 606 323 122 http://www.lenart.org.pl/

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Re: Struts2 REST plugin: Passing array in JSON

Posted by Shaun Lim <sh...@gmail.com>.
By the way, mapping to a simple String[] works, but I'm finding it hard to
believe that the plugin does not know how to handle conversions to List..

On Thu, Oct 11, 2012 at 11:54 AM, Shaun Lim <sh...@gmail.com> wrote:

> Method public java.lang.String
> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
> threw an exception when invoked on net.sf.json.JSONException: Error while
> setting property=arrayListStr type interface java.util.List
>
>
> On Thu, Oct 11, 2012 at 11:19 AM, Chris Pratt <th...@gmail.com>wrote:
>
>> What's the output of the run with this class & JSON?
>>   (*Chris*)
>>
>> On Thu, Oct 11, 2012 at 10:52 AM, Shaun Lim <sh...@gmail.com>
>> wrote:
>>
>> > Hi Chris,
>> >
>> > I did start off with a List<String> implementation but started changing
>> > stuff around in futile attempts to get something working. Anyway I tried
>> > your suggestion, and am still getting the same error:
>> >
>> > //I've a whole bunch of different fields here cause i was testing
>> various
>> > things, but "arrayListStr" follows your recommendation
>> >
>> > public class Test {
>> >     private String name;
>> >     private String description;
>> >     private List countries;
>> >
>> >     private String[] array;
>> >
>> >     private TestChild testChild;
>> >     private ArrayList arrayList;
>> >     private List<String> arrayListStr;
>> >
>> >     public Test() {
>> >         arrayList = new ArrayList();
>> >         arrayListStr = new ArrayList<String>();
>> >     }
>> >
>> >     public String getName() {
>> >         return name;
>> >     }
>> >
>> >     public void setName(String name) {
>> >         System.out.println("setting name");
>> >         this.name = name;
>> >     }
>> >
>> >     public String getDescription() {
>> >         System.out.println("getting desc");
>> >         return description;
>> >     }
>> >
>> >     public void setDescription(String description) {
>> >         System.out.println("settings description");
>> >         this.description = description;
>> >     }
>> >
>> >     public List getCountries() {
>> >         return countries;
>> >     }
>> >
>> >     public void setCountries(List countries) {
>> >         System.out.println("settings countries");
>> >         this.countries = countries;
>> >     }
>> >
>> >     public TestChild getTestChild() {
>> >         return testChild;
>> >     }
>> >
>> >     public void setTestChild(TestChild testChild) {
>> >         System.out.println("setting testchild");
>> >         this.testChild = testChild;
>> >     }
>> >
>> >     public String[] getArray() {
>> >         return array;
>> >     }
>> >
>> >     public void setArray(String[] array) {
>> >         System.out.println("setting arr");
>> >         this.array = array;
>> >     }
>> >
>> >     public ArrayList getArrayList() {
>> >         return arrayList;
>> >     }
>> >
>> >     public void setArrayList(ArrayList arrayList) {
>> >         System.out.println("setting arrlist");
>> >         this.arrayList = arrayList;
>> >     }
>> >
>> >     public List<String> getArrayListStr() {
>> >         return arrayListStr;
>> >     }
>> >
>> >     public void setArrayListStr(List<String> arrayListStr) {
>> >         System.out.println("setting arrliststr");
>> >         this.arrayListStr = arrayListStr;
>> >     }
>> > }
>> >
>> > And the JSON:
>> >
>> > {"testChild": {"description":"kid"},"description":"whee", "name":
>> > "foo","array":["CA","SG"],"arrayListStr":["CA","SG"]}
>> >
>> > Thanks for your help!
>> >
>> > Shaun
>> >
>> > On Wed, Oct 10, 2012 at 11:33 PM, Chris Pratt <thechrispratt@gmail.com
>> > >wrote:
>> >
>> > > You *might* need to initialize the countries array.  I wouldn't be
>> > > surprised if internally the JSON library is doing a
>> > > getCountries().add("CA") and throwing a null pointer exception because
>> > > getCountries is returning a null.
>> > >
>> > > Also, you should really be programming to interfaces, not
>> > implementations.
>> > > Define your methods to take and return the List<String> interface
>> instead
>> > > of the ArrayList<String> specific implementation and your programs
>> will
>> > be
>> > > much more flexible and reusable in the future.  See if this works
>> better:
>> > >   (*Chris*)
>> > >
>> > > public class Test {
>> > >     private String name;
>> > >     private String description;
>> > >     private List<String> countries;
>> > >
>> > >     public Test() {
>> > >        countries = new ArrayList<>();
>> > >     }
>> > >
>> > >     public String getName() {
>> > >         return name;
>> > >     }
>> > >
>> > >     public void setName(String name) {
>> > >         this.name = name;
>> > >     }
>> > >
>> > >     public String getDescription() {
>> > >         return description;
>> > >     }
>> > >
>> > >     public void setDescription(String description) {
>> > >         this.description = description;
>> > >     }
>> > >
>> > >     public List<String> getCountries() {
>> > >         return countries;
>> > >     }
>> > >
>> > >     public void setCountries(List<String> countries) {
>> > >         this.countries = countries;
>> > >     }
>> > > }
>> > >
>> > > On Wed, Oct 10, 2012 at 11:23 PM, Shaun Lim <sh...@gmail.com>
>> > > wrote:
>> > >
>> > > > My entity class:
>> > > >
>> > > > import java.util.ArrayList;
>> > > >
>> > > >
>> > > > public class Test {
>> > > >     private String name;
>> > > >     private String description;
>> > > >     private ArrayList<String> countries;
>> > > >
>> > > >     public Test() {
>> > > >
>> > > >     }
>> > > >
>> > > >     public String getName() {
>> > > >         return name;
>> > > >     }
>> > > >
>> > > >     public void setName(String name) {
>> > > >         this.name = name;
>> > > >     }
>> > > >
>> > > >     public String getDescription() {
>> > > >         return description;
>> > > >     }
>> > > >
>> > > >     public void setDescription(String description) {
>> > > >         this.description = description;
>> > > >     }
>> > > >
>> > > >     public ArrayList<String> getCountries() {
>> > > >         return countries;
>> > > >     }
>> > > >
>> > > >     public void setCountries(ArrayList<String> countries) {
>> > > >         this.countries = countries;
>> > > >     }
>> > > > }
>> > > >
>> > > > The JSON I'm trying to send:
>> > > >
>> > > > {"countries": ["CA", "SG"], "description":"whee", "name": "foo"}
>> > > >
>> > > > The error:
>> > > >
>> > > > 2345447 [http-bio-8080-exec-1] ERROR freemarker.runtime  - Method
>> > > > public java.lang.String
>> > > >
>> > >
>> >
>> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
>> > > > threw an exception when invoked on net.sf.json.JSONException: Error
>> > > > while setting property=countries type interface java.util.List
>> > > >
>> > > > Method public java.lang.String
>> > > >
>> > >
>> >
>> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
>> > > > threw an exception when invoked on net.sf.json.JSONException: Error
>> > > > while setting property=countries type interface java.util.List
>> > > > The problematic instruction:
>> > > > ----------
>> > > > ==> ${msgs[0][0]} [on line 76, column 25 in
>> > > > org/apache/struts2/dispatcher/error.ftl]
>> > > > ----------
>> > > >
>> > > > Java backtrace for programmers:
>> > > > ----------
>> > > > freemarker.template.TemplateModelException: Method public
>> > > > java.lang.String
>> > > >
>> > >
>> >
>> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
>> > > > threw an exception when invoked on net.sf.json.JSONException: Error
>> > > > while setting property=countries type interface java.util.List
>> > > >     at
>> > > >
>> freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:130)
>> > > >     at
>> > > >
>> freemarker.ext.beans.SimpleMethodModel.get(SimpleMethodModel.java:138)
>> > > >     at
>> > > >
>> > >
>> >
>> freemarker.core.DynamicKeyName.dealWithNumericalKey(DynamicKeyName.java:111)
>> > > >     at
>> > > >
>> > >
>> >
>> freemarker.core.DynamicKeyName._getAsTemplateModel(DynamicKeyName.java:90)
>> > > >     at
>> > freemarker.core.Expression.getAsTemplateModel(Expression.java:89)
>> > > >     at freemarker.core.Expression.getStringValue(Expression.java:93)
>> > > >     at freemarker.core.DollarVariable.accept(DollarVariable.java:76)
>> > > >     at freemarker.core.Environment.visit(Environment.java:210)
>> > > >     at freemarker.core.MixedContent.accept(MixedContent.java:92)
>> > > >     at freemarker.core.Environment.visit(Environment.java:210)
>> > > >     at freemarker.core.IfBlock.accept(IfBlock.java:82)
>> > > >     at freemarker.core.Environment.visit(Environment.java:210)
>> > > >     at freemarker.core.IfBlock.accept(IfBlock.java:82)
>> > > >     at freemarker.core.Environment.visit(Environment.java:210)
>> > > >     at freemarker.core.MixedContent.accept(MixedContent.java:92)
>> > > >     at freemarker.core.Environment.visit(Environment.java:210)
>> > > >     at freemarker.core.Environment.process(Environment.java:190)
>> > > >     at freemarker.template.Template.process(Template.java:237)
>> > > >     at
>> > > >
>> org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:797)
>> > > >     at
>> > > >
>> > >
>> >
>> org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:519)
>> > > >     at
>> > > >
>> > >
>> >
>> org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
>> > > >     at
>> > > >
>> > >
>> >
>> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
>> > > >     at
>> > > >
>> > >
>> >
>> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
>> > > >     at
>> > > >
>> > >
>> >
>> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
>> > > >     at
>> > > >
>> > >
>> >
>> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
>> > > >     at
>> > > >
>> > >
>> >
>> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
>> > > >     at
>> > > >
>> > >
>> >
>> org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
>> > > >     at
>> > > >
>> > >
>> >
>> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
>> > > >     at
>> > > >
>> > >
>> >
>> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
>> > > >     at
>> > > >
>> >
>> org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:851)
>> > > >     at
>> > > >
>> > >
>> >
>> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
>> > > >     at
>> > > >
>> > >
>> >
>> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
>> > > >     at
>> > > >
>> > >
>> >
>> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:278)
>> > > >     at
>> > > >
>> > >
>> >
>> org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
>> > > >     at
>> > > >
>> > >
>> >
>> org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300)
>> > > >     at
>> > > >
>> > >
>> >
>> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
>> > > >     at
>> > > >
>> > >
>> >
>> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
>> > > >     at java.lang.Thread.run(Thread.java:680)
>> > > > Caused by: java.lang.NullPointerException
>> > > >     at
>> > > >
>> > >
>> >
>> freemarker.ext.beans.SimpleMemberModel.unwrapArguments(SimpleMemberModel.java:85)
>> > > >     at
>> > > >
>> freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:106)
>> > > >     ... 37 more
>> > > >
>> > > > Setting "name" and "description" without attempting to pass in
>> > > "countries"
>> > > > work - the values are successfully mapped.
>> > > >
>> > > > Using the following XML works too:
>> > > >
>> > > > <com.foo.bar.entity.Test>
>> > > > <countries>
>> > > > <string>SG</string>
>> > > > </countries>
>> > > > <description>testt</description>
>> > > > </com.foo.bar.entity.Test>
>> > > >
>> > >
>> >
>>
>
>

Re: Struts2 REST plugin: Passing array in JSON

Posted by Shaun Lim <sh...@gmail.com>.
Method public java.lang.String
org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
threw an exception when invoked on net.sf.json.JSONException: Error while
setting property=arrayListStr type interface java.util.List


On Thu, Oct 11, 2012 at 11:19 AM, Chris Pratt <th...@gmail.com>wrote:

> What's the output of the run with this class & JSON?
>   (*Chris*)
>
> On Thu, Oct 11, 2012 at 10:52 AM, Shaun Lim <sh...@gmail.com>
> wrote:
>
> > Hi Chris,
> >
> > I did start off with a List<String> implementation but started changing
> > stuff around in futile attempts to get something working. Anyway I tried
> > your suggestion, and am still getting the same error:
> >
> > //I've a whole bunch of different fields here cause i was testing various
> > things, but "arrayListStr" follows your recommendation
> >
> > public class Test {
> >     private String name;
> >     private String description;
> >     private List countries;
> >
> >     private String[] array;
> >
> >     private TestChild testChild;
> >     private ArrayList arrayList;
> >     private List<String> arrayListStr;
> >
> >     public Test() {
> >         arrayList = new ArrayList();
> >         arrayListStr = new ArrayList<String>();
> >     }
> >
> >     public String getName() {
> >         return name;
> >     }
> >
> >     public void setName(String name) {
> >         System.out.println("setting name");
> >         this.name = name;
> >     }
> >
> >     public String getDescription() {
> >         System.out.println("getting desc");
> >         return description;
> >     }
> >
> >     public void setDescription(String description) {
> >         System.out.println("settings description");
> >         this.description = description;
> >     }
> >
> >     public List getCountries() {
> >         return countries;
> >     }
> >
> >     public void setCountries(List countries) {
> >         System.out.println("settings countries");
> >         this.countries = countries;
> >     }
> >
> >     public TestChild getTestChild() {
> >         return testChild;
> >     }
> >
> >     public void setTestChild(TestChild testChild) {
> >         System.out.println("setting testchild");
> >         this.testChild = testChild;
> >     }
> >
> >     public String[] getArray() {
> >         return array;
> >     }
> >
> >     public void setArray(String[] array) {
> >         System.out.println("setting arr");
> >         this.array = array;
> >     }
> >
> >     public ArrayList getArrayList() {
> >         return arrayList;
> >     }
> >
> >     public void setArrayList(ArrayList arrayList) {
> >         System.out.println("setting arrlist");
> >         this.arrayList = arrayList;
> >     }
> >
> >     public List<String> getArrayListStr() {
> >         return arrayListStr;
> >     }
> >
> >     public void setArrayListStr(List<String> arrayListStr) {
> >         System.out.println("setting arrliststr");
> >         this.arrayListStr = arrayListStr;
> >     }
> > }
> >
> > And the JSON:
> >
> > {"testChild": {"description":"kid"},"description":"whee", "name":
> > "foo","array":["CA","SG"],"arrayListStr":["CA","SG"]}
> >
> > Thanks for your help!
> >
> > Shaun
> >
> > On Wed, Oct 10, 2012 at 11:33 PM, Chris Pratt <thechrispratt@gmail.com
> > >wrote:
> >
> > > You *might* need to initialize the countries array.  I wouldn't be
> > > surprised if internally the JSON library is doing a
> > > getCountries().add("CA") and throwing a null pointer exception because
> > > getCountries is returning a null.
> > >
> > > Also, you should really be programming to interfaces, not
> > implementations.
> > > Define your methods to take and return the List<String> interface
> instead
> > > of the ArrayList<String> specific implementation and your programs will
> > be
> > > much more flexible and reusable in the future.  See if this works
> better:
> > >   (*Chris*)
> > >
> > > public class Test {
> > >     private String name;
> > >     private String description;
> > >     private List<String> countries;
> > >
> > >     public Test() {
> > >        countries = new ArrayList<>();
> > >     }
> > >
> > >     public String getName() {
> > >         return name;
> > >     }
> > >
> > >     public void setName(String name) {
> > >         this.name = name;
> > >     }
> > >
> > >     public String getDescription() {
> > >         return description;
> > >     }
> > >
> > >     public void setDescription(String description) {
> > >         this.description = description;
> > >     }
> > >
> > >     public List<String> getCountries() {
> > >         return countries;
> > >     }
> > >
> > >     public void setCountries(List<String> countries) {
> > >         this.countries = countries;
> > >     }
> > > }
> > >
> > > On Wed, Oct 10, 2012 at 11:23 PM, Shaun Lim <sh...@gmail.com>
> > > wrote:
> > >
> > > > My entity class:
> > > >
> > > > import java.util.ArrayList;
> > > >
> > > >
> > > > public class Test {
> > > >     private String name;
> > > >     private String description;
> > > >     private ArrayList<String> countries;
> > > >
> > > >     public Test() {
> > > >
> > > >     }
> > > >
> > > >     public String getName() {
> > > >         return name;
> > > >     }
> > > >
> > > >     public void setName(String name) {
> > > >         this.name = name;
> > > >     }
> > > >
> > > >     public String getDescription() {
> > > >         return description;
> > > >     }
> > > >
> > > >     public void setDescription(String description) {
> > > >         this.description = description;
> > > >     }
> > > >
> > > >     public ArrayList<String> getCountries() {
> > > >         return countries;
> > > >     }
> > > >
> > > >     public void setCountries(ArrayList<String> countries) {
> > > >         this.countries = countries;
> > > >     }
> > > > }
> > > >
> > > > The JSON I'm trying to send:
> > > >
> > > > {"countries": ["CA", "SG"], "description":"whee", "name": "foo"}
> > > >
> > > > The error:
> > > >
> > > > 2345447 [http-bio-8080-exec-1] ERROR freemarker.runtime  - Method
> > > > public java.lang.String
> > > >
> > >
> >
> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
> > > > threw an exception when invoked on net.sf.json.JSONException: Error
> > > > while setting property=countries type interface java.util.List
> > > >
> > > > Method public java.lang.String
> > > >
> > >
> >
> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
> > > > threw an exception when invoked on net.sf.json.JSONException: Error
> > > > while setting property=countries type interface java.util.List
> > > > The problematic instruction:
> > > > ----------
> > > > ==> ${msgs[0][0]} [on line 76, column 25 in
> > > > org/apache/struts2/dispatcher/error.ftl]
> > > > ----------
> > > >
> > > > Java backtrace for programmers:
> > > > ----------
> > > > freemarker.template.TemplateModelException: Method public
> > > > java.lang.String
> > > >
> > >
> >
> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
> > > > threw an exception when invoked on net.sf.json.JSONException: Error
> > > > while setting property=countries type interface java.util.List
> > > >     at
> > > >
> freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:130)
> > > >     at
> > > >
> freemarker.ext.beans.SimpleMethodModel.get(SimpleMethodModel.java:138)
> > > >     at
> > > >
> > >
> >
> freemarker.core.DynamicKeyName.dealWithNumericalKey(DynamicKeyName.java:111)
> > > >     at
> > > >
> > >
> >
> freemarker.core.DynamicKeyName._getAsTemplateModel(DynamicKeyName.java:90)
> > > >     at
> > freemarker.core.Expression.getAsTemplateModel(Expression.java:89)
> > > >     at freemarker.core.Expression.getStringValue(Expression.java:93)
> > > >     at freemarker.core.DollarVariable.accept(DollarVariable.java:76)
> > > >     at freemarker.core.Environment.visit(Environment.java:210)
> > > >     at freemarker.core.MixedContent.accept(MixedContent.java:92)
> > > >     at freemarker.core.Environment.visit(Environment.java:210)
> > > >     at freemarker.core.IfBlock.accept(IfBlock.java:82)
> > > >     at freemarker.core.Environment.visit(Environment.java:210)
> > > >     at freemarker.core.IfBlock.accept(IfBlock.java:82)
> > > >     at freemarker.core.Environment.visit(Environment.java:210)
> > > >     at freemarker.core.MixedContent.accept(MixedContent.java:92)
> > > >     at freemarker.core.Environment.visit(Environment.java:210)
> > > >     at freemarker.core.Environment.process(Environment.java:190)
> > > >     at freemarker.template.Template.process(Template.java:237)
> > > >     at
> > > >
> org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:797)
> > > >     at
> > > >
> > >
> >
> org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:519)
> > > >     at
> > > >
> > >
> >
> org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
> > > >     at
> > > >
> > >
> >
> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
> > > >     at
> > > >
> > >
> >
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
> > > >     at
> > > >
> > >
> >
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
> > > >     at
> > > >
> > >
> >
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
> > > >     at
> > > >
> > >
> >
> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
> > > >     at
> > > >
> > >
> >
> org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
> > > >     at
> > > >
> > >
> >
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
> > > >     at
> > > >
> > >
> >
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
> > > >     at
> > > >
> > org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:851)
> > > >     at
> > > >
> > >
> >
> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
> > > >     at
> > > >
> > >
> >
> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
> > > >     at
> > > >
> > >
> >
> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:278)
> > > >     at
> > > >
> > >
> >
> org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
> > > >     at
> > > >
> > >
> >
> org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300)
> > > >     at
> > > >
> > >
> >
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
> > > >     at
> > > >
> > >
> >
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
> > > >     at java.lang.Thread.run(Thread.java:680)
> > > > Caused by: java.lang.NullPointerException
> > > >     at
> > > >
> > >
> >
> freemarker.ext.beans.SimpleMemberModel.unwrapArguments(SimpleMemberModel.java:85)
> > > >     at
> > > >
> freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:106)
> > > >     ... 37 more
> > > >
> > > > Setting "name" and "description" without attempting to pass in
> > > "countries"
> > > > work - the values are successfully mapped.
> > > >
> > > > Using the following XML works too:
> > > >
> > > > <com.foo.bar.entity.Test>
> > > > <countries>
> > > > <string>SG</string>
> > > > </countries>
> > > > <description>testt</description>
> > > > </com.foo.bar.entity.Test>
> > > >
> > >
> >
>

Re: Struts2 REST plugin: Passing array in JSON

Posted by Chris Pratt <th...@gmail.com>.
What's the output of the run with this class & JSON?
  (*Chris*)

On Thu, Oct 11, 2012 at 10:52 AM, Shaun Lim <sh...@gmail.com> wrote:

> Hi Chris,
>
> I did start off with a List<String> implementation but started changing
> stuff around in futile attempts to get something working. Anyway I tried
> your suggestion, and am still getting the same error:
>
> //I've a whole bunch of different fields here cause i was testing various
> things, but "arrayListStr" follows your recommendation
>
> public class Test {
>     private String name;
>     private String description;
>     private List countries;
>
>     private String[] array;
>
>     private TestChild testChild;
>     private ArrayList arrayList;
>     private List<String> arrayListStr;
>
>     public Test() {
>         arrayList = new ArrayList();
>         arrayListStr = new ArrayList<String>();
>     }
>
>     public String getName() {
>         return name;
>     }
>
>     public void setName(String name) {
>         System.out.println("setting name");
>         this.name = name;
>     }
>
>     public String getDescription() {
>         System.out.println("getting desc");
>         return description;
>     }
>
>     public void setDescription(String description) {
>         System.out.println("settings description");
>         this.description = description;
>     }
>
>     public List getCountries() {
>         return countries;
>     }
>
>     public void setCountries(List countries) {
>         System.out.println("settings countries");
>         this.countries = countries;
>     }
>
>     public TestChild getTestChild() {
>         return testChild;
>     }
>
>     public void setTestChild(TestChild testChild) {
>         System.out.println("setting testchild");
>         this.testChild = testChild;
>     }
>
>     public String[] getArray() {
>         return array;
>     }
>
>     public void setArray(String[] array) {
>         System.out.println("setting arr");
>         this.array = array;
>     }
>
>     public ArrayList getArrayList() {
>         return arrayList;
>     }
>
>     public void setArrayList(ArrayList arrayList) {
>         System.out.println("setting arrlist");
>         this.arrayList = arrayList;
>     }
>
>     public List<String> getArrayListStr() {
>         return arrayListStr;
>     }
>
>     public void setArrayListStr(List<String> arrayListStr) {
>         System.out.println("setting arrliststr");
>         this.arrayListStr = arrayListStr;
>     }
> }
>
> And the JSON:
>
> {"testChild": {"description":"kid"},"description":"whee", "name":
> "foo","array":["CA","SG"],"arrayListStr":["CA","SG"]}
>
> Thanks for your help!
>
> Shaun
>
> On Wed, Oct 10, 2012 at 11:33 PM, Chris Pratt <thechrispratt@gmail.com
> >wrote:
>
> > You *might* need to initialize the countries array.  I wouldn't be
> > surprised if internally the JSON library is doing a
> > getCountries().add("CA") and throwing a null pointer exception because
> > getCountries is returning a null.
> >
> > Also, you should really be programming to interfaces, not
> implementations.
> > Define your methods to take and return the List<String> interface instead
> > of the ArrayList<String> specific implementation and your programs will
> be
> > much more flexible and reusable in the future.  See if this works better:
> >   (*Chris*)
> >
> > public class Test {
> >     private String name;
> >     private String description;
> >     private List<String> countries;
> >
> >     public Test() {
> >        countries = new ArrayList<>();
> >     }
> >
> >     public String getName() {
> >         return name;
> >     }
> >
> >     public void setName(String name) {
> >         this.name = name;
> >     }
> >
> >     public String getDescription() {
> >         return description;
> >     }
> >
> >     public void setDescription(String description) {
> >         this.description = description;
> >     }
> >
> >     public List<String> getCountries() {
> >         return countries;
> >     }
> >
> >     public void setCountries(List<String> countries) {
> >         this.countries = countries;
> >     }
> > }
> >
> > On Wed, Oct 10, 2012 at 11:23 PM, Shaun Lim <sh...@gmail.com>
> > wrote:
> >
> > > My entity class:
> > >
> > > import java.util.ArrayList;
> > >
> > >
> > > public class Test {
> > >     private String name;
> > >     private String description;
> > >     private ArrayList<String> countries;
> > >
> > >     public Test() {
> > >
> > >     }
> > >
> > >     public String getName() {
> > >         return name;
> > >     }
> > >
> > >     public void setName(String name) {
> > >         this.name = name;
> > >     }
> > >
> > >     public String getDescription() {
> > >         return description;
> > >     }
> > >
> > >     public void setDescription(String description) {
> > >         this.description = description;
> > >     }
> > >
> > >     public ArrayList<String> getCountries() {
> > >         return countries;
> > >     }
> > >
> > >     public void setCountries(ArrayList<String> countries) {
> > >         this.countries = countries;
> > >     }
> > > }
> > >
> > > The JSON I'm trying to send:
> > >
> > > {"countries": ["CA", "SG"], "description":"whee", "name": "foo"}
> > >
> > > The error:
> > >
> > > 2345447 [http-bio-8080-exec-1] ERROR freemarker.runtime  - Method
> > > public java.lang.String
> > >
> >
> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
> > > threw an exception when invoked on net.sf.json.JSONException: Error
> > > while setting property=countries type interface java.util.List
> > >
> > > Method public java.lang.String
> > >
> >
> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
> > > threw an exception when invoked on net.sf.json.JSONException: Error
> > > while setting property=countries type interface java.util.List
> > > The problematic instruction:
> > > ----------
> > > ==> ${msgs[0][0]} [on line 76, column 25 in
> > > org/apache/struts2/dispatcher/error.ftl]
> > > ----------
> > >
> > > Java backtrace for programmers:
> > > ----------
> > > freemarker.template.TemplateModelException: Method public
> > > java.lang.String
> > >
> >
> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
> > > threw an exception when invoked on net.sf.json.JSONException: Error
> > > while setting property=countries type interface java.util.List
> > >     at
> > > freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:130)
> > >     at
> > > freemarker.ext.beans.SimpleMethodModel.get(SimpleMethodModel.java:138)
> > >     at
> > >
> >
> freemarker.core.DynamicKeyName.dealWithNumericalKey(DynamicKeyName.java:111)
> > >     at
> > >
> >
> freemarker.core.DynamicKeyName._getAsTemplateModel(DynamicKeyName.java:90)
> > >     at
> freemarker.core.Expression.getAsTemplateModel(Expression.java:89)
> > >     at freemarker.core.Expression.getStringValue(Expression.java:93)
> > >     at freemarker.core.DollarVariable.accept(DollarVariable.java:76)
> > >     at freemarker.core.Environment.visit(Environment.java:210)
> > >     at freemarker.core.MixedContent.accept(MixedContent.java:92)
> > >     at freemarker.core.Environment.visit(Environment.java:210)
> > >     at freemarker.core.IfBlock.accept(IfBlock.java:82)
> > >     at freemarker.core.Environment.visit(Environment.java:210)
> > >     at freemarker.core.IfBlock.accept(IfBlock.java:82)
> > >     at freemarker.core.Environment.visit(Environment.java:210)
> > >     at freemarker.core.MixedContent.accept(MixedContent.java:92)
> > >     at freemarker.core.Environment.visit(Environment.java:210)
> > >     at freemarker.core.Environment.process(Environment.java:190)
> > >     at freemarker.template.Template.process(Template.java:237)
> > >     at
> > > org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:797)
> > >     at
> > >
> >
> org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:519)
> > >     at
> > >
> >
> org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
> > >     at
> > >
> >
> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
> > >     at
> > >
> >
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
> > >     at
> > >
> >
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
> > >     at
> > >
> >
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
> > >     at
> > >
> >
> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
> > >     at
> > >
> >
> org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
> > >     at
> > >
> >
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
> > >     at
> > >
> >
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
> > >     at
> > >
> org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:851)
> > >     at
> > >
> >
> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
> > >     at
> > >
> >
> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
> > >     at
> > >
> >
> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:278)
> > >     at
> > >
> >
> org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
> > >     at
> > >
> >
> org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300)
> > >     at
> > >
> >
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
> > >     at
> > >
> >
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
> > >     at java.lang.Thread.run(Thread.java:680)
> > > Caused by: java.lang.NullPointerException
> > >     at
> > >
> >
> freemarker.ext.beans.SimpleMemberModel.unwrapArguments(SimpleMemberModel.java:85)
> > >     at
> > > freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:106)
> > >     ... 37 more
> > >
> > > Setting "name" and "description" without attempting to pass in
> > "countries"
> > > work - the values are successfully mapped.
> > >
> > > Using the following XML works too:
> > >
> > > <com.foo.bar.entity.Test>
> > > <countries>
> > > <string>SG</string>
> > > </countries>
> > > <description>testt</description>
> > > </com.foo.bar.entity.Test>
> > >
> >
>

Re: Struts2 REST plugin: Passing array in JSON

Posted by Shaun Lim <sh...@gmail.com>.
Hi Chris,

I did start off with a List<String> implementation but started changing
stuff around in futile attempts to get something working. Anyway I tried
your suggestion, and am still getting the same error:

//I've a whole bunch of different fields here cause i was testing various
things, but "arrayListStr" follows your recommendation

public class Test {
    private String name;
    private String description;
    private List countries;

    private String[] array;

    private TestChild testChild;
    private ArrayList arrayList;
    private List<String> arrayListStr;

    public Test() {
        arrayList = new ArrayList();
        arrayListStr = new ArrayList<String>();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("setting name");
        this.name = name;
    }

    public String getDescription() {
        System.out.println("getting desc");
        return description;
    }

    public void setDescription(String description) {
        System.out.println("settings description");
        this.description = description;
    }

    public List getCountries() {
        return countries;
    }

    public void setCountries(List countries) {
        System.out.println("settings countries");
        this.countries = countries;
    }

    public TestChild getTestChild() {
        return testChild;
    }

    public void setTestChild(TestChild testChild) {
        System.out.println("setting testchild");
        this.testChild = testChild;
    }

    public String[] getArray() {
        return array;
    }

    public void setArray(String[] array) {
        System.out.println("setting arr");
        this.array = array;
    }

    public ArrayList getArrayList() {
        return arrayList;
    }

    public void setArrayList(ArrayList arrayList) {
        System.out.println("setting arrlist");
        this.arrayList = arrayList;
    }

    public List<String> getArrayListStr() {
        return arrayListStr;
    }

    public void setArrayListStr(List<String> arrayListStr) {
        System.out.println("setting arrliststr");
        this.arrayListStr = arrayListStr;
    }
}

And the JSON:

{"testChild": {"description":"kid"},"description":"whee", "name":
"foo","array":["CA","SG"],"arrayListStr":["CA","SG"]}

Thanks for your help!

Shaun

On Wed, Oct 10, 2012 at 11:33 PM, Chris Pratt <th...@gmail.com>wrote:

> You *might* need to initialize the countries array.  I wouldn't be
> surprised if internally the JSON library is doing a
> getCountries().add("CA") and throwing a null pointer exception because
> getCountries is returning a null.
>
> Also, you should really be programming to interfaces, not implementations.
> Define your methods to take and return the List<String> interface instead
> of the ArrayList<String> specific implementation and your programs will be
> much more flexible and reusable in the future.  See if this works better:
>   (*Chris*)
>
> public class Test {
>     private String name;
>     private String description;
>     private List<String> countries;
>
>     public Test() {
>        countries = new ArrayList<>();
>     }
>
>     public String getName() {
>         return name;
>     }
>
>     public void setName(String name) {
>         this.name = name;
>     }
>
>     public String getDescription() {
>         return description;
>     }
>
>     public void setDescription(String description) {
>         this.description = description;
>     }
>
>     public List<String> getCountries() {
>         return countries;
>     }
>
>     public void setCountries(List<String> countries) {
>         this.countries = countries;
>     }
> }
>
> On Wed, Oct 10, 2012 at 11:23 PM, Shaun Lim <sh...@gmail.com>
> wrote:
>
> > My entity class:
> >
> > import java.util.ArrayList;
> >
> >
> > public class Test {
> >     private String name;
> >     private String description;
> >     private ArrayList<String> countries;
> >
> >     public Test() {
> >
> >     }
> >
> >     public String getName() {
> >         return name;
> >     }
> >
> >     public void setName(String name) {
> >         this.name = name;
> >     }
> >
> >     public String getDescription() {
> >         return description;
> >     }
> >
> >     public void setDescription(String description) {
> >         this.description = description;
> >     }
> >
> >     public ArrayList<String> getCountries() {
> >         return countries;
> >     }
> >
> >     public void setCountries(ArrayList<String> countries) {
> >         this.countries = countries;
> >     }
> > }
> >
> > The JSON I'm trying to send:
> >
> > {"countries": ["CA", "SG"], "description":"whee", "name": "foo"}
> >
> > The error:
> >
> > 2345447 [http-bio-8080-exec-1] ERROR freemarker.runtime  - Method
> > public java.lang.String
> >
> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
> > threw an exception when invoked on net.sf.json.JSONException: Error
> > while setting property=countries type interface java.util.List
> >
> > Method public java.lang.String
> >
> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
> > threw an exception when invoked on net.sf.json.JSONException: Error
> > while setting property=countries type interface java.util.List
> > The problematic instruction:
> > ----------
> > ==> ${msgs[0][0]} [on line 76, column 25 in
> > org/apache/struts2/dispatcher/error.ftl]
> > ----------
> >
> > Java backtrace for programmers:
> > ----------
> > freemarker.template.TemplateModelException: Method public
> > java.lang.String
> >
> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
> > threw an exception when invoked on net.sf.json.JSONException: Error
> > while setting property=countries type interface java.util.List
> >     at
> > freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:130)
> >     at
> > freemarker.ext.beans.SimpleMethodModel.get(SimpleMethodModel.java:138)
> >     at
> >
> freemarker.core.DynamicKeyName.dealWithNumericalKey(DynamicKeyName.java:111)
> >     at
> >
> freemarker.core.DynamicKeyName._getAsTemplateModel(DynamicKeyName.java:90)
> >     at freemarker.core.Expression.getAsTemplateModel(Expression.java:89)
> >     at freemarker.core.Expression.getStringValue(Expression.java:93)
> >     at freemarker.core.DollarVariable.accept(DollarVariable.java:76)
> >     at freemarker.core.Environment.visit(Environment.java:210)
> >     at freemarker.core.MixedContent.accept(MixedContent.java:92)
> >     at freemarker.core.Environment.visit(Environment.java:210)
> >     at freemarker.core.IfBlock.accept(IfBlock.java:82)
> >     at freemarker.core.Environment.visit(Environment.java:210)
> >     at freemarker.core.IfBlock.accept(IfBlock.java:82)
> >     at freemarker.core.Environment.visit(Environment.java:210)
> >     at freemarker.core.MixedContent.accept(MixedContent.java:92)
> >     at freemarker.core.Environment.visit(Environment.java:210)
> >     at freemarker.core.Environment.process(Environment.java:190)
> >     at freemarker.template.Template.process(Template.java:237)
> >     at
> > org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:797)
> >     at
> >
> org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:519)
> >     at
> >
> org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
> >     at
> >
> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
> >     at
> >
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
> >     at
> >
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
> >     at
> >
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
> >     at
> >
> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
> >     at
> >
> org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
> >     at
> >
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
> >     at
> >
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
> >     at
> > org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:851)
> >     at
> >
> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
> >     at
> >
> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
> >     at
> >
> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:278)
> >     at
> >
> org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
> >     at
> >
> org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300)
> >     at
> >
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
> >     at
> >
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
> >     at java.lang.Thread.run(Thread.java:680)
> > Caused by: java.lang.NullPointerException
> >     at
> >
> freemarker.ext.beans.SimpleMemberModel.unwrapArguments(SimpleMemberModel.java:85)
> >     at
> > freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:106)
> >     ... 37 more
> >
> > Setting "name" and "description" without attempting to pass in
> "countries"
> > work - the values are successfully mapped.
> >
> > Using the following XML works too:
> >
> > <com.foo.bar.entity.Test>
> > <countries>
> > <string>SG</string>
> > </countries>
> > <description>testt</description>
> > </com.foo.bar.entity.Test>
> >
>

Re: Struts2 REST plugin: Passing array in JSON

Posted by Chris Pratt <th...@gmail.com>.
You *might* need to initialize the countries array.  I wouldn't be
surprised if internally the JSON library is doing a
getCountries().add("CA") and throwing a null pointer exception because
getCountries is returning a null.

Also, you should really be programming to interfaces, not implementations.
Define your methods to take and return the List<String> interface instead
of the ArrayList<String> specific implementation and your programs will be
much more flexible and reusable in the future.  See if this works better:
  (*Chris*)

public class Test {
    private String name;
    private String description;
    private List<String> countries;

    public Test() {
       countries = new ArrayList<>();
    }

    public String getName() {
        return name;
    }

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

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public List<String> getCountries() {
        return countries;
    }

    public void setCountries(List<String> countries) {
        this.countries = countries;
    }
}

On Wed, Oct 10, 2012 at 11:23 PM, Shaun Lim <sh...@gmail.com> wrote:

> My entity class:
>
> import java.util.ArrayList;
>
>
> public class Test {
>     private String name;
>     private String description;
>     private ArrayList<String> countries;
>
>     public Test() {
>
>     }
>
>     public String getName() {
>         return name;
>     }
>
>     public void setName(String name) {
>         this.name = name;
>     }
>
>     public String getDescription() {
>         return description;
>     }
>
>     public void setDescription(String description) {
>         this.description = description;
>     }
>
>     public ArrayList<String> getCountries() {
>         return countries;
>     }
>
>     public void setCountries(ArrayList<String> countries) {
>         this.countries = countries;
>     }
> }
>
> The JSON I'm trying to send:
>
> {"countries": ["CA", "SG"], "description":"whee", "name": "foo"}
>
> The error:
>
> 2345447 [http-bio-8080-exec-1] ERROR freemarker.runtime  - Method
> public java.lang.String
> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
> threw an exception when invoked on net.sf.json.JSONException: Error
> while setting property=countries type interface java.util.List
>
> Method public java.lang.String
> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
> threw an exception when invoked on net.sf.json.JSONException: Error
> while setting property=countries type interface java.util.List
> The problematic instruction:
> ----------
> ==> ${msgs[0][0]} [on line 76, column 25 in
> org/apache/struts2/dispatcher/error.ftl]
> ----------
>
> Java backtrace for programmers:
> ----------
> freemarker.template.TemplateModelException: Method public
> java.lang.String
> org.apache.commons.lang.exception.NestableRuntimeException.getMessage(int)
> threw an exception when invoked on net.sf.json.JSONException: Error
> while setting property=countries type interface java.util.List
>     at
> freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:130)
>     at
> freemarker.ext.beans.SimpleMethodModel.get(SimpleMethodModel.java:138)
>     at
> freemarker.core.DynamicKeyName.dealWithNumericalKey(DynamicKeyName.java:111)
>     at
> freemarker.core.DynamicKeyName._getAsTemplateModel(DynamicKeyName.java:90)
>     at freemarker.core.Expression.getAsTemplateModel(Expression.java:89)
>     at freemarker.core.Expression.getStringValue(Expression.java:93)
>     at freemarker.core.DollarVariable.accept(DollarVariable.java:76)
>     at freemarker.core.Environment.visit(Environment.java:210)
>     at freemarker.core.MixedContent.accept(MixedContent.java:92)
>     at freemarker.core.Environment.visit(Environment.java:210)
>     at freemarker.core.IfBlock.accept(IfBlock.java:82)
>     at freemarker.core.Environment.visit(Environment.java:210)
>     at freemarker.core.IfBlock.accept(IfBlock.java:82)
>     at freemarker.core.Environment.visit(Environment.java:210)
>     at freemarker.core.MixedContent.accept(MixedContent.java:92)
>     at freemarker.core.Environment.visit(Environment.java:210)
>     at freemarker.core.Environment.process(Environment.java:190)
>     at freemarker.template.Template.process(Template.java:237)
>     at
> org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:797)
>     at
> org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:519)
>     at
> org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
>     at
> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:91)
>     at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
>     at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
>     at
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
>     at
> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
>     at
> org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
>     at
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
>     at
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
>     at
> org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:851)
>     at
> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
>     at
> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
>     at
> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:278)
>     at
> org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
>     at
> org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300)
>     at
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
>     at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
>     at java.lang.Thread.run(Thread.java:680)
> Caused by: java.lang.NullPointerException
>     at
> freemarker.ext.beans.SimpleMemberModel.unwrapArguments(SimpleMemberModel.java:85)
>     at
> freemarker.ext.beans.SimpleMethodModel.exec(SimpleMethodModel.java:106)
>     ... 37 more
>
> Setting "name" and "description" without attempting to pass in "countries"
> work - the values are successfully mapped.
>
> Using the following XML works too:
>
> <com.foo.bar.entity.Test>
> <countries>
> <string>SG</string>
> </countries>
> <description>testt</description>
> </com.foo.bar.entity.Test>
>