400 Bad Request while posting Json Object - json

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

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.

Spring MVC to send responsebody object to ajax post gives 406 error

There are similar links but I haven't found any solution to work for me, so I was wondering if someone could give me a working example for my scenario. I am doing an ajax get to retrieve data from the server side, so I can create charts dynamically on the client side. Do I need to include MappingJacksonHttpMessageConverter? If that's the answer can someone provide an example i can follow for that?
Java:
#RequestMapping(value="/getReportData.html", method=RequestMethod.GET, produces="application/json")
public #ResponseBody Reports getReport1Data(HttpServletRequest request)
{
System.out.println("Report 1 Page GET Method");
ModelAndView mv = new ModelAndView("report1");
if((Reports)request.getSession().getAttribute(USER_SESSION_REPORTS) != null){
reports = (Reports)request.getSession().getAttribute(USER_SESSION_REPORTS);
System.out.println("--------> Report 1 Page with session data");
return reports;
}
else{
System.out.println("--------> Report 1 Page with NO session data");
}
mv.addObject("report1", reports.getReport1());
return null;
}
Javascript:
function getData(){
$.ajax({
url: "getReportData.html",
type: "GET",
contentType: "application/json",
dataType: JSON,
success: function(report1){
console.log("success: " + report1.utilRatio.decRatio);
},
error: function(report1){
console.log("error: " + report1.utilRatio.decRatio);
}
});
}
Response Headers:
Content-Language: "en",
Content-Length: "1110"
Content-Type: "text/html;charset=utf-8"
Server: "Apache-Coyote/1.1"
Request Headers:
Accept: "/"
Accept-Language: "en-US,en;q=0.5"
Accept-Encoding: "gzip,deflate"
Content-Type: "application/json"
X-Requested-With: "XMLHttpRequest"
It looks like your request headers are wrong. You can remove the contentType setting since you are not sending data to the server and change dataType to the string value "json" instead of the variable JSON.
Also, your response headers are wrong. Just make sure you are always returning a Reports object. And you probably want to remove the html extension from that endpoint since you're just returning an object.
spring uses #ResponseBody annotaion for returning data as json .it will implicitly call the MappingJacksonHttpMessageConverter .so you need to use it.
#RequestMapping(value = "/getjson", method = RequestMethod.POST, produces = "application/json")
#Transactional
public void getJson(HttpServletRequest request, HttpServletResponse response, #RequestParam("type") String type)
throws DatatypeConfigurationException, IOException, JSONException {
JSONObject json = new JSONObject();
Map<String, String[]> parameterMap = request.getParameterMap();
List<Chart> chart=myService.getChart();
if (Chart.size()>0) {
json.put("status", "SUCCESS");
JSONArray array = new JSONArray();
for (Chart chartData: chart) {
JSONObject object = new JSONObject();
object.put("id", chartData.getRaasiId());
object.put("name", chartData.getName());
array.put(object);
}
json.put("options", array);
}
}
}
response.setContentType("application/json");
System.out.println("response======" + json.toString());
PrintWriter out = response.getWriter();
out.write(json.toString());
}
============
on the html
jQuery
.ajax({
url : controllerUrl,
dataType : 'text',
processData : false,
contentType : false,
type : 'GET',
success : function(response) {
success : function(response) {
marker = JSON.stringify(response);
json = jQuery.parseJSON(marker);
json = JSON.parse(json);
alert(json.status);
}
});
for reference:
https://rwehner.wordpress.com/2010/06/09/2-ways-to-create-json-response-for-ajax-request-in-spring3/

Get json data from angularjs http post request thanks to servlet

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

respond to http request with json object in portlet

I am a beginner in liferay portlet development and I am developing a portlet that receives a http get request, processes some information and than it has to return a json object. My problem is that my portlet sends a whole html page instead of just the json object.
This is my code:
HttpServletResponse servletResponse = PortalUtil.getHttpServletResponse((renderResponse));
servletResponse.setHeader("Content-type", "application/json");
servletResponse.setCharacterEncoding("application/json");
PrintWriter out = servletResponse.getWriter();
out.write(EntityUtils.toString(responseEntity));
out.flush();
out.close();
I execute this in the doView() method I know that this is not the best practice, but I am not concerned with that at the moment. Can someone explain to me how to return just the json object I read something about serveResponse, but I couldn't figure out how to invoke it.
Well, one thing to notice, that the doView() is mostly responsible for rendering of your portlet. Your requirement can better achieved by
1 - processAction(Portlet Action) or
2 - serveResource(Portlet AJAX service).
To my view, AJAX request-response will be the most suitable case; for that you just need to create a resource URL on your portlet view. Like:
<portlet:resourceURL var="ajaxResourceURL" />
Add a JavaScript method to the page, from where you can generate AJAX request to your portlet. The method will look something like this,
<script type="text/javascript">
function _callAjax(val1, val2){
var url = '<%=ajaxResourceURL %>'; // pass resource URL you created using scriplet / EL.
jQuery.ajax({
type : "POST",
url : url,
cache:false,
dataType: "json",
data: {
value1: val1, // extra parameters if you want to pass
value2: val2
},
success : function(data){
// do whatever you want with your response data
},
error : function(XMLHttpRequest, textStatus, errorThrown){
alert(errorThrown);
alert(textStatus);
}
});
};
</script>
Call that ajax method on a button / link click event:
<input type="button" onclick="_callAjax('val1', 'val2')" value="Send" />
And finally, in your portlet's action listener class add the following serveResource method, responsible for handling AJAX based request(s).
Here you can get your request parameters and generate a response in the sense you want:
#Override
public void serveResource(ResourceRequest request, ResourceResponse response) throws PortletException,IOException {
String value1 = ParamUtil.getString(request , "value1", "default"); // request parameters
String value2 = ParamUtil.getString(request , "value2", "");
PrintWriter writer = response.getWriter();
JSONObject jsonObject = new JSONObject();
jsonObject.put(String key, boolean/long/Collection/double/Map/Object value);
writer.write(jsonObject.toString());
}
Thats it! Hope, this will be helpful for you :)

Is there a way to deserialize json into complex objects with spring mvc 3.1?

I'm trying to figure out a way to pass a complex object via json with spring mvc 3.1. I am also using knockoutjs, so take the ko.toJSON to be equivalent to JSON.stringify.
DeployT
here is the ajax call:
$.ajax({
url: "/doAction",
type: "post",
data: ko.toJSON({"complexObjectA": ko.toJSON(self.complexObjectA()), "complexObjectB": ko.toJSON(self.complexObjectB()), "id": "", "text": ""}),
dataType: "json",
contentType: "application/json; charset=utf-8",
// callback handler that will be called on success
success: function (response, textStatus, jqXHR) {
//dosomething
},
// callback handler that will be called on error
error: function (jqXHR, textStatus, errorThrown) {
// log the error to the console
},
// callback handler that will be called on completion
// which means, either on success or error
complete: function () {
//dosomething
}
});
The spring controller code looks like:
#RequestMapping(value = "/doAction", method = RequestMethod.POST)
#ResponseBody
public String doAction(#RequestBody MyForm form, HttpServletRequest request, HttpServletResponse response) {
and MyForm is defined as such:
public class MyForm {
private ComplexObjectA complexObjectA;
private ComplexObjectB complexObjectA;
private String id;
private String text;
with the appropriate public getter/setters.
When I attempt to make this call, I get a error 400
The request sent by the client was syntactically incorrect ().
The complex objects are both obtained via a json get earlier and they get serialized just fine from the object to json and into js objects.
Do I need to create a special deserializer with Jackson in order to do this?
As you say that your complex objects serialized successfully before, I can guess that your Spring config files are okay and Jackson is configured properly. I think that you don't need to create a separate serializer/deserializer for MyForm class.
A 400 error "bad request" can come up for example if you make your jQuery AJAX call when a user clicks a link with a non-empty href, so the browser tries to perform the default action. In that case you can see that a request header still has the type "text/html", though you are trying to send "application/json".