I'm getting a 400 Error on calling put on a resource :"code":400,"message":"Unable to process JSON". I'm using the embedded jetty server
I'm using postman as client for testing.
Here is the method in the resource for put method:
#Path("/Ads")
public class AdResource {
#PUT
#Consumes(MediaType.WILDCARD)
#Produces(MediaType.APPLICATION_JSON)
#Timed
#UnitOfWork
public Response update(#Valid AdDTO adDto) {
Ad ad = adDto.buildAd();
ad = adDao.merge(ad);
return Response.ok(toJson(ad)).build();
}
}
Here is the Json data sent from the client:
{
"id": 44,
"created": 1430927007000,
"updated": 1430927052000,
"category": "Voiture",
"type": "Berline",
"make": "AUDI",
"model": "A3",
"month": null,
"year": 2002,
"trimVersion": null,
"transmission": "Manuelle",
"fuel": "Diesel",
"door": "4 portes",
"color": "#FC809B",
"metal": true,
"warranty": true,
"publish": false,
"price": 123,
"mileage": 123,
"power": 123,
"description": "<p>df sdfds sdfsdf sdfsdfds sdfsdfsd</p>",
"adImages": [
{
"id": 55,
"created": 1430926983000,
"updated": 1430926983000,
"name": "amine.png",
"url": "http://localhost/assets/photo/55/photo.png",
"photoUrl": "http://localhost/assets/ad/44/55.jpg",
"thumbPhotoUrl": "http://localhost/assets/ad/44/55_thumb.jpg"
},
{
"id": 54,
"created": 1430926982000,
"updated": 1430926982000,
"name": "amine2.jpg",
"url": "http://localhost/assets/photo/54/photo.jpg",
"photoUrl": "http://localhost/assets/ad/44/54.jpg",
"thumbPhotoUrl": "http://localhost/assets/ad/44/54_thumb.jpg"
}
],
"options": [
"1",
"2",
"13",
"3",
"14",
"15"
]
}
The post and get methods works just fine.
I'm using dropwizard 8.0.1 java 8.
Adding getters to all the variables of returned class solved the error for me.
Related
I have a simple rest API written in java springboot that produces the JSON output as shown in the following example:
{
"status": 0,
"data": {
"total": 351,
"offset": 0,
"limit": 10,
"info": {
"1010": {
"id": 1010,
"name": "John",
"age": 28
},
"1009": {
"id": 1009,
"name": "Philippe",
"age": 42
},
"1008": {
"id": 1008,
"name": "Nick",
"age": 22
},
"1007": {
"id": 1007,
"name": "Razor",
"age": 19
},
"1006": {
"id": 1006,
"name": "Marco",
"age": 67
},
"1005": {
"id": 1005,
"name": "Pablo",
"age": 19
},
"1004": {
"id": 1004,
"name": "Sheldon",
"age": 29
},
"1003": {
"id": 1003,
"name": "Hazel",
"age": 34
},
"1002": {
"id": 1002,
"name": "Penny",
"age": 44
},
"1001": {
"id": 1001,
"name": "Chris",
"age": 41
}
}
},
"timeStamp": "2021-05-26T15:13:41.022+0000 UTC"
}
When I test the API using swagger, the JSON gets sorted automatically based on the keys in the following way:
{
"status": 0,
"data": {
"total": 351,
"offset": 0,
"limit": 10,
"info": {
"1001": {
"id": 1001,
"name": "Chris",
"age": 41
},
"1002": {
"id": 1002,
"name": "Penny",
"age": 44
},
"1003": {
"id": 1003,
"name": "Hazel",
"age": 34
},
"1004": {
"id": 1004,
"name": "Sheldon",
"age": 29
},
"1005": {
"id": 1005,
"name": "Pablo",
"age": 19
},
"1006": {
"id": 1006,
"name": "Marco",
"age": 67
},
"1007": {
"id": 1007,
"name": "Razor",
"age": 19
},
"1008": {
"id": 1008,
"name": "Nick",
"age": 22
},
"1009": {
"id": 1009,
"name": "Philippe",
"age": 42
},
"1010": {
"id": 1010,
"name": "John",
"age": 28
}
}
},
"timeStamp": "2021-05-26T15:13:41.022+0000 UTC"
}
Also when I use an online JSON viewer to visualize the JSON output, the behavior remains the same. However, when I hit the API using Postman, the order is retained. Can some explain this behavior and how this can be controlled?
Probably just a Swagger feature. See https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/
For readability, parameters are grouped by category and sorted
alphabetically.
We have the following simple webserver:
package spring;
import avro.BatteryEvent;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.util.Date;
#RestController
public class EnergyResourcesController {
private final Date date = new Date();
#PostMapping("/event/{uuid}")
BatteryEvent postBatteryEvent(
#PathVariable("uuid") String uuid,
#RequestBody BatteryEvent batteryEvent) throws IOException {
batteryEvent.setTime(date.getTime());
return batteryEvent;
}
}
It uses a BatteryEvent, which is an Avro-generated class, which is built from the following Avro schema:
{
"namespace": "avro",
"type": "record",
"name": "BatteryEvent",
"fields": [
{
"name": "charging_source",
"type": [
"string",
"null"
]
},
{
"name": "processor4_temp",
"type": [
"int",
"null"
]
},
{
"name": "device_id",
"type": [
"string",
"null"
]
},
{
"name": "processor2_temp",
"type": [
"int",
"null"
]
},
{
"name": "processor1_temp",
"type": [
"int",
"null"
]
},
{
"name": "charging",
"type": [
"int",
"null"
]
},
{
"name": "current_capacity",
"type": [
"int",
"null"
]
},
{
"name": "inverter_state",
"type": [
"int",
"null"
]
},
{
"name": "moduleL_temp",
"type": [
"int",
"null"
]
},
{
"name": "moduleR_temp",
"type": [
"int",
"null"
]
},
{
"name": "processor3_temp",
"type": [
"int",
"null"
]
},
{
"name": "soC_regulator",
"type": [
"float",
"null"
]
},
{
"name": "time",
"type": [
"long",
"null"
],
"logicalType": "local-timestamp-millis"
}
]
}
We send the webserver the following JSON,
{
"charging_source": "utility",
"processor4_temp": 160,
"device_id": "18806072-81ca-48ed-b01a-b080f2d8a1fa",
"processor2_temp": 96,
"processor1_temp": 60,
"charging": -912,
"current_capacity": 10948,
"inverter_state": 1,
"moduleL_temp": 199,
"moduleR_temp": 91,
"processor3_temp": 152,
"soC_regulator": 26.598085
}
The problem is the BatteryEvent that we receive has all null values besides the charging field, like so:
{"charging_source": null, "processor4_temp": null, "device_id": null, "processor2_temp": null, "processor1_temp": null, "charging": -261, "current_capacity": null, "inverter_state": null, "moduleL_temp": null, "moduleR_temp": null, "processor3_temp": null, "soC_regulator": null, "time": null}
My question is, why is this? All of the sent data is valid JSON, and our Avro class is valid as well. Our Spring Boot server is simple and valid code that was taken from Spring Boot's own documentation. I want the data which Spring Boot casts to the BatteryEvent object to contain the values from the sent battery event JSON.
I am not sure what is the root cause of your problem, but it seems there is some issue with
JSON serialization/deserialization.
When I tried to replicate your issue, as per your information I was getting some exception which I resolved by using the solution mentioned here here
After this when I execute the POST API I received the expected result with all the values populated.
You can check my code here here
Can you please provide more information about your code, like if you have modified the default serialization/deserialization process ? This will help to get more idea about why in your code the properties are getting set as null
Below are the request and response from my example
Request
{
"charging_source": "utility",
"processor4_temp": 160,
"device_id": "18806072-81ca-48ed-b01a-b080f2d8a1fa",
"processor2_temp": 96,
"processor1_temp": 60,
"charging": -912,
"current_capacity": 10948,
"inverter_state": 1,
"moduleL_temp": 199,
"moduleR_temp": 91,
"processor3_temp": 152,
"soC_regulator": 26.598085
}
Response
{
"charging_source": "utility",
"processor4_temp": 160,
"device_id": "18806072-81ca-48ed-b01a-b080f2d8a1fa",
"processor2_temp": 96,
"processor1_temp": 60,
"charging": -912,
"current_capacity": 10948,
"inverter_state": 1,
"moduleL_temp": 199,
"moduleR_temp": 91,
"processor3_temp": 152,
"soC_regulator": 26.598085,
"time": 1609404352570,
"moduleRTemp": 91,
"moduleLTemp": 199,
"inverterState": 1,
"soCRegulator": 26.598085,
"deviceId": "18806072-81ca-48ed-b01a-b080f2d8a1fa",
"processor1Temp": 60,
"currentCapacity": 10948,
"processor3Temp": 152,
"processor4Temp": 160,
"chargingSource": "utility",
"processor2Temp": 96
}
The field name in entity should be the same as the key name in json
I have a token restful service, which generates the following info when I use postman to hit it (GET).
{
"authorities": [
{
"id": 1,
"authority": "admin"
},
{
"id": 2,
"authority": "ROLE_USER"
}
],
"details": {
"remoteAddress": "0:0:0:0:0:0:0:1",
"sessionId": null,
"tokenValue": "7760e769-9b1e-4669-8b6d-85e51809934d",
"tokenType": "bearer",
"decodedDetails": null
},
"authenticated": true,
"userAuthentication": {
"authorities": [
{
"id": 1,
"authority": "admin"
},
{
"id": 2,
"authority": "ROLE_USER"
}
],
"details": {
"remoteAddress": "0:0:0:0:0:0:0:1",
"sessionId": null
},
"authenticated": true,
"principal": {
"id": 1,
"username": "sysadmin",
"password": "$2a$10$xm6.EOh8GrsnwRy91d2cueZPwvPojuExnYEGy1auFyzqYTtdlHvUe",
"accountNonExpired": true,
"accountNonLocked": true,
"credentialsNonExpired": true,
"enabled": true,
"authorities": [
{
"id": 1,
"authority": "admin"
},
{
"id": 2,
"authority": "ROLE_USER"
}
],
"userId": "1"
},
"credentials": null,
"name": "sysadmin"
},
"credentials": "",
"oauth2Request": {
"clientId": "movez",
"scope": [
"all"
],
"requestParameters": {
"grant_type": "refresh_token"
},
"resourceIds": [],
"authorities": [],
"approved": true,
"refresh": false,
"redirectUri": null,
"responseTypes": [],
"extensions": {},
"grantType": "refresh_token",
"refreshTokenRequest": null
},
"principal": {
"id": 1,
"username": "sysadmin",
"password": "$2a$10$xm6.EOh8GrsnwRy91d2cueZPwvPojuExnYEGy1auFyzqYTtdlHvUe",
"accountNonExpired": true,
"accountNonLocked": true,
"credentialsNonExpired": true,
"enabled": true,
"authorities": [
{
"id": 1,
"authority": "admin"
},
{
"id": 2,
"authority": "ROLE_USER"
}
],
"userId": "1"
},
"clientOnly": false,
"name": "sysadmin"
}
However, when I use RestTemplate exchange to make the api call, I get the following,
The problem here is
There are two layers "authorities", which doesn't match the structure in the Json.
If we go deep, we only have the authority "ROLE_USER", the "admin" is not retrieved.
My code is
Map auth = restTemplate.exchange(tokenVerifyUri, HttpMethod.GET, entity, Map.class).getBody();
It previously worked fine but have this trouble after I upgrade spring to 2.0 (not sure if it is related).
Please help. Thanks in advance.
UPDATE:
If I change Map.class to String.class in exchange function, I got the correct Json.
I am trying to implement REST API for Fortify Software Security Center using Java. I am able to obtain
1)token by using following url
http://xxx.xxx.xxx.xxx:8080/ssc/api/v1/auth/obtain_token
response for above URL as below
{
"data": {
"token": "NDIxMjE0NjUtOGIwNy00ZjFiLWEzMTUtZjZkYTg0MWY1Zjgz",
"creationDate": "2016-09-14T05:49:34.000+0000",
"terminalDate": "2016-09-15T05:49:34.000+0000"
},
"responseCode": 200
}
and
2)get list of reports using following URL
http://xxx.xxx.xxx.xxx:8080/ssc/api/v1/reports
response for above URL as below
{
"data": [
{
"note": "",
"_href": "http://xxx.xxx.xxx.xxx:8080/ssc/api/v1/reports/17",
"formatDefaultText": "PDF",
"projects": [
{
"id": 16,
"name": "Project 1",
"versions": [
{
"id": 30,
"name": "1.0",
"developmentPhase": "New"
}
]
}
],
"authEntity": {
"id": 2,
"userName": "AAA",
"firstName": "AAA",
"lastName": "AAA"
},
"isPublished": false,
"format": "PDF",
"generationDate": "2016-08-03T10:56:46.000+0000",
"statusDefaultText": "Processing Complete",
"reportDefinitionId": null,
"type": "ISSUE",
"typeDefaultText": "Issue Reports",
"inputReportParameters": null,
"name": "Project 1",
"id": 17,
"status": "PROCESS_COMPLETE"
},
{
"note": "",
"_href": "http://xxx.xxx.xxx.xxx:8080/ssc/api/v1/reports/22",
"formatDefaultText": "PDF",
"projects": [
{
"id": 16,
"name": "Project 2",
"versions": [
{
"id": 30,
"name": "1.0",
"developmentPhase": "New"
}
]
}
],
"authEntity": {
"id": 10,
"userName": "BBB",
"firstName": "BBB",
"lastName": "BBB"
},
"isPublished": false,
"format": "PDF",
"generationDate": "2016-08-24T13:45:30.000+0000",
"statusDefaultText": "Processing Complete",
"reportDefinitionId": null,
"type": "ISSUE",
"typeDefaultText": "Issue Reports",
"inputReportParameters": null,
"name": "Project 2",
"id": 22,
"status": "PROCESS_COMPLETE"
},
{
"note": "",
"_href": "http://xxx.xxx.xxx.xxx:8080/ssc/api/v1/reports/41",
"formatDefaultText": "PDF",
"projects": [
{
"id": 2,
"name": "Project 3",
"versions": [
{
"id": 3,
"name": "1.0",
"developmentPhase": "Active Development"
}
]
}
],
"authEntity": {
"id": 10,
"userName": "CCC",
"firstName": "CCC",
"lastName": "CCC"
},
"isPublished": false,
"format": "PDF",
"generationDate": "2016-08-25T16:56:22.000+0000",
"statusDefaultText": "Processing Complete",
"reportDefinitionId": null,
"type": "ISSUE",
"typeDefaultText": "Issue Reports",
"inputReportParameters": null,
"name": "Project 3",
"id": 41,
"status": "PROCESS_COMPLETE"
},
{
"note": "",
"_href": "http://xxx.xxx.xxx.xxx:8080/ssc/api/v1/reports/57",
"formatDefaultText": "XLS",
"projects": [
{
"id": 2,
"name": "Project 4",
"versions": [
{
"id": 3,
"name": "1.0",
"developmentPhase": "Active Development"
}
]
}
],
"authEntity": {
"id": 11,
"userName": "DDD",
"firstName": "DDD",
"lastName": "DDD"
},
"isPublished": false,
"format": "XLS",
"generationDate": "2016-09-09T15:46:22.000+0000",
"statusDefaultText": "Processing Complete",
"reportDefinitionId": null,
"type": "ISSUE",
"typeDefaultText": "Issue Reports",
"inputReportParameters": null,
"name": "Project 4",
"id": 57,
"status": "PROCESS_COMPLETE"
}
],
"count": 4,
"responseCode": 200,
"links": {
"last": {
"href": "http://xxx.xxx.xxx.xxx:8080/ssc/api/v1/reports/?start=0"
},
"first": {
"href": "http://xxx.xxx.xxx.xxx:8080/ssc/api/v1/reports/?start=0"
}
}
}
But I didn't find any end point URL to download the saved reports. Can you please help me to get the end point URL or provide reference API document for HP fortify Software Security Center.
I know this is kind of an old post but just ran into the issue myself and found the solution.
First you have to request a file token as a HTTPPost:
http://xxx.xxx.xxx.xxx:8080/ssc/api/v1/fileTokens
with:
{"fileTokenType": "REPORT_FILE"}
in the request body.
This will return a unique id that you will use to fetch your report.
Next you will make another get request like such:
http://xxx.xxx.xxx.xxx:8080/ssc/transfer/reportDownload.html?mat=[file_token]&id=[project_id]
you will replace the [file_token] with the token returned from the above post and [project_id] with the project you want to download the report for.
so for example:
http://xxx.xxx.xxx.xxx:8080/ssc/transfer/reportDownload.html?mat=7e8d912e-2432-6496-3232-709b05513bf2&id=1
This will return the binary data that you can then save to a file. The file type is specified in the report data as "format"
I'm calling a url like this: /job/My-Job/710/api/json and it's returning some json like this:
{
"actions": [
{
"parameters": [
{
"name": "DEPLOY_HOST",
"value": ""
}
]
},
{
"causes": [
{
"shortDescription": "Started by user Hudson Admin",
"userId": "username",
"userName": "Hudson Admin"
}
]
},
{},
{},
{}
],
"artifacts": [],
"building": true,
"description": null,
"duration": 0,
"estimatedDuration": 390011,
"executor": {},
"fullDisplayName": "My-App #711",
"id": "2013-08-30_12-50-14",
"keepLog": false,
"number": 711,
"result": "SUCCESS",
"timestamp": 1377892214231,
"url": "http://hudsonurl:8081/job/My-App/711/",
"builtOn": "",
"changeSet": {
"items": [
{}
],
"kind": "svn",
"revisions": [
{
"module": "https://oursvn",
"revision": 27498
}
]
},
"culprits": [
{
"absoluteUrl": "http://hudsonsurl:8081/user/handsomeg",
"fullName": "handsome guy"
}
],
"mavenArtifacts": null,
"mavenVersionUsed": "3.0.4"
}
This build is actually in progress right now, but I can't see a way to know that. You'd think that the value of result should be in progress, but it's not. Is this a bug, or is there some other way to check? I'm using Jersey version 1.523
I just noticed there's a "building": true.
Makes me wonder what result is for. Maybe builds are considered SUCCESS until proven otherwise.