public Class Offer {
String name;
@NotNull
String id;
Date start;
Date end;
//getters and setters
}
@POST
@Consumes(APPLICATION_JSON)
@Produces({APPLICATION_JSON})
@Path("/offers")
public Response createOffer(@Valid Offer offer) {
//blah
}
My input is something like this:
{"id" : "someId"
}
This gives a http 400 Bad request back from Jetty, whereas I expect something like 422 Unprocessable entity - name cannot be null
What could I be doing wrong?
On Dropwizard 0.8.1
It looks like only id is annotated with not null, and your request has that set. Why would it complain about name?
--
You received this message because you are subscribed to the Google Groups "dropwizard-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dropwizard-us...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
public class Offer {
@JsonProperty
private String name;
@JsonProperty
private String id;
public String getName() {
return name;
}
public String getId() {
return id;
}
}public class Offer {
private String id;
@NotEmpty
private String name;
@JsonSerialize(using = APIDateFormatSerializer.class)
private ZonedDateTime start;
@JsonSerialize(using = APIDateFormatSerializer.class)
private ZonedDateTime end;
private boolean enabled;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ZonedDateTime getStart() {
return start;
}
public void setStart(ZonedDateTime start) {
this.start = start;
}
public ZonedDateTime getEnd() {
return end;
}
public void setEnd(ZonedDateTime end) {
this.end = end;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public URI createLocation() {
return URI.create("/campaigns/" + getId());
}
}
The resource class
@Path("/v2")
public class OfferResource {
@POST
@Consumes(APPLICATION_JSON)
@Produces({APPLICATION_JSON})
@Path("/offers")
public Response createOffer(@Valid Offer campaign) {
return created(aDefaultOffer().createLocation())
.build();
}
------
JSON in the post
{"id":"123", "name": ""}
A constraintviolationException is indeed thrown from the code but it's not mapped to the correct status code.
I did some more debugging on this. One of the things I found was that I had a jar <groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-bean-validation</artifactId> in my classpath. This I suspected led to a different path in the code. I have removed that.
Now instead of a 400 I start seeing an error 500 being thrown
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Error 500 Request failed.</title>
</head>
<body>
<h2>HTTP ERROR 500</h2>
<p>Problem accessing /v2/offers. Reason:
<pre> Request failed.</pre>
</p>
<hr>
<i>
<small>Powered by Jetty://</small>
</i>
<hr/>
</body>
</html>
Part of the stack trace
WARN [2015-07-16 06:22:59,008] org.eclipse.jetty.server.HttpChannel: /v2/campaigns ! javax.validation.ConstraintViolationException: The request entity had the following errors: ! at io.dropwizard.jersey.jackson.JacksonMessageBodyProvider.validate(JacksonMessageBodyProvider.java:96) ~[dropwizard-jersey-0.8.1.jar:0.8.1] ! at io.dropwizard.jersey.jackson.JacksonMessageBodyProvider.readFrom(JacksonMessageBodyProvider.java:60) ~[dropwizard-jersey-0.8.1.jar:0.8.1] !
On debugging I find that in the
.m2/repository/org/glassfish/jersey/core/jersey-server/2.17/jersey-server-2.17-sources.jar!/org/glassfish/jersey/server/ServerRuntime.java:567
final long timestamp = tracingLogger.timestamp(ServerTraceEvent.EXCEPTION_MAPPING);
final ExceptionMapper mapper = runtime.exceptionMappers.findMapping(throwable);
I see that no exceptionmapper is found for the throwable (ConstaraintViolationException). I wonder if this could have something to do with
the issue.
Hope this provides more insight.
/Dev.
if (registerDefaultExceptionMappers == null || registerDefaultExceptionMappers) {
jersey.register(new LoggingExceptionMapper<Throwable>() {
});
jersey.register(new ConstraintViolationExceptionMapper());
jersey.register(new JsonProcessingExceptionMapper());
jersey.register(new EarlyEofExceptionMapper());
}
server:
applicationConnectors:
- type: http
port: 9000
adminConnectors:
- type: http
port: 9001
registerDefaultExceptionMappers: false <------Aaaaaargggghhhhh
logging:
level: TRACE
Removing the line of course made it work as it should have.
Ooooh...the perils of copy paste.
Thanks all for your answers.
...