How can I create a dropwizard (jersey) resource which accepts a nullable representation? - jersey

I am trying to create an action on a resource within dropwizard which accepts a representation, but allows this to be null, ie. no post data from the client.
Currently, from a client, I have to post "{}" otherwise an HTTP 415, unsupported media type is returned. I assume this is because my client is not sending a content-type header as content-length = 0.
I tried to define the resources as follows, but get a "Producing media type conflict" back from jersey as both methods consume the same path and jersey cannot differentiate between them:
#Path("/interview")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
#Log
class InterviewResource {
#POST
#Timed
Interview advanceNewInterview() {
// some processing...
}
#POST
#Timed
Enquiry advanceNewInterview(#Valid AdvanceInterviewRepresentation advanceInterview) {
// some processing...
}
}
Any ideas on how to represent this?

You could use Optional for your parameter as show below:
#POST
#Timed
Enquiry advanceNewInterview(#Valid Optional<AdvanceInterviewRepresentation> advanceInterview)
{
if (advanceInterview.isPresent())
{
// some processing...
}
}
Howerver the main Reason for 415 is not mentioning the Content-Type header. In your case it should be Content-Type : application/json

Related

Request method 'POST' not supported in Postman

I have created this controller
#PostMapping(value = "/validate")
public ResponseEntity<GenericResponse> validate(#RequestBody #Valid FormulaDTO formulaDto) {
System.out.println(formulaDto);
String expression = formulaDto.getFormula();
service.validate(expression);
return new ResponseEntity<>(new GenericResponse(HttpStatus.CREATED.value(), "Expression Validated"),
HttpStatus.CREATED);
}
The FormulaDTO looks like
public class FormulaDTO {
private String formula;
}
I have created a PostRequest from postman whose body contains the formulaText.
The api call from postman looks like
https://localhost:8443/validate
with body as
{
"formula" :"M00212=curr_month:M00213-curr_month:M00211*100.00"
}
I am getting the following as output with 500 Internal Server Error
{
"timestamp": "2021-05-03",
"message": "Request method 'POST' not supported",
"details": "uri=/error"
}
How can i use PostMapping?
Use http instead of https in postman.
Instead of this: https://localhost:8443/validate
Use this: http://localhost:8443/validate
Looking at the comments
There is no root level mapping at #RestController .
Even if you don't have a root level mapping on controller it seems that spring boot always needs the following annotation on controller level
#RequestMapping
Add it and it will be fixed!

IllegalArgumentException: The HTTP header line does not conform to RFC 7230 when POST-accessing Spring Controller

I want to implement a user registration functionality with Spring. When I try to POST the data to the spring controller, the exception above is thrown. Surprisingly, GET Requests work on the controller.
#RestController
#RequestMapping(RestApi.ANONYMOUS + "register")
public class RegisterController {
#PostMapping(value="/new", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public UserRegistrationResultDto registerUser(#RequestBody UserRegisterDto dto) {
UserRegistrationResultDto result = registerService.registerUser(dto.getMail(),
dto.getPassword(), dto.getRepeatedPassword());
return result;
}
#GetMapping("/test")
public String test() {
return "get success";
}
}
The request that fails with error code 400 is the following:
POST http://localhost:8080/api/anonymous/register/new
Content-Type:application/x-www-form-urlencoded
{
mail=data&password=data&passwordRepeated=data
}
It throws the following exception:
java.lang.IllegalArgumentException: The HTTP header line [{: ] does not conform to RFC 7230 and has been ignored.
This get request however works:
GET http://localhost:8080/api/anonymous/register/test
I am using Tomcat 9 as a server.
Not sure how the POST request is submitted...but a space after : is required for HTTP header fields:
Content-Type: application/x-www-form-urlencoded

getting http 415, Unsupported Media Type using text/xml

I have a jersey endpoint(JAX-RS) that I'm trying to hit with a text/xml req. I'm getting back an http 415 and I don't understand why. Here is the info. Any ideas? Thanks.
#Path("/bid")
#Produces("text/xml;charset=ISO-8859-1")
#Consumes({"text/xml", "application/xml"})
#Resource
public class BidController {
#RolesAllowed("blah")
#POST
public Response bid(final HttpServletRequest request) {
I am hitting it via Postman(REST client) and sending {"Content-Type":"text/xml"}
My POST body is definitely well formed xml.
You are getting a 415 response because JAX-RS does not know how to convert incoming XML into a HttpServletRequest.
If you really want access to the request, then you need to annotate it with #javax.ws.rs.core.Context:
#RolesAllowed("blah")
#POST
public Response bid(#Context final HttpServletRequest request) {
However, as you say you're hitting it with text/xml, then you may actually want:
#POST
public Response bid(final MyRequest request) {
...
}
where MyRequest is declared something like:
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class MyRequest {
#XmlElement
int field1;
#XmlElement
String field2;
...
}
which corresponds to XML like:
<MyRequest>
<field1>11327</field1>
<field2>some string
</MyRequest>
The JAX-RS specification requires implementations to be able to decode incoming text/xml and encode outgoing text/xml via JAXB.

Using Jersey's #BeanParam results in a 415 error

I am trying to use Jersey's #BeanParam annotation the following way:
This is my bean:
public class BeanParamModel {
#QueryParam(value = "param1")
private String param1;
public BeanParamModel(#QueryParam("param1") String param1) {
this.param1 = param1;
}
public String getParam1() {
return param1;
}
public void setParam1(String param1) {
this.param1 = param1;
}}
And this is the resource method that needs to use it:
#Consumes("*/*")
#Path("mypath")
#GET
public Response getUpgradeStatus(#QueryParam("param1") String param1, #BeanParam BeanParamModel user) {
return Response.ok().build();
}
Now I want to test this using a unit test which sends an http request to a test server with the following url:
GET http://path_to_resource?param1=1
My problem is that results in a 415 response with Jersey printing this message:
A message body reader for Java class BeanParamModel, and Java type class BeanParamModel, and MIME media type application/octet-stream was not found.
The registered message body readers compatible with the MIME media type are:...
I've trying adding a "application/x-www-form-urlencoded" header but the message repeats for that header type as well. I also tried using an application/json header, this results in EOF expection from the jackson mapper due to end of input.
Can anyone tell me what I'm not doing correctly? from the jersey documentation of #BeanParam it seems pretty simple.
With a #GET you should not have #Consumes.

POST request to Spring REST web service fails with HTTP status 415

I have set up a spring RESTful web service for taking in the username and password from a user. Been following the tutorial on Spring IO
My service is set up to accept user name and password as shown below:
#Controller
#RequestMapping("/users")
public class UserCommandController {
private static Logger log = LoggerFactory.getLogger(UserCommandController.class);
#RequestMapping(method = RequestMethod.POST)
public ResponseEntity createUser(#RequestBody UserDetail userDetail, UriComponentsBuilder builder) {
User newUser = new User();
newUser.setEmail(userDetail.getEmail());
newUser.setPassword(userDetail.getPassword());
newUser.setUserName(userDetail.getUsername());
try {
UserFactory.getInstance().saveNewUser(newUser);
} catch(UserException ue) {
log.error("Saving user failed. Exception: "+ue.getMessage());
}
return new ResponseEntity(HttpStatus.OK);
}
}
I am sending POST parameters to the service as a test through Google chrome plugin POSTMAN but I get "HTTP: 415..The server refused this request because the request entity is in a format not supported by the requested resource for the requested method."
Does anyone have an idea what I am doing wrong ?
Set the header:
Content-Type=application/json
This solved my problem!
The HTTP 415 response code means that the server expected data posted with a different content type. It appears you simply posted a form with username, password and email as parameters. That would result in a content-type of application/x-www-form-urlencoded.
Try posting with a content-type of application/xml or application/json. In your post body, you will need to put your data in the corresponding format. For example, if you use application.xml, the XML body should look something like:
<userDetail>
<userName>xxx</userName>
<password>xxx</password>
<email>xxx</email>
</userDatail>
Of course the exact format (i.e. element names) depends on the XML bindings. In fact, whether or not the expected format is XML or JSON or something else is also likely a server configuration.
Posting a request of this type cannot easily be done with a browser. You will need some other HTTP client. A tool like SOAP-UI might be a good bet.

Resources