Hi

There're few issues which interfere at the moment.
First one is not actually an issue in the JAX-RS sense : JAX-RS resource
methods can only handle a single parameter which is not annotated with JAXRS
annotations like @PathParam/etc. Thus you see add() working but multiple()
not.

Another issue is that JSONProvider can not deserialize explicit collections
at the moment, like
{ "x":20, "y":10 }, thus converting

CalculatorResponse multiply( double x, double y );

to 

CalculatorResponse multiply( double[] args);

would not work and would be probably wrong (require extra checks like length
equals to 2, etc).

so if you do POST 

{ "x":20, "y":10 }

then I'd recommend introduce a hierarchy like

@XmlRootElement("bean")
class AbstractOpBean {

protected double x;
protected double y;

}

class MultiplyOpBean extends AbstractOpBean {

    public doable multiply() {return x * y; }
}

and then just do 


CalculatorResponse multiply(MultipleOpBean op) {
   CalculatorResponse response = new CalculatorResponse();
   response.setValue(op.multiply(););
}

perhaps you can have an abstract calculate() method on the Abstract bean
instead and then delegate in all the cases to a helper function.

The only remaining thing then would be to explicitly configure a
JSONProvider with a 'wrapperName' property being set to 'bean' so that a
sequence like

{ "x":20, "y":10 }

could be deserialized into MultiplyOpBean. Now, as far as JAXB annotations
are concerned you may want to have @XmlRootElement on MultiplyOpBean instead
otherwise you would also likely need to add @XmlSeeAlso to AbstractBeanOp...
 
hope it helps
Sergey


Javier Delgadillo wrote:
> 
> I'm hoping someone on this list can help me figuring out what I'm missing. 
> I'm trying to write a CXF/Spring/JAX-RS webapp that uses JSON for both
> inputs and outputs.  I've got a simple ICalculator interface with the
> standard add/subtract/multiply/divide methods.  add/subtract are working
> used @PathParm and @QueryParam annotations and return valid JSON responses
> for the CalculatorResponse class.  I've been trying to get multiply (or
> divide) to work by posting a JSON string that has the parameters.  In
> essence, I'd like the following request to parse and pass parameters
> appropriately:
> 
> POST /calculator/multiply HTTP/1.1
> Accept: */*
> Accept-Language: en-us
> Referer: http://server/jaxrstest/calc.html
> x-requested-with: XMLHttpRequest
> Content-Type: application/json
> Accept-Encoding: gzip, deflate
> User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR
> 1.1.4322; .NET CLR 2.0.50727; InfoPath.2; .NET CLR 3.0.4506.2152; .NET CLR
> 3.5.30729)
> Host: server:80
> Content-Length: 18
> Connection: Keep-Alive
> Pragma: no-cache
> 
> { "x":20, "y":10 }
> 
> 
> But CXF always complains because the parser for the input isn't parsing
> JSON.  It sees the '{' character and throws an exception because it was
> expecting a number.  I've searched google and the cxf-users list but
> haven't found an example that tells me how to configure CXF to parse the
> JSON string.  Has anyone tried doing this?  I'm hoping I just missed a
> setting in the Spring Config files.
> 
> Using cxf-bundle-jaxrs 2.2.2, spring 2.5.6
> 
> Relevant code/config files below:
> 
> 
> @XmlRootElement( name="CalculatorResponse" )
> 
> public class CalculatorResponse
> 
> {
> 
>     double m_value;
> 
> 
> 
>     // Default Constructor
> 
>     public CalculatorResponse()
> 
>     {
> 
>     }
> 
> 
> 
>     public void setValue( double value )
> 
>     {
> 
>         m_value = value;
> 
>     }
> 
> 
> 
>     public double getValue()
> 
>     {
> 
>         return m_value;
> 
>     }
> 
> }
> 
> 
> @Path("/calculator/")
> @Consumes("application/json")
> @Produces("application/json")
> public interface ICalculator
> {
>     /**
>      * This will be accessible via /calculator/1/2
>      * @param x value for x
>      * @param y value for y
>      * @return CalculatorResponse
>      */
>     @GET
>     @Path("/add/{x}/{y}")
>     CalculatorResponse add( @PathParam( "x" )long x, @PathParam( "y" )long
> y );
> 
>     /**
>      * The parameters here will be passed like typical URL params
>      * /calculator/subtract?x=10.0&y=5.0
>      * @param x Value for X
>      * @param y Value for Y
>      * @return CalculatorResponse
>      */
>     @GET
>     @POST
>     @Path("subtract")
>     CalculatorResponse subtract( @QueryParam( "x" ) double x, @QueryParam(
> "y" ) double y );
> 
>     @POST
>     @Path("divide")
>     CalculatorResponse divide( double x, double y );
> 
>     @POST
>     @Path("multiply")
>     CalculatorResponse multiply( double x, double y );
> }
> 
> 
> public class CalculatorImpl implements ICalculator
> 
> {
> 
>     // Default Constructor
> 
>     public CalculatorImpl()
> 
>     {
> 
>     }
> 
> 
> 
>     public CalculatorResponse add( long x, long y)
> 
>     {
> 
>         CalculatorResponse response = new CalculatorResponse();
> 
>         response.setValue( x+y );
> 
>         return response;
> 
>     }
> 
> 
> 
> 
> 
>     public CalculatorResponse subtract( double x, double y)
> 
>     {
> 
>         CalculatorResponse response = new CalculatorResponse();
> 
>         response.setValue( x-y );
> 
>         return response;
> 
>     }
> 
> 
> 
>     public CalculatorResponse divide( double x, double y)
> 
>     {
> 
>         CalculatorResponse response = new CalculatorResponse();
> 
>         response.setValue( x/y );
> 
>         return response;
> 
>     }
> 
> 
> 
>     public CalculatorResponse multiply( double x, double y)
> 
>     {
> 
>         CalculatorResponse response = new CalculatorResponse();
> 
>         response.setValue( x*y );
> 
>         return response;
> 
>     }
> 
> }
> 
> 
> 
> <?xml version="1.0" encoding="UTF-8"?>
> 
> <beans xmlns="http://www.springframework.org/schema/beans";
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
> 
>     xmlns:jaxrs="http://cxf.apache.org/jaxrs";
> 
>     xmlns:util="http://www.springframework.org/schema/util";
> 
>     xsi:schemaLocation="
> 
> http://www.springframework.org/schema/beans
> 
> http://www.springframework.org/schema/beans/spring-beans.xsd
> 
> http://cxf.apache.org/jaxrs
> 
> http://cxf.apache.org/schemas/jaxrs.xsd
> 
> http://www.springframework.org/schema/util
> http://www.springframework.org/schema/util/spring-util-2.0.xsd";
> 
> 
> 
>     default-lazy-init="false">
> 
> 
> 
>     <import resource="classpath:META-INF/cxf/cxf.xml" />
> 
>     <import
> resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml" />
> 
>     <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
> 
> 
> 
>     <util:map id="jsonNamespaceMap" map-class="java.util.Hashtable">
> 
>         <entry key="http://databasin.org/"; value="b"/>
> 
>         <entry key="http://cxf.apache.org/bindings/xformat"; value="cxf" />
> 
>     </util:map>
> 
> 
> 
>     <bean id="jsonProvider"
> class="org.apache.cxf.jaxrs.provider.JSONProvider">
> 
>         <property name="namespaceMap" ref="jsonNamespaceMap"/>
> 
>     </bean>
> 
> 
> 
>     <bean id="calculatorBean"
> class="com.esri.solutions.databasin.impl.CalculatorImpl" />
> 
> 
> 
>     <jaxrs:server id="myService" address="/">
> 
>         <jaxrs:serviceBeans>
> 
>             <ref bean="calculatorBean" />
> 
>         </jaxrs:serviceBeans>
> 
>         <jaxrs:providers>
> 
>             <ref bean="jsonProvider" />
> 
>         </jaxrs:providers>
> 
>     </jaxrs:server>
> 
> </beans>
> 
> 
> 
> ---
> Javier Delgadillo
> ESRI / Implementation Services
> http://www.arcwebservices.com/
> (909) 793-2853 x1068
> 
> 
> 

-- 
View this message in context: 
http://www.nabble.com/Spring%2C-CXF%2C-JAX-RS%2C-JSON-tp25066939p25079830.html
Sent from the cxf-user mailing list archive at Nabble.com.

Reply via email to