Rest web services(post) consumes json not working - java

So I am trying to create a simple webservice post that consumes json. But I am geting the error RESTEASY002010: Failed to execute: javax.ws.rs.NotSupportedException: RESTEASY003065: Cannot consume content type
My webservice:
#POST
#Produces(MediaType.APPLICATION_XML)
#Path("teste1")
#Consumes(MediaType.APPLICATION_JSON)
public Response teste1(String product) {
String result = "Product created : " + product;
System.out.println("resultado");
System.out.println(result);
return Response.ok() //200
.entity("<erro> none </erro>")
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
.header("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With").build();
}
I also tried to do:
#Consumes("application/json")
But I am getting the same error. I can make it work if I do:
#Consumes("*/*")
But I can't understand why it doesn't work when I say it consumes json. To test the webservice I am using https://apitester.com/. With the folowing Post Data:
{
"key" : "value",
"array" : [
{ "key" : 1 },
{ "key" : 2, "dictionary": {
"a": "Apple",
"b": "Butterfly",
"c": "Cat",
"d": "Dog"
} },
{ "key" : 3 }
]
}

In general the
#Consumes("application/json")
specifies a content media type which webservice can handle.
But also you may need to explicitly specify an appropriate type in the Content-Type header for your request.
I am not familiar with the https://apitester.com but probably it does not send the Content-Type header by default
In such case your server can treat the request body as a plain text, for instance. That request would not be routed to your endpoint, because it is not designed for the plain text.
Setting the #Consumes(*/*) fixes that problem, because the wrong media type matches that pattern as well.
Could you please ensure that you sends the Content-Type: application/json with your POST request?

Related

Receive JSON data from a webservice using REST API

I need to receive JSON data from this Api http://countryapi.gear.host/v1/Country/getCountries using REST API. I need to receive NativeName and Region for the specific country.
My main problem is how to send request for the specific country (for example I print Name Australia) and get the response for NativeName and Region - Australia, Oceania (it should be String).
I have such classes:
public class Client {
public static void main(String[] args) throws ClientProtocolException, IOException {
HttpClient clientGetEntity = new DefaultHttpClient();
HttpGet request = new HttpGet("http://countryapi.gear.host/v1/Country/getCountries?pName=Australia");
request.addHeader("accept", "application/json");
HttpResponse responseGetEntity = clientGetEntity.execute(request);
//String json =EntityUtils.toString((HttpEntity) responseGetEntity);
System.out.println("Request : " + request.toString());
System.out.println("Response : " + responseGetEntity.toString());
}
}
EDITS
As regards getting the specific country's name, you need to make a get request with the country name such as:
http://countryapi.gear.host/v1/Country/getCountries?pName=Australia
The response from this request:
{
"IsSuccess": true,
"UserMessage": null,
"TechnicalMessage": null,
"TotalCount": 1,
"Response": [
{
"Name": "Australia",
"Alpha2Code": "AU",
"Alpha3Code": "AUS",
"NativeName": "Australia",
"Region": "Oceania",
"SubRegion": "Australia and New Zealand",
"Latitude": "-27",
"Longitude": "133",
"Area": 7692024,
"NumericCode": 36,
"NativeLanguage": "eng",
"CurrencyCode": "AUD",
"CurrencyName": "Australian dollar",
"CurrencySymbol": "$",
"Flag": "https://api.backendless.com/2F26DFBF-433C-51CC-FF56-830CEA93BF00/473FB5A9-D20E-8D3E-FF01-E93D9D780A00/files/CountryFlags/aus.svg",
"FlagPng": "https://api.backendless.com/2F26DFBF-433C-51CC-FF56-830CEA93BF00/473FB5A9-D20E-8D3E-FF01-E93D9D780A00/files/CountryFlagsPng/aus.png"
}
]
}
You can access NativeName and region by:
data.Response[0].NativeName and data.Response[0].Region respectively.
Since the data returned from the API is always a JSON string, dont forget to parse the string before use.
----------------------------------------
I am not a java developer but I have dealt with a lot of JSON data, Also C# and TypeScript projects.
First, you should take a look at this line:
request.addHeader("accept", "application/fson");
Am afraid this is not a valid JSON request header and if we where to start debugging your code, it would be difficult to pinpoint where the problem lies if the basis of the whole request is faulty. Please correct to:
request.addHeader("accept", "application/json"); and try again, if you have the same result, we can continue debugging from there.

Convert String error response to Http Status code

In Java+Spring application I am using, from a third party called over RestTemplate , we get the error response in the JSON with 200 response code.
e.g
{
"errors": [{
"reason": "did not like the request",
"error": "BAD_REQUEST"
}]
}
How can I convert BAD_REQUEST to the 400 integer representations.
Apache HttpStatus inte does not seem to provide any interface to do so.
Maybe you can use org.springframework.http.HttpStatus:
String error = "BAD_REQUEST";
HttpStatus httpStatus = HttpStatus.valueOf(error);
int errorIntCode = httpStatus.value();
or more safe:
String error = "BAD_REQUEST";
HttpStatus httpStatus = Arrays.stream(HttpStatus.values())
.filter(status -> status.name().equals(error))
.findAny()
.orElse(HttpStatus.INTERNAL_SERVER_ERROR);
int errorIntCode = httpStatus.value();
More succinct and short
HttpStatus.OK.value();

trying to build a Response object for a Java RESTful service

I am trying to build a Response object with a information I am getting back from a database. The information I am getting back is in a Change object:
The change.getDocument() coming back is:
{"testSolution":false,"solutionId":333,"clientId":4018593,"firewall":false,"pod":"pod3.dmy3","networkPolicy":{"speed":"1","subnets":{"nat":{"vlan":3004,"cidr":["110.168.0.0/24"]},"private":{"vlan":3004,"cidr":["15.10.1.128/25"]}}}}
So I am creating a Response like this:
return Response.status(422).location(location).entity(changeRequest).build();
In the unit test I do this:
String responseJson = response.readEntity(String.class);
System.out.println("The response is: " + responseJson);
For testing, but I get this result:
The response is: {"object_id" : 333,"object_type" : "class com.entities.Solution", "operation" : "", "revision" : 0, "remote_user" : "", "remote_host" : "", "created" : "", "published" : "", "comment" : "HTTP Status Code 422", "error" : "HTTP Status Code 422, there is a pending change request for this Solution. Replying with pending ChangeRequest", "document" : {} }
Everything is as expected, but the document node contains no information. Am I building the Response object correctly?
Try to return it in this way:
Response.status(Status.OK).type(MediaType.APPLICATION_JSON)
.entity(changeRequest).build();

Test Spring MVC response pattern (Ignore a json field in the items in the response )

I am testing a spring MVC application.I need to be sure that the response to the browser has a certain pattern, my application sends back some json, and for each Json item there is a field called DT_RowId that I do not want to compare, because DT_RowId contains a random number. Therefore, I would like to compare all the Json body, except DT_RowId and its content.
By the way a typical occurence of DT_RowId is "DT_RowId":"8407709537703772". And a typical json response is:
{"id":-1,"fieldErrors":[],"aaData":[{"id":8002,"firstname":"Bob","lastname":"Jones","email":"bob.jones#gmail.com","DT_RowId":"8407709537703772"},{"id":8002,"firstname:"Dan","lastname":"Jones","email":"dan.jones#gmail.com","DT_RowId":"8404309537701754"}]}
Below, my test:
#Test
public void testGetUsersJson() throws Exception {
mockMvc.perform(get("/users")
.accept(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(content().contentType("application/json"))
// How can I modify the line below??
.andExpect(content().bytes(IOUtils.toByteArray(ctx.getResource("classpath:responses/users.getUsersJson.mywebapp.response.json").getInputStream())))
.andExpect(status().isOk())
.andExpect(redirectedUrl(null))
.andExpect(forwardedUrl(null));
}
How can I modify the code above? I would like to compare all the Json response except the field"DT_RowId". Any clever ideas?
You can use andExpect(content().matches(regex here)), and write a regex to match your users.getUsersJson.mywebapp.response.json content excluding your DT_RowId.
If you are willing to add an extra dependency to your project, this can be achieved using the JsonUnit Spring MVC integration and formatting your JSON as below
{
"id": -1,
"fieldErrors": [],
"aaData": [
{
"id": 8002,
"firstname": "Bob",
"lastname": "Jones",
"email": "bob.jones#gmail.com",
"DT_RowId": "${json-unit.any-number}"
},
{
"id": 8002,
"firstname": "Dan",
"lastname": "Jones",
"email": "dan.jones#gmail.com",
"DT_RowId": "${json-unit.any-number}"
}
]
}

Jackson: Mapping dynamic JSON response

I'm retrieving data from a rest service and I'm using JSON to map the JSON response to java POJOs. All works fine, except the service will return a different JSON result for invalid calls, which is not mappable to the POJO:
{
"error":[
{
"code": 1,
"message":"Parameter is invalid."
}
]
}
UPDATE:
The response format for a valid call looks something like this:
persons: {
personCount: 14
person: [
{
firstname: "Michael"
name: "Bolton"
}
]
}
I'm mapping the response like this:
Person person = mapper.readValue(in, Person.class);
I've looked through the API and some SO and blog-postings, but I didn't find a hint on how to approach this so far. Can you give me a hint?

Categories