0

I have CXF rest service and passing amounts and dates in MyRequest. I somebody passess 'abc' in amount or 'abc' in mydate then some internal cxf exceptions occurs. I want to have my own classes validating values of amount and mydate and throw my custom exceptions. Is it possible? I know that in webservices there are some datatype adapters but in REST i cant see any examples on CXF documentation.

  @POST
    @Path( "/myMethod" )
    void myMethod(MyRequest request);

MyRequest{
private BigDecimal amount;
private Date mydate;

//getters and setters
}
michealAtmi
  • 1,012
  • 2
  • 14
  • 36

2 Answers2

0

As you don't use any other frameworks, you will do the conversion/validation step by hand. What I normally do is to accept such arguments as String as every input and output are initially strings. Later I try to convert them into the objects that I need. So I propose the following:

MyRequest{
    private String amount;
    private String mydate;

    //getters and setters
}

And in the controller:

void myMethod(MyRequest request)
{
    try
    {
        BigDecimal bigDecimalAmount = BigDecimal.valueOf(Long.parseLong(request.getAmount()));
    }
    catch(Exception exception
    {
        // handle exception
    }
}

Further if you use a framework like Spring, you may want to look at how custom validators can be implemented.

actc
  • 672
  • 1
  • 9
  • 23
  • I use cxf and I cant change api, I need an answer specific to cxf / jaxrs – michealAtmi Dec 20 '16 at 16:39
  • I meant that you might use some more frameworks. You don't have to.Spring e.g. would try to convert these arguments into the corresponding classes. – actc Dec 20 '16 at 16:40
0

You have some alternatives:

1- If you have an XML schema you can use JAXB validation with a custom MessageBodyReader. See Validate JAXBElement in JPA/JAX-RS Web Service

2- You can use JAXB XMLAdapter to customize how a data type is read and mapped to an object. See How do you specify the date format used when JAXB marshals xsd:dateTime?

You have to annotate the properties

@XmlRootElement
 public class MyRequest{

     @XmlElement(name = "mydate", required = true) 
     @XmlJavaTypeAdapter(DateAdapter.class)
     protected Date mydate; 

And define the XmlAdapter

public class DateAdapter extends XmlAdapter<String, Date> {

    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public String marshal(Date v) throws Exception {
        synchronized (dateFormat) {
            return dateFormat.format(v);
        }
    }

    @Override
    public Date unmarshal(String v) throws Exception {
        synchronized (dateFormat) {
            return dateFormat.parse(v);
        }
    }

This solution is applicable to XML data and also to JSON using Jackson mapper because some of the JAXB annotations are supported deserializing data. See http://wiki.fasterxml.com/JacksonJAXBAnnotations

To configure jackson with jaxb provider in CXF see https://cxf.apache.org/docs/jax-rs-data-bindings.html#JAX-RSDataBindings-Jackson

 <jaxrs:providers>
      <bean class="org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider"/>
 </jaxrs:providers>
Community
  • 1
  • 1
pedrofb
  • 37,271
  • 5
  • 94
  • 142