Send Json Object to Spring Controller - json

Hy guys.
I have this js code, where I create an object to send to a Spring controller via Ajax function:
$('#eventsdatageneral').on('click', '.btn.btn-info', function(event)
{
var today_date = new Date().getTime();
var dataToSend = new Object();
dataToSend.dateToSend = today_date;
dataToSend.nameToSend = host_name;
dataToSend.typeToSend = type_name;
console.log(dataToSend);
event.preventDefault();
//here starts the code to sending data to Spring controller
$.ajax({
url: "../todaydatarecover.json",
type: "post",
data: dataToSend,
success : function() {
console.log("Invio riuscito.");
//console.log(moment(today_date).format('DD/MM/YYYY'));
}
});
});
This is the controller:
#PostMapping(value="/todaydatarecover.json")
#ResponseBody
public ModelAndView todayInfoAndIdRecover(ModelAndView model, HttpServletRequest request,
#RequestParam(name="dateToSend", required=false) long dateInBox,
#RequestParam(name="nameToSend", required=false) String nameInBox,
#RequestParam(name="typeToSend", required=false) String typeInBox) throws IOException
{
//First of all, we invoke getinfo methods to take info and id
Timestamp date = new Timestamp(dateInBox);
Events event = networks.getInfoandId(nameInBox, typeInBox, date);
//Second, we put this list in the model and set properties for jquery datatables
model.addObject("data", event);
//Verify id and info
System.out.println("The info is: " + event.getInfo());
System.out.println("The id is: " + event.getId());
//Finally, we return the model
return model;
}
When I try to execute, i got an org.springframework.dao.EmptyResultDataAccessExceptionIncorrect result size: expected 1, actual 0; but, if I query the DB via MySQL client, i can take the correct result without problems. So, there is a row that match the query I perform; this make me think that the problem is how I create the Json Object and/or I send it to Controller.
What's my error?

When sending informations with data, it's in the request's body, you can't retrieve your data with #RequestParam. You need to use #RequestBody and create and object with your three variables.
Example :
#PostMapping(value="/todaydatarecover.json")
#ResponseBody
public ModelAndView todayInfoAndIdRecover(#RequestBody TodayData todayData, ModelAndView model, HttpServletRequest request) throws IOException
{

Related

Spring Boot Ajax Parse Error - cannot return object to ajax success fn

I am sending a value through a jquery ajax call to my spring controller. I want it to send an object back to populate a form in an iziModal. Currently, it sends the value from the browser back to my controller, and runs through my method in my controller, but then I get stuck. For some reason I'm having issues sending the response back to my ajax success function.
I am getting this parse error: SyntaxError: Unexpected token t in JSON at position 1556482
Here is my controller method:
#RequestMapping(value="/editCarrierAjax", method= RequestMethod.POST)
public #ResponseBody CarrierAppointment getCarrierDets (#RequestParam("data") String data, MasterCarrier masterCarrier, Model model) throws Exception{
CarrierAppointment carrierToEdit = carrierAppointmentRepository.findById(Long.parseLong(data));
model.addAttribute("carrierToEdit", carrierToEdit);
return carrierToEdit;
}
Ajax Call:
$('.trigger-edit-carrier').on('click', function(event){
var selectId = $(this).attr('value');
console.log(selectId);
var token = $("meta[name='_csrf']").attr("content");
console.log(token);
var header = "X-CSRF-TOKEN";
console.log(header);
$.ajax({
type: "POST",
url: "/editCarrierAjax",
data: {data:selectId},
dataType:"json",
cache: false,
timeout: 600000,
beforeSend: function(xhr) {
xhr.setRequestHeader(header, token);
console.log(header +", "+ token);
},
success: function(data, jqXHR){
console.log("success fn");
console.log(data);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("Status: " + textStatus); alert("Error: " + errorThrown);
}
});
});
I've tried adding the Jackson library mentioned here Convert a object into JSON in REST service by Spring MVC
but it still throws an error. Any idea how to fix this error?
It seems like your data returned by method is having issue in parsing JSON. sometimes it happens due to some special characters in data. Could you just try to log carrierToEdit( System.out.println(carrierToEdit);
) on server side and see its value? probably it will be very BIG string content and id you put it in any text editor and go to position 1556482 you will see t which is causing this...
SyntaxError: Unexpected token t in JSON at position 1556482
also if your data in not sensitive you can try to validate it online using some JSON validator tools like https://jsonlint.com/
You can find the issue there and some minor changes in data/code would fix your parsing issue...
#RequestMapping(value="/editCarrierAjax", method= RequestMethod.POST)
public #ResponseBody CarrierAppointment getCarrierDets (#RequestParam("data") String data, MasterCarrier masterCarrier, Model model) throws Exception{
CarrierAppointment carrierToEdit = carrierAppointmentRepository.findById(Long.parseLong(data));
System.out.println(carrierToEdit);
model.addAttribute("carrierToEdit", carrierToEdit);
return carrierToEdit;
}
Hope this Helps... All the Best :)
The fact that you get a 400 bad request status code returned if you set contentType and dataType to json (maybe try out application/json!) in your jQuery code could relate to controller misconfiguration. If all of your controller methods process JSON (receive JSON payload in requestbody, respond with JSON payload in responsebody) then you could try to set the #RestController annotation at your controllers class-level - this annotation also implicitly adds a #ResponseBody annotation and configures all controller methods to consume and produce content of type application/json. E.g. like this:
#RestController
public class YourControllerClass {
#PostMapping("/editCarrierAjax")
public CarrierAppointment getCarrierDets(#RequestParam("data") String data, MasterCarrier masterCarrier, Model model) throws Exception {
CarrierAppointment carrierToEdit = carrierAppointmentRepository.findById(Long.parseLong(data));
model.addAttribute("carrierToEdit", carrierToEdit);
return carrierToEdit;
}
}
The other option would be to explictly configure this single controller method, to consume/produce JSON, e.g. like this:
#Controller
public class YourControllerClass {
#ResponseBody
#RequestMapping(value="/editCarrierAjax", method= RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public CarrierAppointment getCarrierDets(#RequestParam("data") String data, MasterCarrier masterCarrier, Model model) throws Exception{
CarrierAppointment carrierToEdit = carrierAppointmentRepository.findById(Long.parseLong(data));
model.addAttribute("carrierToEdit", carrierToEdit);
return carrierToEdit;
}
}
Please share your whole controller and CarrierAppointment class if any of those approaches don't fix your issue. You should also validate the generated JSON that is sent back to your client as #Programmer suggested. Good luck!

updating JSON Object in spring restful web services

I want to pass a json object for the update function but its doesn't accept the json object and get an error. The error is:
the code is:
(value = "/UpdateUser/", method = RequestMethod.PUT , consumes=MediaType.APPLICATION_JSON_VALUE)
public void UpdateUser(JSONObject RequiredObject)throws UnknownHostException {
// RequiredObject=new HashMap<>();
System.out.println("hello into update " + RequiredObject);
// readJSON.UpdateUser(RequiredObject);
}
you have to receive the body of your request as a #RequestBody and you can receive this json object as a User object directly
#RequestMapping(value = "/UpdateUser/", method = RequestMethod.PUT ,
consumes=MediaType.APPLICATION_JSON_VALUE)
public void UpdateUser(#RequestBody User user) throws UnknownHostException {
// RequiredObject=new HashMap<>();
System.out.println("hello into update " + RequiredObject);
//readJSON.UpdateUser(RequiredObject);
}

How to pass request for a delete method in junit

Hi I have a json request which I have to pass in my junit testcase but the request is delete as delete do not support setEntity method. How can I pass the request in my testcase.
Json request which I have to pass
{
"userId":"AJudd",
"siteId":"131",
"alternateSiteId":"186"
}
mytest case for this
#Test
public void testdeleteAltSite() throws ClientProtocolException, IOException {
String resultCode = "001";
String resultText = "Success";
String url = "http://localhost:8080/adminrest1/alternatesite";
HttpClient client = HttpClientBuilder.create().build();
HttpDelete delete = new HttpDelete(url);
// add header
delete.addHeader("Transaction-Id", "11");
delete.addHeader("content-type", "application/json");
LOG.info(url);
HttpResponse response = client.execute(delete);
byte[] buf = new byte[512];
InputStream is = response.getEntity().getContent();
int count = 0;
StringBuilder builder = new StringBuilder(1024);
while ((count = is.read(buf, 0, 512)) > 0) {
builder.append(new String(buf, 0, count));
}
String output = builder.toString();
System.out.println(output);
}`
How to pass the json value so that the passed value data can be deleted?
IMHO this is a problem with your design.
If your intent is to delete an alternate site and its id is unique then passing the alternateSiteId as part of the URI should sufficient:
Method: DELETE
URL: http://localhost:8080/adminrest1/alternatesite/{alternateSiteId}
If alternateSiteId is not unique then you are updating a relationship. In that case you should use a PUT which allows you to include a body in your request. Please note you should pass the id of the resource you are updating as part of your URI, for example:
Method: PUT
URL: http://localhost:8080/adminrest1/alternatesite/{userId}
Body:{
"siteId":"131",
"alternateSiteId":"186"
}
Ok, first of all: Sending a body with a DELETE is not what usually happens around the internet. Nevertheless, it is not forbidden (Is an entity body allowed for an HTTP DELETE request?). So, two ideas:
1) New class
I assume you use org.apache.http.client: Just extend HttpEntityEnclosingRequestBase:
public class HttpDeleteWithEntity extends HttpEntityEnclosingRequestBase {
public final static String METHOD_NAME = "DELETE";
public HttpDeleteWithEntity() {
super();
}
public HttpDeleteWithEntity(final URI uri) {
super();
setURI(uri);
}
public HttpDeleteWithEntity(final String uri) {
super();
setURI(URI.create(uri));
}
#Override
public String getMethod() {
return METHOD_NAME;
}
}
This is basically c&p'ed from the HttpPost class. I did not test this, tho.
Then use your HttpDeleteWithEntity class instead of HttpDelete.
2) Use custom headers
If you can modify your server code that might be a good alternative.
delete.addHeader("testwith", jsonString);
or
delete.addHeader("userId","AJudd");
delete.addHeader("siteId","131");
delete.addHeader("alternateSiteId","186);
Finally, if you are in charge of the server implementation I would recommend to implement DELETE requests without any body (see artemisian's answer).

Return "View" inside "Json" with Spring MVC

I'm using Spring MVC, and I need return in the Controller, a Json object that contains the view, by example, the related jsp page.
return: { name: "fragment-form", other-info:"other-info", view: view}
where "view" should be the JSP page linked to your ModelAndView
I read other post, but I not find the solution, because I need that controller to the work, if it's posible.
Sugestions?
EDIT:
I have a form with your values, and the submit, from javascript execute this follow code:
#RequestMapping(method = RequestMethod.POST)
public Object create(#Valid #RequestBody PatientForm form, HttpServletResponse response) {
ModelMap map = new ModelMap();
map.put("form", form);
return new ModelAndView("addPatientForm", map);
}
I need return a Json where the "ModelAndView("addPatientForm", map)" processed within the json that is returned.
Would something like this work for you:
#RequestMapping(value="/somepage", method=RequestMethod.POST)
public ResponseEntity<String> generateViewasJSON(){
JSONObject json = new JSONObject();
json.put("name","fragment-form");
...
HttpHeaders headers = new HttpHeaders();
headers.set( "Content-Type", "application/json" );
return new ResponseEntity<String>( json.toString(), headers, HttpStatus.OK );
}

Restlet implementing post with json receive and response

First, what i wanted to know is what i am doing is the right way to do it.
I have a scenario where i have will receive a json request and i have to update the database with that, once the db is updated i have to respond back with the json acknowledgment.
What i have done so far is create the class extending application as follows:
#Override
public Restlet createRoot() {
// Create a router Restlet that routes each call to a
// new instance of ScanRequestResource.
Router router = new Router(getContext());
// Defines only one route
router.attach("/request", RequestResource.class);
return router;
}
My resource class is extending the ServerResource and i have the following method in my resource class
#Post("json")
public Representation post() throws ResourceException {
try {
Representation entity = getRequestEntity();
JsonRepresentation represent = new JsonRepresentation(entity);
JSONObject jsonobject = represent.toJsonObject();
JSONObject json = jsonobject.getJSONObject("request");
getResponse().setStatus(Status.SUCCESS_ACCEPTED);
StringBuffer sb = new StringBuffer();
ScanRequestAck ack = new ScanRequestAck();
ack.statusURL = "http://localhost:8080/status/2713";
Representation rep = new JsonRepresentation(ack.asJSON());
return rep;
} catch (Exception e) {
getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);
}
My first concern is the object i receive in the entity is inputrepresentation so when i fetch the jsonobject from the jsonrepresentation created i always get empty/null object.
I have tried passing the json request with the following code as well as the client attached
function submitjson(){
alert("Alert 1");
$.ajax({
type: "POST",
url: "http://localhost:8080/thoughtclicksWeb/request",
contentType: "application/json; charset=utf-8",
data: "{request{id:1, request-url:http://thoughtclicks.com/status}}",
dataType: "json",
success: function(msg){
//alert("testing alert");
alert(msg);
}
});
};
Client used to call
ClientResource requestResource = new ClientResource("http://localhost:8080/thoughtclicksWeb/request");
Representation rep = new JsonRepresentation(new JSONObject(jsonstring));
rep.setMediaType(MediaType.APPLICATION_JSON);
Representation reply = requestResource.post(rep);
Any help or clues on this is hight appreciated ?
Thanks,
Rahul
Using just 1 JAR jse-x.y.z/lib/org.restlet.jar, you could construct JSON by hand at the client side for simple requests:
ClientResource res = new ClientResource("http://localhost:9191/something/other");
StringRepresentation s = new StringRepresentation("" +
"{\n" +
"\t\"name\" : \"bank1\"\n" +
"}");
res.post(s).write(System.out);
At the server side, using just 2 JARs - gson-x.y.z.jar and jse-x.y.z/lib/org.restlet.jar:
public class BankResource extends ServerResource {
#Get("json")
public String listBanks() {
JsonArray banksArray = new JsonArray();
for (String s : names) {
banksArray.add(new JsonPrimitive(s));
}
JsonObject j = new JsonObject();
j.add("banks", banksArray);
return j.toString();
}
#Post
public Representation createBank(Representation r) throws IOException {
String s = r.getText();
JsonObject j = new JsonParser().parse(s).getAsJsonObject();
JsonElement name = j.get("name");
.. (more) .. ..
//Send list on creation.
return new StringRepresentation(listBanks(), MediaType.TEXT_PLAIN);
}
}
When I use the following JSON as the request, it works:
{"request": {"id": "1", "request-url": "http://thoughtclicks.com/status"}}
Notice the double quotes and additional colon that aren't in your sample.