Discussion:
Intercept 400 response generation when Jersey detects bad xml?
Mike Summers
2012-01-24 19:58:03 UTC
Permalink
I'm writing a test server that needs to emulate a 3rd party RESTful server,
I'm using Jersey to write the test server.

All of the requests are POST with application/xml payloads so I started off
with:

@Path("GetUserDetails")
@POST
@Consumes(MediaType.APPLICATION_XML)
public GetUserDetailsResp GetUserDetails(GetUserDetailsReq request) {
...
}

Jersey happily returns 400 when the XML is badly formatted
(GetUserDetailsReq is a JAXB object), which is not what I need. Rather I
need to return 200 and an XML error block.

I can get around the 400 by unmarshaling in the method and using an
@Provider/ExceptionMapper class, but that's clunky. Is there a declarative
way to specify to Jersey an alternative to returning the 400? Maybe a
variant on @Provider/ExceptionMapper?

TIA.
Pavel Bucek
2012-01-26 15:48:57 UTC
Permalink
Hello Mike,

you should be able to implement ExceptionMapper for
WebApplicationException (which is thrown in this case) and construct
your response.

Regards,
Pavel
Post by Mike Summers
I'm writing a test server that needs to emulate a 3rd party RESTful
server, I'm using Jersey to write the test server.
All of the requests are POST with application/xml payloads so I
@Path("GetUserDetails")
@POST
@Consumes(MediaType.APPLICATION_XML)
public GetUserDetailsResp GetUserDetails(GetUserDetailsReq request) {
...
}
Jersey happily returns 400 when the XML is badly formatted
(GetUserDetailsReq is a JAXB object), which is not what I need. Rather
I need to return 200 and an XML error block.
I can get around the 400 by unmarshaling in the method and using an
@Provider/ExceptionMapper class, but that's clunky. Is there
a declarative way to specify to Jersey an alternative to returning the
TIA.
Mike Summers
2012-01-26 16:02:18 UTC
Permalink
Hi Pavel.

The exception wrapper works if I unmarshal inside the method, something
like this:
@Path("GetUserDetails")
@POST
public GetUserDetailsResp GetUserDetails(String r) throws JAXBException{
GetUserDetailsReq request = new JaxbHelper().unsafeUnmarshall(new
GetUserDetailsReq(), r);

However if I let Jersey unmarshal as part of the method signature the
wrapper is not invoked, this does not work:
@Path("GetUserDetails")
@POST
@Consumes(MediaType.APPLICATION_XML)
public GetUserDetailsResp GetUserDetails(GetUserDetailsReq request) {

Is that as expected/by design? My wrapper looks like:
public class MalformedXMLException implements
ExceptionMapper<JAXBException> {
public Response toResponse(JAXBException e) {

I also tried mapping ParamException but it didn't make any difference.
Jersey 1.3 btw.

Thanks for the feedback-- Mike
Post by Pavel Bucek
Hello Mike,
you should be able to implement ExceptionMapper for
WebApplicationException (which is thrown in this case) and construct your
response.
Regards,
Pavel
Post by Mike Summers
I'm writing a test server that needs to emulate a 3rd party RESTful
server, I'm using Jersey to write the test server.
All of the requests are POST with application/xml payloads so I started
@Path("GetUserDetails")
@POST
@Consumes(MediaType.**APPLICATION_XML)
public GetUserDetailsResp GetUserDetails(**GetUserDetailsReq
request) {
...
}
Jersey happily returns 400 when the XML is badly formatted
(GetUserDetailsReq is a JAXB object), which is not what I need. Rather I
need to return 200 and an XML error block.
I can get around the 400 by unmarshaling in the method and using an
@Provider/ExceptionMapper class, but that's clunky. Is there a declarative
way to specify to Jersey an alternative to returning the 400? Maybe a
TIA.
Pavel Bucek
2012-01-26 16:07:23 UTC
Permalink
JAXBException is wrapped in WebApplicationException - you would need to
have something like

public class MalformedXMLException implements
ExceptionMapper<*WebApplicationExpception*>

please let me know whether that works.

Pavel
Post by Mike Summers
Hi Pavel.
The exception wrapper works if I unmarshal inside the method,
@Path("GetUserDetails")
@POST
public GetUserDetailsResp GetUserDetails(String r) throws JAXBException{
GetUserDetailsReq request = new JaxbHelper().unsafeUnmarshall(new
GetUserDetailsReq(), r);
However if I let Jersey unmarshal as part of the method signature the
@Path("GetUserDetails")
@POST
@Consumes(MediaType.APPLICATION_XML)
public GetUserDetailsResp GetUserDetails(GetUserDetailsReq request) {
public class MalformedXMLException implements
ExceptionMapper<JAXBException> {
public Response toResponse(JAXBException e) {
I also tried mapping ParamException but it didn't make any difference.
Jersey 1.3 btw.
Thanks for the feedback-- Mike
Hello Mike,
you should be able to implement ExceptionMapper for
WebApplicationException (which is thrown in this case) and
construct your response.
Regards,
Pavel
I'm writing a test server that needs to emulate a 3rd party
RESTful server, I'm using Jersey to write the test server.
All of the requests are POST with application/xml payloads so
@Path("GetUserDetails")
@POST
@Consumes(MediaType.APPLICATION_XML)
public GetUserDetailsResp
GetUserDetails(GetUserDetailsReq request) {
...
}
Jersey happily returns 400 when the XML is badly formatted
(GetUserDetailsReq is a JAXB object), which is not what I
need. Rather I need to return 200 and an XML error block.
I can get around the 400 by unmarshaling in the method and
Is there a declarative way to specify to Jersey an alternative
to returning the 400? Maybe a variant on
@Provider/ExceptionMapper?
TIA.
Mike Summers
2012-01-26 16:21:03 UTC
Permalink
Aha, that worked.

Thanks!
Post by Pavel Bucek
JAXBException is wrapped in WebApplicationException - you would need to
have something like
public class MalformedXMLException implements ExceptionMapper<*
WebApplicationExpception*>
please let me know whether that works.
Pavel
Hi Pavel.
The exception wrapper works if I unmarshal inside the method, something
@Path("GetUserDetails")
@POST
public GetUserDetailsResp GetUserDetails(String r) throws JAXBException{
GetUserDetailsReq request = new JaxbHelper().unsafeUnmarshall(new
GetUserDetailsReq(), r);
However if I let Jersey unmarshal as part of the method signature the
@Path("GetUserDetails")
@POST
@Consumes(MediaType.APPLICATION_XML)
public GetUserDetailsResp GetUserDetails(GetUserDetailsReq request) {
public class MalformedXMLException implements
ExceptionMapper<JAXBException> {
public Response toResponse(JAXBException e) {
I also tried mapping ParamException but it didn't make any difference.
Jersey 1.3 btw.
Thanks for the feedback-- Mike
Post by Pavel Bucek
Hello Mike,
you should be able to implement ExceptionMapper for
WebApplicationException (which is thrown in this case) and construct your
response.
Regards,
Pavel
Post by Mike Summers
I'm writing a test server that needs to emulate a 3rd party RESTful
server, I'm using Jersey to write the test server.
All of the requests are POST with application/xml payloads so I started
@Path("GetUserDetails")
@POST
@Consumes(MediaType.APPLICATION_XML)
public GetUserDetailsResp GetUserDetails(GetUserDetailsReq request) {
...
}
Jersey happily returns 400 when the XML is badly formatted
(GetUserDetailsReq is a JAXB object), which is not what I need. Rather I
need to return 200 and an XML error block.
I can get around the 400 by unmarshaling in the method and using an
@Provider/ExceptionMapper class, but that's clunky. Is there a declarative
way to specify to Jersey an alternative to returning the 400? Maybe a
TIA.
Loading...