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.