Get json data from angularjs http post request thanks to servlet - json

I try to send data in JSON format from angularJS client thanks to post http request and get it thanks to j2ee servlet. But I meet a mistake. My complete data can be access thanks to getParameterNames method in my servlet and I can't get it in other way.
I don't understand why my data is the Key and not a value.
AngularJS Client
setParametersForTools : function (toolName, data) {
var jsonData = JSON.stringify(data) // I try with json and stringify json
var promise =
$http({
url: configuration.root_url_api+"SetParametersServlet?tool="+toolName,
method: "POST",
dataType: 'json',
data: data,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
.then(function (response){
console.log(response);
}, function (error){
console.log(error);
})
return promise;
}
Servlet
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String toolname = request.getParameter("tool"); //toolname is correct
String json = request.getParameter("data"); // return null...
Enumeration<String> paramsName = request.getParameterNames();
for (;paramsName.hasMoreElements();) {
String paramName=paramsName.nextElement();
System.out.println("param:"+paramName);
}
}
Servlet log
//For Parameter names
param:tool
param:{ my correct data in json format}
Maybe I don't send data correctly but after many searches I don't understand what's wrong.

Please make the following changes in your code.
setParametersForTools : function (toolName, data) {
$http.post(configuration.root_url_api+"SetParametersServlet?tool="+toolName, data)
.then(function (response){
console.log(response);
}, function (error){
console.log(error);
});
}

If you want to use json I'd suggest to implement JAX-RS service instead of Servlet, it will be much easier, especially if you will later use some more complex json.
Pseudo code for service (you will need to add jax-rs configuration to web.xml also):
#Path("/myPath")
public class MyService {
#POST
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public OutputData setParameters(InputData data, #QueryParam("tool") String tool) {
System.out.println("Input data: " + data);
System.out.println("Tool name: " + tool);
...
return outputData;
}
}
where inputData and outputData are Java objects representing json.

I found a good answer with this post.
$httpParamSerializer method fixes the problem

Related

Bad request AJAX post to Spring API

I'm sending JSON data to my Spring API but I always get a bad request. I have tried some things. At first, chanceReward was of type Map<String, Object>. Later I thought it should be a String but it still had a bad request. I researched and thought I needed consumes = "application/json" in the annotation but result is the same. Not sure anymore what to do. Below is the code for my API:
#RequestMapping(value = "/chance/{id}/saveChanceRewards", method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
public #ResponseBody Map<String, Object> saveChanceRewards(#PathVariable("id") String id,
#RequestBody String chanceRewards) {
try {
JSONArray jsonArray = new JSONArray(chanceRewards);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject JObject = jsonArray.getJSONObject(i);
System.out.println(JObject.getString("name") + " " + JObject.getString("weight"));
}
} catch(JSONException e) {
_log.error("Error parsing JSON");
}
Map<String, Object> map = new HashMap<String, Object>();
// TODO
return map;
}
Below is the ajax code (inside a .jsp):
let arrayRewards = [];
// get the data from dynamic list of text fields
for (let i = 1; i <= chanceRewardCount; i++) {
arrayRewards.push({
name: $('#chanceRewardName' + i).val(),
weight: $('#chanceRewardWeight' + i).val()
});
}
let data = {'data': arrayRewards};
let jsonData = JSON.stringify(data);
$.ajax({
type: 'post',
dataType: "json",
data: data,
contentType: 'application/json',
url: "${home}/chance/${id}/saveChanceRewards",
method: 'post',
success: function(response) {
console.log('response', response);
},
error: function(err) {
console.log('error', err);
}
});
I'm using Spring Framework 3.2.1.
The 400 Bad Request error is an HTTP status code that means that the request you sent to the website server, often something simple like a request to load a web page, was somehow incorrect or corrupted and the server couldn't understand it.
That mean the server not able to understand the request from your ajax.
First, change #RequestBody String chanceRewards to #RequestBody ChanceRewards chanceRewards
And define ChanceRewards and ChanceReward class.
class ChanceReward {
private String name;
private String weight;
// Getter Setter ...
}
class ChanceRewards {
private List<ChanceReward> data;
// Getter Setter ...
}
If still failed, try open inspect mode and click network tab to check the request send from ajax.
Replace double quotes in your url: "${home}/chance/${id}/saveChanceRewards", by backtick.
There are quite a few things going on here, so let's work on them!
First, I see you've stringified the data into jsonData, but your actual ajax post has data: data instead. Easy fix, just swap in the right variable.
Second thing I notice is that you're wrapping the rewards array in an object (with data = {'data': arrayRewards}) but your Java code expects the array itself (JSONArray) right out of the request body. So this will also throw an exception. You don't have to wrap the array with an object if it's not needed.
Lastly, you mention that you always get a "bad request", but what exactly do you mean? An "HTTP 400" error? Some other HTTP error? It might be useful to give more info on the exact error(s) you see on the javascript side and on the Java server side.
All the other things like worrying about making a ChanceReward / ChanceRewards class, accepts/consumes/produces headers, etc., are superfluous at this point. They are boilerplate niceties and you don't need any of them for this to work correctly.

Why is string/json sent in post request to .netcore web api resulting in null?

I have an array that I'm converting to JSON using JSON.stringify
const arrayOfUpdatesAsJSON = JSON.stringify(this.ArrayOfTextUpdates);
This outputs some valid JSON.
[{"key":"AgentName","value":"Joe Blogs"},{"key":"AgentEmail","value":"Joe#test.com"}]
As I'm going to be sending JSON to the server I set the content type to application/json
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
})
};
When a button is pressed I make the request with the url, body and header.
try {
this.httpservice
.post(
url,
arrayOfUpdatesAsJSON,
httpOptions
)
.subscribe(result => {
console.log("Post success: ", result);
});
} catch (error) {
console.log(error);
}
This works fine and hits the method I'm expecting inside the api.
[HttpPost("{id:length(24)}", Name = "UpdateLoan")]
public IActionResult Update(string id, string jsonString)
{
Console.WriteLine(jsonString);
... and some other stuff
}
The ID is populated inside the url builder which populates ok. I would then expect the contents of my variable jsonString inside the api to be populated with the json of my request however it is always null. What am I missing?
Firstly you need to mark jsonString with [FromBody] to tell model binder bind the parameter from posted json. And because you are expecting plain string value you need to pass valid json string (not object) so you need to call additional JSON.stringify in javascript
const jsonArray = JSON.stringify(this.ArrayOfTextUpdates);
const arrayOfUpdatesAsJSON = JSON.stringify(jsonArray);
this.httpservice
.post(
url,
arrayOfUpdatesAsJSON,
httpOptions
)
Controller
[HttpPost("{id:length(24)}", Name = "UpdateLoan")]
public IActionResult Update(string id, [FromBody] string jsonString)

How to retrieve JSON data in controller in ASP.net Core?

i need to get data sent with JSON and save to model in asp.net controller
//JSON data
var dataType = 'application/json';
var data = {
ID: 'Zaki',
}
console.log('Submitting form...');
console.log(data);
$.ajax({
type: 'POST',
url: 'Save',
dataType: 'json',
contentType: dataType,
data: data,
success: function (result) {
console.log('Data received: ');
console.log(result);
}
});
Controller
[HttpPost]
public ActionResult Save([FromBody] string ID)
{
return Json (ID);
}
am getting null in console , it supposed to be zaki and from there i wanna write saving code...
Another way to do it is to simply use 'dynamic' type to handle json request data. Take a look:
[HttpPost]
public IActionResult YoutMethod([FromBody] dynamic requestData)
{
Log.Information(requestData.field1);
Log.Information(requestData.field2);
// ...
return Ok();
}
Modify this line in your code data: data, to
data:JSON.stringify(data)
When sending data to a web server, the data has to be a string and JSON.stringify method converts a JavaScript object into a string.
Another approach would be, instead of getting raw string value, wrap your parameter into a class object like this
public class ParamObj
{
public string ID{get;set;}
}
and in your controller get a parameter of this object type like this..
public ActionResult Save([FromBody] ParamObj data)
Thanx
I know that is already marked as answered, but here is another way to do it:
I am not using the binding FromBody attribute.
Controller
public class JsonRequest
{
public string Id { get; set; }
}
[HttpPost]
public ActionResult Save(JsonRequest data)
{
return Json(data.Id);
}
Instead of using dataType I am using accept and you don't need to convert your json into a string.
To avoid problems with relative paths I am using: url: '#Url.Action("Save", "Home")' as well.
Javascript
function send()
{
//JSON data
var dataType = 'application/json';
var data = {
"id": "Zaki"
}
console.log('Submitting form...');
console.log(data);
$.ajax({
type: 'POST',
url: '#Url.Action("Save", "Home")',
accept: dataType,
data: data,
success: function (result) {
console.log('Data received: ');
console.log(result);
}
});
}
Good luck with your project.

Watson SpeechToText Java and javascript model differences

I'm working on integrating the watson-speech.js javascript library with a Spring-based server using the Watson Java SDK. I'm trying to send the output from a WatsonSpeech.SpeechToText.recognizeMicrophone call to the server with no luck. The Speech java classes appear to have the appropriate #SerializedName annotations that match the json being sent from the client, but I'm getting UnrecognizedPropertyException errors from Jackson.
Unrecognized field "keywords_result" (class com.ibm.watson.developer_cloud.speech_to_text.v1.model.SpeechResults), not marked as ignorable (2 known properties: "resultIndex", "results"])
Here's the controller method:
#RequestMapping(value = "/postWatsonRequest", method = RequestMethod.POST)
#ResponseBody
#ResponseStatus(value=HttpStatus.OK)
public ResponseObject postWatsonRequest(#RequestBody SpeechResults speechResults) {
...
}
I'm clearly missing something. Do I need to unpack the json manually on the server side (custom deserializer?) or format it into an acceptable json string on the client side?
It turned out to be a couple of mistakes on my part and although I'm not sure this is the best solution it does work. Here's the full code for anyone that's interested. Key things that made it work:
You must use the receive-jason event to capture the full json result. The data event appears to only return the final text
The result data had to be wrapped in a valid json wrapper - data:{message:data} (this was my big mistake)
Do not include contentType: 'application/json; charset=utf-8', in the ajax call or the controller will not recognize the json data
The Watson Java SDK WebSocketManager receives an okhttp3.ResponseBody from Watson from which it extracts a string. I presume this is similar to what the javascript SDK receives so I used the same code from the WebSocketManager to convert the JSON.stringify string to a SpeechResults object in the controller.
From the okhttp3.ResponseBody javadoc:
A one-shot stream from the origin server to the client application with the raw bytes of the response body
Watson javascript
function listen(token) {
stream = WatsonSpeech.SpeechToText.recognizeMicrophone({
token: token,
readableObjectMode: true,
objectMode: true,
word_confidence: true,
format: false,
keywords: keywordsArray,
keywords_threshold : 0.5,
continuous : false
//interim_results : false
//keepMicrophone: navigator.userAgent.indexOf('Firefox') > 0
});
stream.setEncoding('utf8');
stream.on('error', function(err) {
console.log(err);
stream.stop();
});
stream.on('receive-json', function(msg) {
console.log(msg);
if (msg.state != 'listening') {
if (msg.results[0].final) {
console.log('receive-json: ' + msg);
postResults(msg);
stream.stop();
}
}
});
}
Ajax post
function postResults(results) {
var data = JSON.stringify(results);
console.log('stringify: ' + data);
$.ajax({
type: 'POST',
url: appContextPath + '/postWatsonResult',
dataType: 'json',
data: {message:data}
})
.done(function(data) {
console.log('done data: '+ data);
})
.fail(function(jqXHR, status, error) {
var data = jqXHR.responseJSON;
console.log('fail data: '+ data);
});
}
Spring controller
#RequestMapping(value = "/postWatsonResult", method = RequestMethod.POST)
#ResponseBody
#ResponseStatus(value=HttpStatus.OK)
public ResponseObject postWatsonResult(#RequestParam("message") String message, Locale locale) {
logger.info("postWatsonRequest");
JsonObject json = new JsonParser().parse(message).getAsJsonObject();
SpeechResults results = null;
if (json.has("results")) {
results = GSON.fromJson(message, SpeechResults.class);
}
if (results != null) {
logger.debug("results: " + results.getResults().get(0).getAlternatives().get(0).getTranscript());
}
return new ResponseObject();
}
I still think it should be possible somehow to use #RequestBody SpeechResults speechResults so I'll continue to play around with this, but at least I have a working solution.

400 Bad Request while posting Json Object

i am trying to post jsonObject from jsp to controller and i am getting 400 Bad Request Error.
My jsp code
$.ajax({
url : 'save.web',
type: "post",
dataType: 'json',
contentType:'application/json',
data: "data="+JSON.stringify(jsonArray),
success:function(data){
}
});
});
My json Object
var jsonArray="{"+'"'+"cds"+'"'+":"+"[";
for(i=0;i<newRow.length;i++)
{
jsonArray=jsonArray+"{"+'"'+"dno" +'":'+newRow[0]+","+'"'+"CampaignCode"
+'":'+newRow[1]+"," +'"'+"CampaignName"+'":'+newRow[2]+","
+'"'+"ServiceNo" +'":'+newRow[3]+"}";
}
jsonArray=jsonArray+"]}";
My controller Code
#RequestMapping(value = "/save.web", method = RequestMethod.POST)
#ResponseBody
public String save(WebRequest webRequest,Model model,HttpServletRequest
request, HttpServletResponse response,#RequestParam CampaignDisplay[] cds)
{
for(CampaignDisplay inputs : cds){
System.out.println(inputs.getId());
}
return "menu";
}
input Json Object which i am passing is
{"cds":[{"dno":8,"CampaignCode":d,"CampaignName":e,"ServiceNo":f},
{"dno":7,"CampaignCode":a,"CampaignName":b,"ServiceNo":c}]}
I dont know why ia m getting 400 erro? i ahve set the headers also
seems the controller is not able to understand the request. The reason is "You are posting JSON, not form data, but you are trying to read as a form parameter".
change your method to
**public String save(WebRequest webRequest,Model model,HttpServletRequest
request, HttpServletResponse response,#RequestBody Map<String, Object> inputParameter)
{**
Check this link for your reference 400 Bad request on Spring Jquery Ajax Post