I have the following Code on my Client
var value = {"userId":form.userId.value};
var xhrArgs = {
url : messageUrl,
handleAs : "text",
content: value,
load : displayMessages,
error : function(error) {
dojo.byId("displayArea").innerHTML = "Error aquiring messages";
}
};
dojo.xhrGet(xhrArgs);
}
And on my server side controller code
#RequestMapping(value = "/getMessages.htm", method = RequestMethod.GET)
public #ResponseBody String showMessageTable(#RequestParam("userId") String userId,ModelMap params)
{
I am getting a 400 error saying
The request sent by the client was syntactically incorrect ()
Could someone explain what i'm doing wrong? I have tested the dojo code with firebug and the value seems to be passing just fine. Thanks!
It might be helpful. visit to this URL : http://maxheapsize.com/2010/07/20/spring-3-mvc-ajax-and-jquery-magic-or-better-simplicity/
Related
I am working with a javascript client that I am trying to use to communicate with a server. I have a Javascript function that is POSTing to a Spring Boot REST service. The service is a simple test service that doesn't do much...
#RequestMapping(method = RequestMethod.POST,value="/testservice")
#ResponseBody
public String testPostRequest(#RequestParam String someText)
{
System.out.println("Reached the counting service! Param value: " + someText);
if(someText != null)
{
...
perform some actions
...
}
return("Success");
}
The Javascript I am using to send POST requests to the server is below:
var sendWords = function(toSend) {
var data = { DataList : [toSend] };
var param = { someText: data };
$.post("http://localhost:8080/testservice",param,
function(status,ret) {
alert("We're back "+status);
});
};
The toSend parameter is just a string containing some text that will be posted to the service. Note that the port for the service was set to 8080 in the server's application.properties file.
When I call the Javascript function and post the string to the service, I get the following log message from the server:
2019-07-28 20:00:06.292 WARN 80844 --- [nio-8080-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'someText' is not present]
I am doing something wrong, but cannot figure out what it is. I am sending an object that is tagged as the someText string, but it is not being recognized by the server for some reason.
Can someone tell me what I am missing? How do I get this to work?
var data = { DataList : [toSend] };
var param = { someText: data };
Here data is not string.
You may need to stringify it.
var param = { someText: JSON.stringify(data) };
You are missing the value in the #RequestParam(), such as #RequestParam(value="someText", required=true).
You could use #PathVariable too.
This could be helpful:
#RequestParam vs #PathVariable
I am trying to make a DELETE request but it doesn't work. My code is as follows:
$.ajax({
type : "DELETE",
url : "/meds/dme-rest-api/resources/data-setup/deleteCheckList.json?" + $.param({"checkListId":currentCheckListId}),
headers : {authToken : '${TOKEN}'},
cache : false,
success : function(data){
console.log(data);
}
});
The response which I get is : {"errorMessage":"","success":true}
But the data is not getting deleted. What is the reason behind this ?
Please let me know if I should some extra information.
Update The API is as follows:
#DELETE
#Path("deleteCheckList.json")
#Produces(MediaType.APPLICATION_JSON)
public Response deleteCheckList(#HeaderParam(value = RestHttpHeaderNames.AUTH_TOKEN) String authToken,
#FormParam(value = "checkListId") int iCheckListId) throws Exception, SQLException {
User user = UserManagement.getInstance().get(authToken);
String sCompanyNo = user.getCompanyNo();
int iEmployeeNo = user.getEmployeeNo();
return RestUtils.getNoCacheResponseBuilder(Response.Status.OK).entity(
DataSetupManager.newInstance().deleteCheckList(sCompanyNo, iEmployeeNo, iCheckListId).toString())
.build();
}
Your java method always returns Response OK.
You should delete what you need to delete, which may fail. If it fails, return a status that is not OK
I'm trying read the value of a session attribute in Java that has been set through Javascript before. The attribute gets set correctly as Chrome shows here.
But I can't seem to get this attribute value in the Controller later.
I feel like I'm missing out on something how this whole session thing works.
Because when I debug the code, it just shows me that my MainController.java is stored in there.
My Code
main.js
function setSessionCounter(count){
listElementsCounter = count;
sessionStorage.setItem("listElementsCounter", listElementsCounter);
}
MainController.java
#RestController
#EnableWebMvc
#Scope("session")
public class MainController {
...
#RequestMapping(value = "/search", method = RequestMethod.POST)
public ModelAndView showSearchResults(#ModelAttribute("SpringWeb")SearchParameters sp, ModelMap model, HttpSession session) throws SQLException {
//Build SQL without the counter
int elementsCount = (Integer)(session.getAttribute("listElementsCounter"));
...
}
I also tried it this way in the Controller:
#RequestMapping(value = "/search", method = RequestMethod.POST)
public ModelAndView showSearchResults(#ModelAttribute("SpringWeb")SearchParameters sp, ModelMap model, HttpServletRequest request) throws SQLException {
HttpSession session = request.getSession();
//Build SQL without the counter
int elementsCount = (Integer)(session.getAttribute("listElementsCounter"));
...
}
I would really appreciate if someone could point out what I'm doing wrong (:
I think this will help you in sending ajax request to your spring controller
In Javascript
function myFunction() {
console.log("clicked on submit button");
var data = {"listElementsCounter":count}
$.ajax({
type: "POST",
url: "testurl",
data:data,
success :function(result) {
//anything you want to do after success
}
});
}
In Controller
#RequestMapping(value="/testurl" , method=RequestMethod.POST)
#ResponseBody
public void process(#RequestParam("listElementsCounter") Integer count) {
//do whatever you want to do for the count
}
JavaScript is executed on the client side, and no session attributes can be stored.
You can pass information from client to server with, for example, an Ajax call and on the server side (the controller) store the data with the session.setAttribute command.
Here is my code for AngularJS controller from which i am sending http post request to server:
'use strict';
var input = {title: "", note:""};
notes.controller('inputController', function inputController($scope, $http) {
$scope.cancleInput = function () {
//not yet implemented
}
$scope.saveInput = function () {
input.title = $scope.title;
input.note = $scope.note;
$http.post("/saveData/writeData", input);
}
})
Here is my code inside C# controller:
public class saveDataController : Controller
{
public static void writeData(input input)
{
var jsonString = new JavaScriptSerializer().Serialize(input);
//other code
}
}
The http post call is not recognizing the C# method.
I am pretty sure that my URL is wrong or i am missing any C# attribute.
I am getting following error:
POST http://localhost:56171/saveData/writeData 500 (Internal Server Error)
The C# method is not hitting the break point so it is never being called by the post request.
I think you should check by getting post data from input stream data in your c# controller. you are getting 500 error because angular $http will post ajax request with "application/json" content type which is not accessible through the Request.Form collection. Try by changing public
public static void writeData(input input)
to
public static void writeData()
and use Request.InputStream to get data.
var Res = new StreamReader(Request.InputStream);
Try by creating API controller by inheriting from ApiController and decorate method with HttpPost verb as below -
public class saveDataController : ApiController
{
[HttpPost]
public static void writeData(input input)
{
var jsonString = new JavaScriptSerializer().Serialize(input);
//other code
}
}
Here is what I did to make it work:
I added custom Api configuration in WebApiConfig file.
config.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{Action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Then I modified the HTTP Post URL according to the new Api configuration.
$http.post("/api/saveData/writeData", input);
Then I made the C# controller inherit from ApiController.
One last change i made was that i added [HTTP POST] attribute to the C# method and removed the static keyword.
(I do not understand why having 'static' in the method definition made the method undetectable by HTTP POST.)
public class saveDataController : ApiController
{
[HttpPost]
public void writeData(input input)
{
//bunch of code
}
}
while saving form details using backbone i m getting error as
POST http://localhost:8080/gamingengine/restful-services/badges 500 (Internal Server Error)
st.ajaxTransport.sendjquery.js:4
st.extend.ajaxjquery.js:4
Backbone.ajaxbackbone.js:1197
Backbone.syncbackbone.js:1178
_.extend.syncbackbone.js:284
_.extend.savebackbone.js:490
Backbone.Form.extend.saveBadgesbadges.js:219
st.event.dispatchjquery.js:3
st.event.add.y.handle
Uncaught SyntaxError: Unexpected token <
st.extend.parseJSONjquery.js:2
window.clearErrorscommon.js:386
st.event.dispatchjquery.js:3
st.event.add.y.handlejquery.js:3
st.event.triggerjquery.js:3
rjquery.js:4
st.ajaxTransport.send.r
my backbone code is as follows
this.model.save(this.getValue(), {
//beforeSend : setHeader, //added
iframe : true,
wait : true,
files : $file,
elem : this,
data : _.omit(this.getValue(), ['iconFile']),
silent : true,
success : function(model, response, options) {
alert("inside save..");
var error = false;
_.each(response, function(val, key) {
if (app.BadgesView.fields[key]
&& val instanceof Object
&& val.error) {
error = true;
app.BadgesView.fields[key]
.setError(val.message);
}
});
if (!error) {
app.BadgesView.model.set(model);
app.BadgesListCollection.add(model);
return;
}
return false;
},
error : function(model, response, options) {
console.log("error while save in badges.js : ");
}
});
and server side code is as follows which is using resteasy
#POST
#Consumes("multipart/form-data")
#Produces("text/html")
#Cache(noStore = true)
public final Response saveBadges(
#MultipartForm final BadgesForm badgesForm) throws IOException {
System.out.println("saveBadges called........");
final int no_of_coins = badgesForm.getNo_of_coins();
final String badge_name = badgesForm.getBadge_name();
final int score = badgesForm.getScore();
final int badge_id = badgesForm.getBadge_id();
final byte[] iconFile = badgesForm.getIconFile();
final Validator validatorNumeric = ValidationFactory
.getTextFieldNumericValidator();
validatorNumeric.validate("no_of_coins", no_of_coins,
threadlocalExceptions.get());
System.out.println("iconFile :" + iconFile);
if (iconFile.length >= GamingConstants.ONE) {
ValidationFactory.getImageContentValidator().validate("iconFile",
iconFile, threadlocalExceptions.get());
ValidationFactory.getImageSizeValidator().validate("iconFile",
iconFile, // added size // validator
threadlocalExceptions.get());
}
if (threadlocalExceptions.get().isEmpty()) {
try {
final Badges badges = new Badges();
badges.setNo_of_coins(no_of_coins);
badges.setBadge_name(badge_name);
badges.setScore(score);
badges.setBadge_id(badge_id);
final Coin coin = new Coin();
coin.setId(badgesForm.getCoin());
badges.setCoin(coin);
Badges.save(badges);
final Badges badgesObj = new Badges();
badgesObj.setBadge_id(badges.getBadge_id());
badgesObj.setCoin(coin);
badgesObj.setBadge_name(badges.getBadge_name());
badgesObj.setNo_of_coins(badges.getNo_of_coins());
badgesObj.setScore(badges.getScore());
if (iconFile.length >= GamingConstants.ONE) {
final String imgPath = "restful-services/badges/"
+ badges.getBadge_id() + "/image";
badgesObj.setIconPath(imgPath);
final String fileName = path + badges.getBadge_id()
+ ".png";
CommonUtils.writeIcon(iconFile, fileName);
} else {
badgesObj.setIconPath(defaultPath);
}
Badges.update(badgesForm.getBadge_id(), badgesObj);
final gamingengine.bind.Badges bindBadges = new gamingengine.bind.Badges();
bindBadges.setBadge_id(badgesObj.getBadge_id());
bindBadges.setCoin(badgesObj.getCoin());
bindBadges.setNo_of_coins(badgesObj.getNo_of_coins());
bindBadges.setBadge_name(badgesObj.getBadge_name());
bindBadges.setIconPath(badgesObj.getIconPath());
bindBadges.setScore(badgesObj.getScore());
final ObjectMapper mapper = new ObjectMapper();
final String jsonString = mapper.writeValueAsString(bindBadges);
return Response.ok().entity(jsonString).build();
} catch (DBException e) {
if (e.getMessage().startsWith(DBException.PARENT_NOT_EXISTS)) {
final String fieldName = e.getMessage()
.substring(e.getMessage().indexOf("-") + 1).trim()
.toLowerCase();
e.getValidationException()
.setMessage(
"The "
+ fieldName
+ " is already deleted.Please refresh the page ");
threadlocalExceptions.get().put(fieldName,
e.getValidationException());
}
}
}
final Map<String, ValidationException> exceptions = threadlocalExceptions.get();
threadlocalExceptions.remove();
final ObjectMapper mapper = new ObjectMapper();
final String exceptionJsonString = mapper
.writeValueAsString(exceptions);
return Response.ok().entity(exceptionJsonString).build();
}
while saving data of the form, backbone does not call the saveBadges() method of server side code
in chrome network it shows as
badges
/gamingengine/restful-services
POST
500
Internal Server Error
text/html
now i tried as
data:this.getvalue() in save() its sending all values to server except for iconPath
**iconPath : {
type : "FilePicker",
title : "Icon"
}**
and in save() of backbone
**var $file = $('input[name="iconPath"]', this.el);** this two lines are not sending iconPath, its empty any guesses
any help appreciated!!! thanks
The issue could be related to the content-type expected by your service, "multipart/form-data". Backbone by default does not provide an implementation to send a multipart request on the "save" method.
Here is a link with information about how you can send the multipart-request:
multipart form save as attributes in backbonejs
Also, message that you are receiving about the unexpected character ">" could be related to the "dataType" associated to the request, try to change it to "text" to avoid parsing to JSON, adding that you should be getting the correct error.
this.model.save(this.getValue(), {
//beforeSend : setHeader, //added
iframe : true,
wait : true,
files : $file,
dataType: "text",
elem : this,
data : _.omit(this.getValue(), ['iconFile']),
silent : true..
}
I will suggest to review your developer console as well in Chrome, Safari or Firefox to see how the request is been sent to the server, that could give you a better understanding how your request is been received by the server.
Also, try testing your service by external "Restful" tool, chrome provided the "Advance Restful Client" where you can test your service.
Hope this information helps to solve your issue or guide you in the right direction.