#RequestBody return null after create body - java

i have created RequestBody with Gson and add to Post request, but in the controller of api (url), all attrs return null.
Add to RequestBody:
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
Gson gson = new Gson();
JSONObject jsonObject = new JSONObject();
jsonObject.put("dataFromAppChinh", "demo thoi");
jsonObject.put("path", path);
String body = gson.toJson(jsonObject);
RequestBody requestBody = RequestBody.create(body, JSON);
Request request = new Request.Builder().url("http://" + path + "/api/startapp").post(requestBody).build();
Controller
#RestController
#RequestMapping("/api")
public class ChatBot {
#PostMapping(value = "/startapp")
#ResponseBody
public Object start(#RequestBody() ChatBotResponse item) {
try {
item.setResponseList(startApp(item.getPath()));
return item;
} catch (Exception ex) {
log.error(ex);
return ex.getMessage();
}
}
}
My ChatBotResponse POJO:
#Data
public class ChatBotResponse
{
private String dataFromAppChinh;
private String responseList;
private String path;
}

i found problem is gson.toJson(jsonObject) insert map string before my Json String.
I changed to jsonObject.toString() and it worked.

Related

RestTemplate return NULL to all parameters when posting form data

I developed an OCR API using Flask to scan photos and return the scanned data. I want to call this API from Spring boot, So i can POST the photo to the API endpoint and get a response and use that response to map it to my POJO. When ever i put my photo using postman i get all Parameters as NULL. everything i did is correct. I converted the image and i sent it to the correct URL. I don't exactly know the problem here.
Flask API results with POSTMAN
{
"2": {
"adadFar": "ا 0",
"esmTijari": "PFE",
"esmTijariLatin": "EXAMPLE RNE",
"makarEjtima": "Shand! شارع الطيب",
"makarNachat": "شارع الطيب المهيري",
"nithamKanouni": "مسؤولية محدودة ald",
"rasMal": "1000000",
"tasmiya": "FACULTE DES SCIENCES",
"tasmiyaLatin": "LCS 3"
},
"adad_sejel: ": "F1700655698",
"modatCharika: ": "99",
"mouaref: ": "1887415R",
"nachatRaisi: ": "بيع الاعلاف و الالات الفلاحية و الصناعية",
"tarikh: ": "2015/09/29",
"tarikhBideyetNachat: ": "2001-12-6",
"tarikhEchhar: ": "2005-01-26"
}
Spring boot Result when POSTING the photo
{
"mouaref": null,
"adad_sejel": null,
"tarikh": null,
"tasmiya": null,
"tasmiyaLatin": null,
"esmTijari": null,
"esmTijariLatin": null,
"makarEjtima": null,
"makarNachat": null,
"nithamKanouni": null,
"rasMal": null,
"adadFar": null,
"nachatRaisi": null,
"tarikhBideyetNachat": null,
"tarikhEchhar": null,
"modatCharika": null
}
Here's my Pojo class:
public class formResponse {
private String mouaref;
private String adad_sejel;
private String tarikh;
private String tasmiya;
private String tasmiyaLatin;
private String esmTijari;
private String esmTijariLatin;
private String makarEjtima;
private String makarNachat;
private String nithamKanouni;
private String rasMal;
private String adadFar;
private String nachatRaisi;
private String tarikhBideyetNachat;
private String tarikhEchhar;
private String modatCharika;
\\getters and setters
public formResponse(){
}
Here's my Service class:
#Service
public interface FormRecognition {
public static formResponse getInfoClientFromRne(MultipartFile image) {
try {
formResponse form = new formResponse();
MultiValueMap<String, Object> bodyMap = new LinkedMultiValueMap<>();
bodyMap.add("image", new FileSystemResource(convert(image)));
// System.out.println("body map ;" + bodyMap.size());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(bodyMap, headers);
// System.out.println("Headers: "+requestEntity.getHeaders());
// System.out.println("requestEntity ; "+requestEntity.toString());
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<formResponse> response = restTemplate.exchange("http://172.20.10.3:3500/upload-image", HttpMethod.POST, requestEntity,
formResponse.class);
form= response.getBody();
// System.out.println("form ; "+response);
// System.out.println("form ; "+form.getMouaref());
return form;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static File convert(MultipartFile file) {
File convertFile = new File(file.getOriginalFilename());
try {
convertFile.createNewFile();
FileOutputStream fos = new FileOutputStream(convertFile);
fos.write(file.getBytes());
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return convertFile;
}
}
Here's my Controller:
#RestController
public class FileUploadController
{
#RequestMapping(value = "/upload", produces = {
MediaType.APPLICATION_JSON_VALUE }, method = RequestMethod.POST)
public formResponse upload(#RequestParam("image") MultipartFile[] image){
System.out.println("params: emtry");
try {
formResponse form = FormRecognition.getInfoClientFromRne(image[0]);
System.out.println("params: " + form);
return form;
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
Solved it! It turns out i was making ':' in the Flask response. That's why Spring boot couldn't read the response because it was different. I changed my Python script to match the exact naming in spring boot and that's when i got the data.

How to map a JSON response to a Java class using Java 11 HttpClient and Jackson?

I'm new to the Java 11 HttpClient and would like to give it a try. I have a simple GET request that return JSON and I would like to map the JSON response to a Java class called Questionnaire.
I understand that I can turn the response out of box into a String or an input stream like this
HttpRequest request = HttpRequest.newBuilder(new URI(String.format("%s%s", this.baseURI, "/state")))
.header(ACCEPT, APPLICATION_JSON)
.PUT(noBody()).build();
HttpResponse<String> response = this.client.send(request, HttpResponse.BodyHandlers.ofString());
How can I write something that converts the JSON string to my Questionnaire class like this?
HttpResponse<Questionnaire> response = this.client.send(request, HttpResponse.BodyHandlers./* what can I do here? */);
I use Jackson to transform JSON into Java class instances. Is there Jackson support for the new Java standard HttpClient yet?
UPDATE 1
I was not precise enough, sorry about that. I am looking for a blocking get example. I was aware of http://openjdk.java.net/groups/net/httpclient/recipes.html#jsonGet
Solution for Java 11 HttpClient::sendAsync only
Based on this link you can do something like this :
public static void main(String[] args) throws IOException, URISyntaxException, ExecutionException, InterruptedException {
UncheckedObjectMapper uncheckedObjectMapper = new UncheckedObjectMapper();
HttpRequest request = HttpRequest.newBuilder(new URI("https://jsonplaceholder.typicode.com/todos/1"))
.header("Accept", "application/json")
.build();
Model model = HttpClient.newHttpClient()
.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenApply(uncheckedObjectMapper::readValue)
.get();
System.out.println(model);
}
class UncheckedObjectMapper extends com.fasterxml.jackson.databind.ObjectMapper {
/**
* Parses the given JSON string into a Map.
*/
Model readValue(String content) {
try {
return this.readValue(content, new TypeReference<Model>() {
});
} catch (IOException ioe) {
throw new CompletionException(ioe);
}
}
}
class Model {
private String userId;
private String id;
private String title;
private boolean completed;
//getters setters constructors toString
}
I used some dummy endpoint which provides sample JSON input and sample model class to map the response directly to Model class using Jackson.
Solution for Java 11 HttpClient::send and HttpClient::sendAsync
I found a way by defining custom HttpResponse.BodyHandler :
public class JsonBodyHandler<W> implements HttpResponse.BodyHandler<W> {
private Class<W> wClass;
public JsonBodyHandler(Class<W> wClass) {
this.wClass = wClass;
}
#Override
public HttpResponse.BodySubscriber<W> apply(HttpResponse.ResponseInfo responseInfo) {
return asJSON(wClass);
}
public static <T> HttpResponse.BodySubscriber<T> asJSON(Class<T> targetType) {
HttpResponse.BodySubscriber<String> upstream = HttpResponse.BodySubscribers.ofString(StandardCharsets.UTF_8);
return HttpResponse.BodySubscribers.mapping(
upstream,
(String body) -> {
try {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(body, targetType);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
});
}
}
Then I call it :
public static void main(String[] args) throws URISyntaxException, IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder(new URI("https://jsonplaceholder.typicode.com/todos/1"))
.header("Accept", "application/json")
.build();
Model model = HttpClient.newHttpClient()
.send(request, new JsonBodyHandler<>(Model.class))
.body();
System.out.println(model);
}
The response is :
Model{userId='1', id='1', title='delectus aut autem', completed=false}
The JavaDoc of HttpResponse.BodySubscribers::mapping was particulary useful to solve this. It can be further improved to use HttpResponse.BodySubscribers::ofInputStream instead of HttpResponse.BodySubscribers.ofString(StandardCharsets.UTF_8) to define the BodySubscriber for the JsonBodyHandler.
Simplifying #michalk solution for Java 11 HttpClient::send
HttpService Class Example:
public class HttpService {
private final HttpClient httpClient= HttpClient.newBuilder().version(HttpClient.Version.HTTP_2).build();
public HttpService() {}
public <T> T sendGetRequest(String url, Class<T> responseType) throws IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder().GET().uri(URI.create(url)).header("Accept", "application/json").build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
return new ObjectMapper().readValue(response.body(), responseType);
}
public <T> List<T> sendGetListRequest(String url, Class<T> responseType) throws IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder().GET().uri(URI.create(url)).header("Accept", "application/json").build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(response.body(), objectMapper.getTypeFactory().constructCollectionType(List.class, responseType));
}}
Model Class Example:
public class Model {
private String id;
public Model() {}
public String getId() { return this.id; }
public void setId(String id) { this.id = id; }
#Override
public String toString() { return "Model{" + "id='" + id + '\'' + '}'; }}
Sending HTTP GET request:
public class Main {
public static void main(String[] args) {
try {
HttpService httpService = new HttpService();
Model model = httpService.sendGetRequest("http://localhost:8080/api/v1/models/1", Model.class);
System.out.println("Single Object:" + model);
System.out.print('\n');
List<Model> models = httpService.sendGetListRequest("http://localhost:8080/api/v1/models", Model.class);
for(Model m: models) { System.out.println("Object:" + m); }
}
catch (IOException | InterruptedException e) {
System.err.println("Failed to send GET request: " + e.getMessage());
}
}}
Response:
Single Object: Model{id='1'}
Object: Model{id='1'}
Object: Model{id='2'}
Object: Model{id='3'}
Required Maven Dependency (pom.xml):
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.3</version>
</dependency>
If you're OK with including a dependency, check out Methanol (disclaimer: I'm the library's author). The library has special BodyHandler implementations for object mapping. You can add JSON support by installing the jackson adapter.
var request = MutableRequest.GET("https://example.com")
.header("Accept", "application/json");
var modelResponse = client.send(request, MoreBodyHandlers.ofObject(Model.class));
// Use TypeRef<T> for complex types
var modelListResponse = client.send(request, MoreBodyHandlers.ofObject(new TypeRef<List<Model>>() {}));

How to parse Retrofit JSON response

I have a typical Retrofit API request:
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(URL)
.build();
ApiEndpointInterface api = restAdapter.create(ApiEndpointInterface.class);
api.getToken('1', new Callback<DefaultResponse>() {
#Override
public void success(DefaultResponse json, Response response) {
//
}
#Override
public void failure(RetrofitError response) {
//
}
});
And the returned JSON is:
{"success":true,"data":{"token_id":"pPt9AKl0Cg","token_key":"8ax224sFrJZZkStAQuER"}}
How can I parse this JSON? It seems wrong/tedious to create a new model class for each different response across my app. Is there a better way to do it?
you should write your model class like below
public class MyResponseModel {//write setters and getters.
private boolean success;
private DataModel data;
public static class DataModel {
private String token_id;
private String token_key;
}
}
now in your getToken() method should look like this
getToken('1', Callback<MyResponseModel> response);
retrofit will parse the response and convert it to the class above.
Try this code,
JsonElement je = new JsonParser().parse(s);
JsonObject asJsonObject = je.getAsJsonObject();
JsonElement get = asJsonObject.get("data");
System.out.println(s + "\n" + get);
JsonObject asJsonObject1 = get.getAsJsonObject();
JsonElement get1 = asJsonObject1.get("token_id");
System.out.println(get1);
JsonElement get2 = asJsonObject1.get("token_key");
System.out.println(get2);

REST API Authentication with Jersey

I'm trying to implement an authentication on my current Java Restful API (Jersey) by following this tutorial. I put all new authentication classes inside a "auth" package. When I run the jquery example code, it says that "DemoBusinessRESTResourceProxy is an interface and cannot be instantiated". So I research and decided to put the Jersey annotations on DemoBusinessRESTResource and delete DemoBusinessRESTResourceProxy:
#Local
#Path("access/")
#Stateless(name = "DemoBusinessRESTResource", mappedName = "ejb/DemoBusinessRESTResource")
public class DemoBusinessRESTResource {
private static final long serialVersionUID = -6663599014192066936L;
#POST
#Path("/login")
#Produces(MediaType.APPLICATION_JSON)
public Response login(#Context HttpHeaders httpHeaders,
#FormParam("username") String username,
#FormParam("password") String password) {
Authenticator authenticator = Authenticator.getInstance();
String serviceKey = httpHeaders
.getHeaderString(HTTPHeaderNames.SERVICE_KEY);
try {
String authToken = authenticator.login(serviceKey, username,
password);
JsonObjectBuilder jsonObjBuilder = Json.createObjectBuilder();
jsonObjBuilder.add("auth_token", authToken);
JsonObject jsonObj = jsonObjBuilder.build();
return getNoCacheResponseBuilder(Response.Status.OK).entity(
jsonObj.toString()).build();
} catch (final LoginException ex) {
JsonObjectBuilder jsonObjBuilder = Json.createObjectBuilder();
jsonObjBuilder.add("message",
"Problem matching service key, username and password");
JsonObject jsonObj = jsonObjBuilder.build();
return getNoCacheResponseBuilder(Response.Status.UNAUTHORIZED)
.entity(jsonObj.toString()).build();
}
}
#GET
#Path("/demo-get-method")
#Produces(MediaType.APPLICATION_JSON)
public Response demoGetMethod() {
JsonObjectBuilder jsonObjBuilder = Json.createObjectBuilder();
jsonObjBuilder.add("message", "Executed demoGetMethod");
JsonObject jsonObj = jsonObjBuilder.build();
return getNoCacheResponseBuilder(Response.Status.OK).entity(
jsonObj.toString()).build();
}
#POST
#Path("/demo-post-method")
#Produces(MediaType.APPLICATION_JSON)
public Response demoPostMethod() {
JsonObjectBuilder jsonObjBuilder = Json.createObjectBuilder();
jsonObjBuilder.add("message", "Executed demoPostMethod");
JsonObject jsonObj = jsonObjBuilder.build();
return getNoCacheResponseBuilder(Response.Status.ACCEPTED).entity(
jsonObj.toString()).build();
}
#POST
#Path("/logout")
public Response logout(#Context HttpHeaders httpHeaders) {
try {
Authenticator authenticator = Authenticator.getInstance();
String serviceKey = httpHeaders
.getHeaderString(HTTPHeaderNames.SERVICE_KEY);
String authToken = httpHeaders
.getHeaderString(HTTPHeaderNames.AUTH_TOKEN);
authenticator.logout(serviceKey, authToken);
return getNoCacheResponseBuilder(Response.Status.NO_CONTENT)
.build();
} catch (final GeneralSecurityException ex) {
return getNoCacheResponseBuilder(
Response.Status.INTERNAL_SERVER_ERROR).build();
}
}
private Response.ResponseBuilder getNoCacheResponseBuilder(
Response.Status status) {
CacheControl cc = new CacheControl();
cc.setNoCache(true);
cc.setMaxAge(-1);
cc.setMustRevalidate(true);
return Response.status(status).cacheControl(cc);
}
}
Now, I'm getting this error:
A system exception occurred during an invocation on EJB BusinessRESTResource, method: public javax.ws.rs.core.Response com.rest.auth.DemoBusinessRESTResource.login(javax.ws.rs.core.HttpHeaders,java.lang.String,java.lang.String), Caused by: java.lang.AbstractMethodError: com.sun.jersey.spi.container.ContainerRequest.getHeaderString(Ljava/lang/String;)Ljava/lang/String;
I'm new in Java WS and I'm totally lost.
I found the problem. The problem was the jar version files.

Errors on Json deserialize

i'm trying deserialize my object, but I can not get no error!
I'm using gson on android to read json file.
My deserialize
this is my request class, i using a rest server.
public Object getListaSeguradoras(String _codPais, String _tipoPesquisa)
{
try {
HttpClient httpClient = new DefaultHttpClient();
HttpPost post = new HttpPost(Config.WS_PATH);
post.setHeader("content-type", "application/json; charset=UTF-8");
post.addHeader("Client-Application","xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
//Make object in JSON format
JSONObject dato = new JSONObject();
dato.put("CodPais", _codPais);
dato.put("TipoPesquisa", _tipoPesquisa);
StringEntity entity = new StringEntity(dato.toString());
post.setEntity(entity);
HttpResponse resp = httpClient.execute(post);
String respStr = EntityUtils.toString(resp.getEntity());
Gson gson = new Gson();
Type collectionType = new TypeToken<Collection<SeguradoraLista>>(){}.getType();
Collection<SeguradoraLista> ListaSeguradoras = gson.fromJson(respStr, collectionType);
return ListaSeguradoras;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
My object:
This is my getter and setter
public class SeguradoraLista{
public String SeguradoraId;
public String Nome;
public String getSeguradoraId() {
return this.SeguradoraId;
}
public String getNome() {
return this.Nome;
}
public void setSeguradoraId ( String SeguradoraId) {
this.SeguradoraId = SeguradoraId;
}
public void setNome ( String Nome) {
this.Nome = Nome;
}
}
My json:
this is the json string on my string respStr
[{"SeguradoraId":"19","Nome":"AIG Europe"},
{"SeguradoraId":"25","Nome":"AIOI Insurance Co. Of Europe"},
{"SeguradoraId":"28","Nome":"Aktiv Forsikring A/S"},
{"SeguradoraId":"160","Nome":"Enter Forsikring AS"},
{"SeguradoraId":"167","Nome":"Euro Insurances Ltd."},
{"SeguradoraId":"189","Nome":"Försäkrings-AB Volvia"},
{"SeguradoraId":"219","Nome":"Gjensidige NOR Forsikring"},
{"SeguradoraId":"245","Nome":"If Skadeforsikring NUF"},
{"SeguradoraId":"265","Nome":"Jernbanepersonalets Forsikring Gjensiding"},
{"SeguradoraId":"271","Nome":"KLP Skadeforsikring AS"},
{"SeguradoraId":"284","Nome":"Landbruksforsikring"},
{"SeguradoraId":"309","Nome":"Lloyd's v/Vital Skade AS"},
{"SeguradoraId":"459","Nome":"SpareBank 1 Skadeforsikring AS"},
{"SeguradoraId":"472","Nome":"Tennant Forsikring nuf"},
{"SeguradoraId":"473","Nome":"Terra Skadeforsikring AS"},
{"SeguradoraId":"494","Nome":"Trygg-Hansa Forsikring Nuf"},
{"SeguradoraId":"517","Nome":"Vesta Skadeforsikring A/S"},
{"SeguradoraId":"536","Nome":"Zürich Forsikring"}]
what I'm doing wrong? I can't make this direct deserealizing?
You seem to have an array of SeguradoraLista objects.
So just create a TypeToken of type List<SeguradoraLista>
Type collectionType = new TypeToken<List<SeguradoraLista>>() {}.getType();
List<SeguradoraLista> ListaSeguradoras = gson.fromJson(respStr, collectionType);
Actually, Collection<SeguradoraLista> would work as well.

Categories

Resources