I have a react front and java backend. I am using a axios.patch request and I keep receiving a 422 response. I do not know what is wrong. I would like this to update correctly. I'm using jsonpatch to try and update this object.
I've tried numerous things. Is there something wrong with my request? I do not know.
Here my code:
return API.patch(`bmwsales/updateWeb/${vid}/`, veh, {headers: {
'Authorization' : basic }})
.then((response) =>{
if (response.status==200){
dispatch(updateVehicleSuccess());
}
}, (error) =>{
if (error.response.status == 500){
dispatch(vehicleError(error.message, "Could not update rfidtag, please try again."));
}else if
(error.response.status == 422){
dispatch(vehicleError(error.message, "Could not update rfidtag, please try again."));
}
controller:
#PatchMapping("/bmwsales/updateWeb/{id}")
public ResponseEntity<?> updateVehicleTagWeb(#PathVariable(value="id") Integer id, #RequestBody Bmwsales v) throws JsonProcessingException{
ObjectMapper objMapper=new ObjectMapper();
JsonPatchBuilder jsonPatchBuilder=Json.createPatchBuilder();
JsonPatch jsonPatch=jsonPatchBuilder.replace("/templocation",v.getTemplocation()).replace("/rfidtag", v.getRfidtag()).build();
Bmwsales vehicle=bmwService.getVin(id).orElseThrow(ResourceNotFoundException::new);
BmwsalesUpdate veh=oMapper.asInput(vehicle);
BmwsalesUpdate h=patchHelp.patch(jsonPatch, veh, BmwsalesUpdate.class);
oMapper.INSTANCE.update(vehicle, h);
return new ResponseEntity<>(h, HttpStatus.OK);
I would like to know how to fix this....
error:
xhr.js:178 PATCH http://...../bmwsales/updateWeb/69406/ 422
Looks like this is happening....there currently is no value in templocation and I'm trying to update it....how do I change my object mapper to accept that the current value can be null? I'm thinking this is the problem...maybe...
javax.json.JsonException: '{"id":69406,"rfidtag":"E200420C71A06015010B6362"}' contains no value for name 'templocation'
OK I think I fixed this....I changed my Jackson Config to comment out the setdefaultpropertyinclusion to only include non null. Now that is ok. But now instead of updating the 2 fields that I have indicated the json patch is trying to update the whole object. How do I restrict this?
Maybe you can set the consumes attribute inside the #PatchMapping with the value APPLICATION_JSON_VALUE in the class MediaType and the value field with the URL string, also check your Bmwsales object and see if all the fields matches with your request.
Hope this helps.
Related
I am making a call to Google Directory API and only need a few fields it is returning. I am fairly new to Java/Spring so I am trying to figure out what is the best way to go about this. I am making my request like this:
restTemplate.exchange(url, HttpMethod.GET, req, Object, userKey);
I currently have it as an Object, but not sure if this is correct. I do not want to map out the very large object it returns when I only need a few fields. Is there a way to access the fields, phone, organizations, locations ?
res.getClass().getField("phones") did not work for me.
For purposes we can consider the shape of the object:
{
phones: [type: String, number: String],
organizations: [title: String],
locations: [buildingId: String]
}
You can parse your response JSON as JsonNode.
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree("[your JSON here]");
After that get only fields, which you need. For example:
jsonNode.get("request").get("phones").get("type").asText()
or just a phones object
You should be able to do something like below. Here "User" is com.google.api.services.admin.directory.model.User
List<User> users = result.getUsers();
if (users == null || users.size() == 0) {
System.out.println("No users found.");
} else {
System.out.println("Users:");
for (User user : users) {
System.out.println(user.getName().getFullName());
}
}
please, this is y concern: I'll like to know how to query a web service defined as in the below code using postman for test purposes.
PS: I can't change the method signature
I have a web service like this :
#POST
#Path("/uploadOpenAccountRequestFiles/{requestId}")
#Consumes({MediaType.APPLICATION_JSON,MediaType.MULTIPART_FORM_DATA})
public Response uploadOpenAccountRequestFiles(#PathParam("requestId") String requestId,
MultipartFormDataInput multipartFormDataInput)
throws JsonGenerationException, JsonMappingException, IOException {
initContext();
logger.info("DIGIBANK : uploadOpenAccountRequestFiles END: ");
String msge = "";
try {
digiBean.saveToserver(requestId, multipartFormDataInput);
} catch (Exception e) {
msge = e.getMessage();
e.printStackTrace();
}
org.af.webservice.Response resp = new org.af.webservice.Response(
request.getSession().getId(), "uploadOpenAccountRequestFiles", "",
msge.equalsIgnoreCase("OK") ? true : false, msge.equalsIgnoreCase("OK") ? false : true, "",
msge.equalsIgnoreCase("OK") ? true : false, "Boolean", msge);
logger.info("DIGIBANK : uploadOpenAccountRequestFiles END: ");
return Response.ok().entity(mapper.writeValueAsString(resp)).build();
}
this is are images of my configurations:
enter image description here
enter image description here
For calling that service, you need to pass requestId like below:
http://localhost:8080/uploadOpenAccountRequestFiles/requestId-value-here
For sending MultiPart data such as a file, you need to select form-data option in the body section in Postman and select the file by selecting the File dropdown. Also, make sure to set the appropriate headers for the request.
Check the below stackoverflow answer for more details:
Tool for sending multipart/form-data request
The steps of uploading a file through postman along with passing some input data along with the multipart request is very well discussed in below blog along with the screenshot. In this blog, the api code is written in node js. You can go through it once. It may give some information.
https://jksnu.blogspot.com/2021/09/how-to-create-post-request-with.html
public interface UserService {
#POST(Constants.Api.URL_REGISTRATION)
#FormUrlEncoded
BaseWrapper registerUser(#Field("first_name") String firstname, #Field("last_name") String lastname, #Field("regNumber") String phone, #Field("regRole") int role);
public BaseWrapper registerUser(User user) {
return getUserService().registerUser(user.getFirstName(), user.getLastName(), user.getPhone(), user.getRole());
}
This create Exception
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
Big thanks for help.
Let's look at the error you are receiving.
Expected BEGIN_OBJECT
Your JSON is an object, and all JSON objects are enclosed in curly braces ({}). BEGIN_OBJECT is therefore {. And it's expecting it somewhere.
but was STRING
But instead he found a string "Something". Still doesn't tell us where.
at line 1 column 1 path $
Ah, perfect. At line 1 column 1. Which is the start of the JSON. So you have forgotten to enclose the whole thing in {} (or at least you have forgotten the first one, but I bet you've forgotten them both).
Recently i'd faced similiar issue and solutioned only by adding "Accept: application/json" into header section. So, if you're using retrofit 2.0;
1st solution: For post method add headers parameter like below;
#Headers({"Accept: application/json"})
#POST(Constants.Api.URL_REGISTRATION)
#FormUrlEncoded
BaseWrapper registerUser(#Field("first_name") String firstname,
#Field("last_name") String lastname,
#Field("regNumber") String phone,
#Field("regRole") int role);
2nd solution: Add header into your interceptor class like this;
NB: Code is in kotlin
private fun getInterceptor(): Interceptor {
try {
return Interceptor {
val request = it.request()
it.proceed(
request.newBuilder()
.header("Accept", "application/json")
.header("Authorization", "$accessTokenType $accessToken")
.build()
)
}
} catch (exception: Exception) {
throw Exception(exception.message)
}
}
}
Hope it helps, happy coding :)
Cleaning and rebuilding the project works for me.
If you want to add the ArrayList in the json object and parse in GSON then make sure the ArrayList should be like below.
ArrayList<JSONObject>
Instead of
ArrayList<String>
and Parse like this.
ArrayList<JSONObject> mItem = new ArrayList<JSONObject>();
mItem.add(jsonObject);
// and Use like this.
JSONArray list = new JSONArray(mItem);
jsonObject.put("Item",list);
If your app was using stored data from previous version and you changed the data type, you may encounter this error.
For example: I had something stored as a String in my previous version. I later updated the class that had the data stored in it to an object type. When I ran it, I got this error. After clearing the app-data or re-installing it, the error cleared.
Clearing the app-data might be an easy fix.
SOLUTION
In Kotlin we can use Response of ResponseBody and manage the initial response within it.
viewModelScope.launch(Dispatchers.IO) {
mainRepository.getAPIData(
Constants.getRequestBody(requestBody.toString())
).let { it ->
if (it.isSuccessful && it.code() == 200) {
val responseBody = it.body()
val res: String? = responseBody?.string()
try {
val main = JSONObject(res!!)
Log.e("TAG", "onSuccess: " + main.toString())
if (main.getInt("StatusCode") == 200) {
val type = object : TypeToken<Response>() {}.type
val response: Response = Gson().fromJson(
main.toString(), type
)
Log.e("TAG", "onSuccess: " + response.toString())
} else {
apiResponseData.postValue(Resource.error(main.getString("Message"), null))
Log.e("TAG", "onFail: " + main.toString())
}
} catch (exception: JSONException) {
Log.e("TAG", "Exception: " + exception.message)
}
}
}
}
Response - Retrofit
ResponseBody - okHttp
Response is actual model Response e.g. UserResponse
Here, getAPIData() is API call which returns Response of ResponseBody
apiResponseData is MutableLiveData
using this you can avoid JSON type cast error in response.
It's a proguard problem. In release minifyEnabled true broke the API models.
You need to add Serializable in ResponseModel and in RequestModel API
https://i.stack.imgur.com/uHN22.png
this is my servlet code
List<Group> list= dao.findgroup(user);
JSONObject json=(JSONObject) JSONSerializer.toJSON(list);
ServletResponse response=ActionContext.getServletResponse();
response.setContentType("text/JSON");
PrintWriter out=response.getWriter();
out.println(json);
out.close();
//this is my jquery code
$.get("viewgroup.process",function(data){
var use=$.parseJSON(data);
$(use).each(function(i,v)
{
var det="<tr><td>"+v.value+"</td><td>"+v.description+"</td><td>"+v.code+"</td><td>"+v.status+"</td><td><a href='#'>reset code</a></td><td><a href='#'>change status</a></td></tr>";
$(det).appendTo("#tablebody");
});
Now my problem is when i am sending this request and getting a list as json object,and when I use method parseJSON it gives me error:
SyntaxError: JSON.parse: unexpected character
Can any one tell me why this error is there?
Pretty sure the data parameter when using $.get is already a javascript object (rather than a JSON string), so no need to parse it again:
$.get("viewgroup.process",function(data){
var use = data;//or just use data directly rather that a new variable called use
$(use).each(function(i,v)
{
var det="<tr><td>"+v.value+"</td><td>"+v.description+"</td><td>"+v.code+"</td><td>"+v.status+"</td><td><a href='#'>reset code</a></td><td><a href='#'>change status</a></td></tr>";
$(det).appendTo("#tablebody");
});
//rest of code...
});
Change out.println(json); to out.println(json.toString()); in your servlet code. You want to send out the stringified JSON, not the actual object.
http://www.json.org/javadoc/org/json/JSONObject.html#toString%28%29
I have this method :
#GET
#Path("/myservice")
#Produces(MediaType.APPLICATION_JSON)
public Response mysercice() {
boolean userExists = false;
CacheControl cacheControl = new CacheControl();
cacheControl.setNoCache(true);
cacheControl.setNoStore(true);
JSONObject jsonObject = new JSONObject();
jsonObject.put("userExists", userExists);
return Response.ok(jsonObject, MediaType.APPLICATION_JSON).cacheControl(cacheControl).build();
}
When accessing to the URL of the method in the browser, I get { }, it means that the object is empty.
So, I tried to use :
return Response.ok(jsonObject.toString(), MediaType.APPLICATION_JSON).cacheControl(cacheControl).build();
So, I get in the browser {"userExists" : false}
But I didn't understand why when returning simply the JSONObject, we get in the browser an empty object.
Most JAX-RS implementations come with a provider for mapping response entities to JSON. So when you write:
return Response.ok(jsonObject, MediaType.APPLICATION_JSON).build();
You are basically requesting that the JAX-RS provider marshall the JSONObject into JSON for you. The only problem being that JSONObject isn't really meant to be serialized this way. Instead its meant to be used to build a JSON representation incrementally, then convert that representation into a JSON string value. You have two options:
Create a POJO containing all the fields you want to send back to the client. Return this POJO in your method and it will be automatically converted to JSON (`return Response.ok(myPojo, MediaType.APPLICATION_JSON).build()
Return the JSON data directly as a String (which you already did in your example that works).