I am trying to save checkbox values in localstorage using map. so that i can filter result using map. I am able to store map key-values in localstorage using javascript. but later when i retreive and pass map from localstorage to controller, I am getting map with null values.
this is my code
store map in localstorage
$(':checkbox[name=brand]').on('change', function() {
var assignedTo = $(':checkbox[name=brand]:checked').map(function() {
return this.id;
}).get();
localStorage.setItem('brands', JSON.stringify(assignedTo))
});
localstorage
passing to controller
$.ajax({
type : "POST",
url : "filter",
data : {
txtMaxAge : localStorage.getItem('txtMaxAge'),
brands : JSON.parse(localStorage.getItem("brands"))
}, // parameters
success : function(result) {
// alert('changed');
}
});
controller
#RequestMapping("/filter")
#ResponseBody
public String filter(
#RequestParam(value = "txtMaxAge", required = false) String txtMaxAge,
#RequestParam(value = "brands", required = false) Map<String, String> brands,
HttpServletRequest request, HttpServletResponse response) {
System.out.println("max"+txtMaxAge);
System.out.println("printing map----");
for (Map.Entry<String,String> entry : brands.entrySet())
System.out.println("Key = " + entry.getKey() +
", Value = " + entry.getValue());
return "send data";
}
I am getting this error
max10000000
printing map----
2018-12-15 13:37:59.142 WARN 13672 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver :
Resolved [java.lang.NullPointerException] to ModelAndView: reference to view with name 'error';
model is {errorTitle=Contact Your Administrator!!, errorDescription=java.lang.NullPointerException
What i am doing wrong here?
The problem is that brands is not map type,it is an array of strings. Change the type accordingly and it should work.
Try to change your controller code:
#RequestMapping(value = "/filter")
#ResponseBody
public String filter(
#RequestParam(value = "txtMaxAge", required = false) String txtMaxAge,
#RequestParam(value = "brands[]", required = false) String[] brands,
HttpServletRequest request, HttpServletResponse response) {
System.out.println("max " + txtMaxAge);
System.out.println("map " + brands);
return "send data";
}
if you really want brands in a Map ; here's my take on it.
Here my controller
#RequestMapping(value = "/filter", method = RequestMethod.POST)
public String submission(#RequestParam("brands")String brands) {
try {
JSONParser parser = new JSONParser();
JSONObject ob = (JSONObject)parser.parse(brands);
Map<String,String> mp = new HashMap<>();
mp.put(ob.keySet().toString(), ob.values().toString());
for(Map.Entry<String,String> entry : mp.entrySet()) {
System.out.println("Key = " + entry.getKey() +
", Value = " + entry.getValue().toString());
}
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "home";
}
Here's my ajax call,
$.ajax({
type: "POST",
url: "${pageContext.request.contextPath}/Submit",
data: {
brands: localStorage.getItem("brands")
},
success : function() {
console.log('done');
}
});
Related
I am coming across an issue trying to send long strings of JSON to a MVC controller. First let me explain the need, then I will explain what I have tried. I am preserving the HTML of the UI for a table into SQL. That way I can pull it back out and render it later. That being said, when I try to send from AJAX post to the controller, I keep getting the error that JSON max length has been hit.
What have I tried?
I have tried changing all settings in the web config and in the JSON serializer in the MVC controller to the int.MaxLength values. I have also changed my controller result to a content results instead of JsonResult. Here is some of the current code I use (stripped all unnecessary code and left what is needed for troubleshooting).
Controller:
[HttpPost]
[ValidateInput(false)]
/// <summary>
/// Inserts / updates a new saved quote template
/// </summary>
/// <param name="jsonData"></param>
public ActionResult SaveQuoteTemplate(string htmlTemplate, int totalRecords, int totalBadRecords, string templateName, string templateDescription, string templateNotes, string templateId)
{
var serializer = new JavaScriptSerializer() { MaxJsonLength = int.MaxValue };
// For simplicity just use Int32's max value.
// You could always read the value from the config section mentioned above.
var returnData = new
{
StatusCodeEntity = ReturnCodeHandler.Status400,
StatusMessage = "Unkown error occurred while trying to save the template.",
};
var resultSet = new ContentResult
{
Content = serializer.Serialize(returnData),
ContentType = "application/json"
};
try
{
JsonModel<QuoteEntitySavedItemVM> jsonModel = new JsonModel<QuoteEntitySavedItemVM>();
if (!String.IsNullOrEmpty(htmlTemplate))
{
string userPrefix = Session["LoginID"] != null ? Session["LoginID"].ToString() : string.Empty;
QuoteEntitySavedItemVM qsvm = new QuoteEntitySavedItemVM()
{
JSON = htmlTemplate,
CreationDate = DateTime.Now,
Description = templateNotes,
TotalRecords = totalRecords,
TotalBadRecords = totalBadRecords,
Name = String.Format("{0} - {1}", userPrefix, templateName),
Id = QPortal.Web.Helpers.Utilities.SafeToInt32(templateId) //convert to int or safely returns 0 if null
};
qsvm.Id = _quoteEntityService.SavedQuoteTemplate(qsvm); //returns project id. So will now assign new on or same if update ran
if (qsvm.Id == -1)
{
var badReturn = new
{
StatusCodeEntity = ReturnCodeHandler.Status400,
StatusMessage = "There is already a project with this name. Please change name.",
ObjData = new List<QuoteEntitySavedItemVM>() { qsvm }
};
resultSet = new ContentResult
{
Content = serializer.Serialize(badReturn),
ContentType = "application/json"
};
}
else
{
var goodReturn = new
{
StatusCodeEntity = ReturnCodeHandler.Status200,
StatusMessage = "Project saved #" + DateTime.Now.ToString() + ".",
ObjData = new List<QuoteEntitySavedItemVM>() { qsvm }
};
resultSet = new ContentResult
{
Content = serializer.Serialize(goodReturn),
ContentType = "application/json"
};
}
}
else
{
var errorReturn = new
{
StatusCodeEntity = ReturnCodeHandler.Status400,
StatusMessage = "Saving project failed due to submitted quote model to save being null. Please verify that you currently have a network connection or refresh page and try again."
};
resultSet = new ContentResult
{
Content = serializer.Serialize(errorReturn),
ContentType = "application/json"
};
}
}
catch (Exception e)
{
var errorReturn = new
{
StatusCodeEntity = ReturnCodeHandler.Status500,
StatusMessage = "An unknown error occurred while trying to save project. Please refresh page and try again. Details: " + e.Message
};
resultSet = new ContentResult
{
Content = serializer.Serialize(errorReturn),
ContentType = "application/json"
};
}
return resultSet;
}
View and JS snippet:
//save project
function saveQuoteTemplate() {
var $templateBody = $("#quoteEntityItemsContainer"),
url = '#Url.Action("SaveQuoteTemplate", "Home")',
htmlTemplate = $templateBody.html(),
totalRecords = $("#quoteEntityItemsContainer").find("tr").length,
totalBadRecords = $("#quoteEntityItemsContainer").find("tr.table-danger").length,
templateName = $("#txtTemplateNameLabel").text(),
templateUserID = $("#txtUserID").text().trim(),
templateNotes = $("#taNotes").val(),
templateId = $("#txtTemplateNameLabel").attr("projectid"),
data = { 'htmlTemplate': htmlTemplate, "totalRecords": totalRecords, "totalBadRecords": totalBadRecords, "templateName": templateUserID + templateName, "templateNotes": templateNotes, "templateId": templateId };
updateProgressNotification('Saving project...');
console.log("MAX LENGTH: 2097152 | 4MB default. This string length is:" + htmlTemplate.length);
$.ajax({
url: url,
type: 'POST',
data: JSON.stringify({ htmlTemplate, totalRecords, totalBadRecords, templateName, templateNotes, templateId }),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
//Ajax evnts
success: _saveQuoteTemplateSuccessHandler,
error: _saveQuoteTemplateErrorHandler
});
$("#txtTemplateNameLabel").text(templateName);
storeProjectTempData();
}
What I am wondering, is how can I get around the max length issue that causes the failure server side before even hitting the controller, or can I change the JSON being sent to the controller, as just string param, string param2, and so on so it is not sent over as JSON?
Thanks much as always in advance!
To answer your question directly, here is how you can increase the sixe of a request body sent to the server.
<requestLimits maxAllowedContentLength="52428800" /> or
.UseKestrel(options =>
{
options.Limits.MaxRequestBodySize = 52428800; //50MB
});
see https://www.talkingdotnet.com/how-to-increase-file-upload-size-asp-net-core/
Add [FromBody] into your request action
public ActionResult SaveQuoteTemplate([FromBody]string htmlTemplate, int totalRecords, int totalBadRecords, string templateName, string templateDescription, string templateNotes, string templateId) { ... }
Here the first ajax is hitting my controller sucessfully by hitting url 'getMergeRuleMaxCount' but when i try to hit this url 'getMergingDatasets'
so that my control reaches to controller and i can get the data send by ajax in controller, first of all i am not able to get into controller and it is giving me some exception which is mentioned below.
As per my understanding issues is coming while sending the multiple data to my controller.
Iam not getting what iam doing wrong, and how should i get the data in my controller?
Can any body let me know the posible solution?
Exception
WARN : org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public com.hcl.ae.model.MergeRule com.hcl.ae.controller.MergeRuleController.getMergingDatasets(javax.servlet.http.HttpServletRequest,com.hcl.ae.model.MergeRule) throws java.io.IOException
Merge.js
function mergingDataSetValidation(){
var company = $("#company").val();
if (company=="") {
alert("Please select company");
}
var companyClass = $("#companyClass").val();
var companyName = jQuery("#company").find("option[value='" + jQuery("#company").val() + "']").text();
var className = jQuery("#companyClass").find("option[value='" + jQuery("#companyClass").val() + "']").text();
$
.ajax({
type : "GET",
url : "getMergeRuleMaxCount",
success : function(data) {
var count = data;
var selectedValue = "Merge_" + companyName + "_" + className + "_Rule_" + count;
$("#mergeRuleName").val(selectedValue);
var parameter = {
"companyId": company,
"classId" : companyClass
};
$
.ajax({
type : "GET",
url : "getMergingDatasets",
dataType: "json",
contentType: "application/json; charset=utf-8",
data : JSON.stringify(parameter),
/*data : 'company=' + company + '&class=' + companyClass,*/
success : function(data) {
alert("success");
return;
},
error: function(error) {
alert("Error occured while fetching merging datasets..!!")
}
});
},
error: function(error) {
alert("Something went wrong..!!, please refresh the page and try again.")
}
});
};
Controller
#JsonView(Views.Public.class)
#RequestMapping(value = "/getMergingDatasets",method = RequestMethod.GET)
public #ResponseBody MergeRule getMergingDatasets(HttpServletRequest req, #RequestBody MergeRule parameter) throws IOException {
System.out.println(parameter.getCompanyId());
System.out.println(parameter.getClassId());
/* System.out.println(req.getParameter("company"));
System.out.println(req.getParameter("companyClass"));*/
List<DropdownMenu> mergingDatasets = mergeRuleDAO.getMergingDataSets(parameter.getCompanyId(), parameter.getClassId());
return (MergeRule) mergingDatasets;
}
Your MergeRule must containers all your Ajax's params. But your controller use get, so you can't use #RequestBody, you need two #RequestParam.
such as:
#RequestMapping(value = "/getMergingDatasets",method = RequestMethod.GET)
public #ResponseBody MergeRule getMergingDatasets(HttpServletRequest req, #RequestParam String companyId, #RequestParam String classId) throws IOException {
System.out.println(companyId);
System.out.println(classId);
/*System.out.println(req.getParameter("company"));
System.out.println(req.getParameter("companyClass"));*/
List<DropdownMenu> mergingDatasets = mergeRuleDAO.getMergingDataSets(companyId, classId);
return (MergeRule) mergingDatasets;
}
I am having a servlet where I am getting value from properties file. I want to get the value from servlet in my javascript and set that value to a textbox using AJAX. I am totally new to Ajax so please provide me a solution by looking at my code.
SERVLET
#WebServlet("/PopulateProperties")
public class PopulateProperties extends HttpServlet {
private static final long serialVersionUID = 1L;
Properties prop = new Properties();
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
String serverName=request.getParameter("servernameDD");
List<Map<String,String>> returnObj = new ArrayList<Map<String,String>>();
String[] servers = getSearchAttr("servers");
if (servers != null && servers.length > 0) {
String[] lookfor = getSearchAttr("servers_lookfor");
for (String server : servers) {
Map<String,String> obj = new HashMap<String,String>();
if (lookfor != null) {
for (String look : lookfor) {
//System.out.println("looking for :"+look);
String value = prop.getProperty(server+"_"+look);
if(server.equalsIgnoreCase(serverName)){
if(look.equalsIgnoreCase("Links")){
String getlook=prop.getProperty(look);
String getlink=prop.getProperty(server+'_'+look,"Links");
System.out.println("Hello" +getlink);
System.out.println(getlook);
request.setAttribute("serverLink", getlink);
}
}
if (value != null) {
obj.put(look, value);
}
request.setAttribute("servers", server);
request.setAttribute("lookfor", look);
}
}
//System.out.println("Object :"+obj);
returnObj.add(obj);
}
}
response.sendRedirect("updateserverstatus.html");
}
private String[] getSearchAttr( String property){
String lookfor = prop.getProperty(property,"");
String[] ret = {lookfor};
if (lookfor.contains(",")) {
return lookfor.split(",");
} else {
//System.out.println("comma not present in "+property);
//System.out.println("webservice :"+lookfor);
return ret;
}
}
I tried the following Ajax request but I am getting "serverLink undefined error"
function OnSelectionChange(){
$.ajax({
type: "POST",
url: "/PopulateProperties",
data: "{Links: " + serverLink + "}",
success: function(result){
alert(result.d);
console.log(result);
}
});
}
You use a servlet to get data and forward. It is not a proper way to provide data with servlet. A better solution is:
In your servlet, you should just return the properties data in a json format. You can refer this
Then you get this data with ajax in your html page, and update the text of textarea.
It is better to crerate separate servlet just for this purpose. This will keep your code coherent.
Pass all the parameter which will be used to narrow down to the data you need to retrive.
For simplicity just return the value or you can return the data as a JSON key value pair.
If your textbox is like this. <input type="text" id="prop_txt">
then the ajax code will be
$.ajax({
type: "POST",
url: "/PopulateProperties",
data: "{A:(..a value..),
B:(..b value..),
....
....
(..all the parameters required..)
}",
success: function(result){
//alert(result.d);
console.log(result);
$('#prop_txt').val(result);
}
});
Hope this heplps.
I am trying to pass long array from jquery load to spring controller. How can i sent js object array t spring mvc controller.
Every time action occured the no data alert on script will called.
Script
var arr = [];//Array
$(document).ready(function() {
$(".rating").click(function() {
var idx = $(this).closest('td').index();
var userskill = {//Object
tech : $(this).closest('td').siblings('td.tech').text(),
skill : $('#listTable thead th').eq(idx).text(),
rValue : $(this).val()
}
add(userskill);
});
});
function add(userskill) {
arr.push(userskill);
$.ajax({
type : 'POST',
dataType : 'json',
url : '/SimplWebApp/saveUserRating',
data : ({
id : JSON.stringify(arr)
}),
success : function(responseData) {
if (responseData != null) {
alert(responseData);
} else {
alert("no data");
}
}
});
}
controller
#RequestMapping(value = "saveUserRating")
public #ResponseBody String saveUserRating(#RequestParam(value="id[]", required=false) String[] x) {
Gson gson = new Gson();
String data = gson.toJson(x);
return data;
}
The JSON array resides in the body of the request. You can use the #RequestBody annotation to obtain the array if you have Jackson on the classpath to deserialize the JSON.
saveUserRating(#RequestBody(required=false) String[] ids)
If you want to use the array as the response body simply return the array from the handler method. It will be serialized to JSON automatically.
#ResponseBody
public String[] saveUserRating(saveUserRating(#RequestBody(required=false) String[] ids)) {
return ids;
}
I have a jquery function, I have 2 types string & array, If i pass only string type, it hits the controller and works fine, but if i pass array along with it, I get the network error 400 bad request. How do i go about it. Code is as follows
function saveFocusGrp() {
var focusName = window.prompt('Please enter the focus group name:');
var enteredFocusList = [];
enteredFocusList = focuslist; // here focuslist is declared globally and is assigned the value in other function which I'm getting it in this function it will be in the form abc,def,xyz
alert("focus Name====>" + focusName);
alert("focus List====> " + enteredFocusList); // I get the values here in alert too
$.ajax({
url : '/DataWeb/saveFocusData',
type : 'get',
dataType : 'json',
data : { focusGroupName : focusName, focusList : enteredFocusList },
success : function(map) {
console.log(map);
var $out = $('#focusGroupName');
$out.html(map.successMsg);
}
});
}
Error i get in firebug is: NetworkError: 400 Bad Request
Home controller code :
#RequestMapping(value = "/saveFocusData", method = RequestMethod.GET)
public void saveFocusData(HttpServletRequest req, HttpServletResponse res,
#RequestParam("focusGroupName") String focusGroupName,
#RequestParam("focusList") List focusList) throws IOException {
System.out.println("Inside home controller============");
Gson json = new Gson();
res.setContentType("application/json");
HashMap<String, String> map = new HashMap<String, String>();
String successMsg="";
map.put("successMsg", successMsg);
res.getWriter().print(json.toJson(map));
}