I wonder if someone could help me out please? What I'm trying to achieve (via ajax) is to pass parameters to a URL but not on the query string as I don't want to expose the parameters.
So I have a page which contains an Index method:
public ActionResult Index(int qualID)
{
//do stuff with qualID and load up a model
return PartialView("ICTEnrolmentForm", myNewModel);
}
and on (a completely separate page) I have the following block of ajax:
<script>
var enrolmentURL = "/enrolment/";
$('.enrolNow').click(function (e) {
var qualID = $(this).attr('data-qual');
$.ajax({
url: enrolmentURL,
type: 'POST',
data: { 'qualID': qualID },
success: function(model)
{
window.location = enrolmentURL;
}
});
});
</script>
If if create a breakpoint on the ActionResult method I can see that the method is being called (with the QualID populated) but then the redirect is fired and I'm getting an Null parameter error.
I'm obviously being really dim but if someone could point out the error of my ways that'd be much appreciated.
Thanks,
C
if you use spring boot, add this in your controller:
#RequestMapping(value = "/enrolment/",method = RequestMethod.POST)
public ActionResult Index(#RequestParam(value = "qualID" , required = false) String qualID)
{
//do stuff with qualID and load up a model
return PartialView("ICTEnrolmentForm", myNewModel);
}
I assume this is C# code and not Java, as mentioned in the TAG section?
The problem is that qualID can be NULL if you invoke the controller method via HTTP. However, qualID has the datatype Int32 which can't be null. So you have to change the datatype and the method signature to
public ActionResult Index(int? qualID)
Now, qualID is allowed to be NULL(you have to check this before you use the variable in your code and throw an appropriate error message). Additionally, check your defined routes.
not sure if this an answer or not but I've found a workaround basically I do an ajax post to another method which populates the model and puts the model into a session variable then upon success I'm doing the redirect to the URL which loads the session model onto the page.
The URL stays clean which is the main thing that I was after.
Thanks for your time folks.
Related
I have a simple JSP file with some radios, one text input and one button.
In the button onClick I am doing an Ajax request to a Spring controller as you can see bellow:
function callFiltrarViaAJAX() {
var filtro = $("#filtro").val();
var optFiltro = $('input[name=optFiltro]:checked').val();
$.ajax({
type : "GET",
url : "filtrar",
//dataType : "json",
data : {
filtro : filtro,
optFiltro : optFiltro
},
success: function(data) {
console.log("SUCCESS: ", data);
},
error: function(e) {
console.log("ERROR: ", e);
},
done: function(e) {
console.log("DONE");
}
});
}
In the Spring controller I am receiving this request with success with the following code:
#Controller
public class FiltroController {
#RequestMapping(value = "/filtrar", method = RequestMethod.GET)
public #ResponseBody String filtrarVacina(FiltroTO filtro, HttpServletResponse response, ModelAndView model) {
VacinaTO v = new VacinaTO();
v.setId(new Long(10));
v.setLote("Lote 1");
v.setNome("BCG");
model.addObject("vacina", v);
response.setStatus(200);
return "TEST OK";
}
}
As you can see in the code above, I'm adding a POJO object in the ModelAndView that I'am trying to use in the JSP to show the return of the Ajax request in a table.
My Ajax request returns with success too but the problem is that even returning with success I can't use the POJO object, when I try to access the object by expression language I got nothing.
I've been searching about this situation and I found a lot of contents but none of the solutions that I've found works for me, but I found an interesting answer:
JSP inside ListItems onclick
So, is it means that I can't get a new parameter in the same JSP file with a Ajax request ? If yes, would be a JSON file the better way to get the return from the Spring controller ?
You can't access the model because you're returning an arbitrary string from controller instead of the view in which you want to access model.
If you're trying to access vacine from some.jsp, then you should return some from the controller method.
Of course, what I said is valid if you have proper ViewResolver configuration.
I have a problem in my spring boot app with the csrf token.
I have a form where I can edit a Person. A Person can have
Let us now imagine that the person has a car and enter this and store it. The next time he wants to delete this car and enter another one. I have created that so that there is a list of all of his cars -- he has the option to remove this from the list. Now I'm starting from these pills and want to send with the corresponding ID to the server a POST. When I try I get a 403 forbidden and I have no idea why.
If I change from POST to GET, then it works.
My JavaScript (taken from this site: http://docs.spring.io/autorepo/docs/spring-security/4.0.0.CI-SNAPSHOT/reference/htmlsingle/#the-csrfmetatags-tag)
var csrfParameter = $("meta[name='_csrf_parameter']").attr("content");
var csrfHeader = $("meta[name='_csrf_header']").attr("content");
var csrfToken = $("meta[name='_csrf']").attr("content");
// using JQuery to send a non-x-www-form-urlencoded request
var headers = {};
headers[csrfHeader] = csrfToken;
$.ajax({
url: "./delete/car",
type: "GET",
headers: headers,
});
$.ajax({
url: "./delete/car",
type: "POST",
headers: headers,
});
My controller methods:
#RequestMapping(value = "/{login}/delete/car", method = RequestMethod.GET)
public ModelAndView delete(#PathVariable("login") final String login) {
System.out.println("Stop");
return new ModelAndView("redirect:" + WebSecurityConfig.URL_PERSONS_OVERVIEW);
}
#RequestMapping(value = "/{login}/delete/car", method = RequestMethod.POST)
public ModelAndView deleteInstEmp(#PathVariable("login") final String login) {
System.out.println("Stop");
return new ModelAndView("redirect:" + WebSecurityConfig.URL_PERSONS_OVERVIEW);
}
Any suggestions?
Thanks in advance.
OK, after strugglin with all that, I get the following result.
I added the fail method to the Ajax construct and get the following message:
"Failed to execute 'setRequestHeader' on 'XMLHttpRequest': '${_csrf.headerName}' is not a valid HTTP header field name."
the official spring site advises that you have to put this: <sec:csrfMetaTags /> or from other sources, this: <meta name="_csrf" th:content="${_csrf.token}"/> in your html file.
After this, you should be able to access these attributes in your JavaScript, but in my case I get undefined and ${_csrf.headerName}.
A last try was to take the value from the hidden value (chapter 24.5: http://docs.spring.io/autorepo/docs/spring-security/4.0.0.CI-SNAPSHOT/reference/htmlsingle/#the-csrfmetatags-tag).
Now, I have the following:
$(function () {
var token = $("input[name='_csrf']").val();
var header = "X-CSRF-TOKEN";
$(document).ajaxSend(function(e, xhr, options) {
xhr.setRequestHeader(header, token);
});
});
$.ajax({
url: "./delete/car",
type: "POST",
success:function(response) {
alert(response);
}
});
With this it works like a charm.
Another way, you can use the following code:
$.ajax({
url : './delete/car',
headers: {"X-CSRF-TOKEN": $("input[name='_csrf']").val()},
type : 'POST',
success : function(result) {
alert(result.msgDetail);
}
})
I suggest you first check if a valid csrf token and the header have been generated using chrome debugger. If not, then have you added the <sec:csrfMetaTags /> in the <head>?(you will need to import the spring security taglibs). If using Apache tiles, you will have to add this at the <head> section of the template file being used for the view.
If the token is not empty, then in your security-context/configuration file, check if you have disabled csrf security by any chance. By default it is enabled and needs to be for this process to work.
Assumptions, I am new to Spring MVC, JSP, Scripting/Ajax
Here's my task.
In Spring MVC, I have buttons in my jsp page, on button click, I want to perform some task (controller method), which doesn't return anything. I want to show the same page. It shouldn't reload the page nor should redirect to some other page.
Here's what I am doing...
I have a page with lots of buttons. I am using bootstrap css and button tag.
like,
Start
On this button click, I am calling an Ajax to the method from controller,
$('#startApp').click(function() {
BootstrapDialog.show({
message : 'Sure ?!',
buttons : [ {
label : 'Ok',
cssClass : 'btn-default',
action : function(dialogItself) {
$.ajax({
type : "POST",
url : "/MyApp/startApp",
success : function(response) {
alert("Success");
}
});
dialogItself.close();
}
}, {
label : 'Close',
action : function(dialogItself) {
dialogItself.close();
}
} ]
});
This calls the controller method,
#RequestMapping(value = "/startApp", method = RequestMethod.POST)
public void start() {// some operation.}
However, when I do this, operation is performed but in logs I am getting below error,
root cause dispatcher: com.ibm.ws.jsp.webcontainerext.JSPErrorReport: JSPG0036E: Failed to find resource /WEB-INF/views/startApp.jsp
Questions,
Is it the right way to do ?
I don't want to redirect to startApp.jsp, I want it to return to my index.jsp (where the code resides), how can I achieve this ?
You need to return something to the client. Spring default tries to send back startApp.jsp because that's what in the url (/startApp). Try this: this will send back an HTTP OK status (200).
#RequestMapping("/startApp", method = RequestMethod.POST)
public ResponseEntity start()
{
return new ResponseEntity(HttpStatus.OK);
}
You can also send back a json by returning a POJO (it'll be automatically serialized by the Jackson JSON lib) if that's what you want, or even a simple string as the html content by returning a String.
The purpose of ajax is to refresh a part of page. so re-directing to another page is meaningless, you could make the return type as String in your controller.
#RequestMapping(value = "/startApp", method = RequestMethod.POST)
#ResponseBody
public String start() {
// some operation
return "sucess"
}
Read my answer here Returning Hashmap From controller to JSP in Springmvc to know how to pass parameters in response
I am trying to POST to a Spring MVC controller method via ajax. Using Chrome's developer tools, I can tell that the values from the form are being sent, but in the method, the form values are null.
Here is the jquery call:
var form = $('#renegotiationForm').serialize();
$.ajax({
method:'POST',
url:'/renegotiate/wizard/startRenegotiation',
data:{'renegotiationForm': form},
success: function(data) { this.transitionTo(data); }
});
Here is the Spring MVC method (meant to return only a single string):
#RequestMapping(value="wizard/startRenegotiation", method = RequestMethod.POST)
public #ResponseBody String processStart(#ModelAttribute("renegotiationForm") RenegotiationForm form, BindingResult bindingResult) {
log.debug("Entered showStart(), method=POST");
RenegotiationType type = RenegotiationType.valueOf(form.getRenoType().trim().toUpperCase());
RenegotiationActivity activity = RenegotiationActivity.valueOf(form.getRenoActivity().trim().toUpperCase());
String result = "";
if (type == RenegotiationType.TYPE1 && activity == RenegotiationActivity.ACTIVITY1) {
result = "deleteType1";
}
return result;
}
The values are bound using the Spring Form taglib, and I have confirmed that the path attributes of the form tags match the fields of the RenegotiationForm.
I think it's because you are trying to send an "string" from ajax and you want to get and Object (RenegotiationForm), try to change it to String and Format in Server-side. I recommend you to add the type you are sending from client-side, too.
#RequestMapping(value = "wizard/startRenegotiation", method = RequestMethod.POST, produces="application/json")
Found the answer. Further on in my code, I had a function like this:
var ajaxcall = function() { $.ajax({
// ajax settings
});
}
Unfortunately, setting it up this way doesn't make it work as a jquery deferred, and specifically I couldn't use the .then() function to process of ajax requests.
Thanks for the help.
I'm trying to make a simple AJAX call in my Spring MVC project but am running into trouble. I am making my AJAX request by sending an String type argument and I'm wanting to get an ArrayList type back. I've read many tutorials at this point and can't figure out what's wrong with my AJAX/Controller configuration. I am using the ResponseBody annotation when trying to return my needed result back to the view. In this controller I am not returning an updated ModeAndView object, but this shouldn't matter since the page does not need to be refreshed because I'm using AJAX. Below is my AJAX call and controller code. I would really appreciate it if someone could give me a hint on what I'm doing wrong here.
function getdays() {
var monthSelected = $("#monthselect option:selected").text();
alert(monthSelected);
$.ajax({
url : '${pageContext.request.contextPath}/ajaxdays',
data: monthSelected,
success : function(data)
{
$('#daySelect').html(data);
alert(data);
}
});
}
Here is my controller class:
#Controller
#SessionAttributes
public class WorkstationController
{
#RequestMapping(value = "/ajaxdays", method = RequestMethod.GET)
public #ResponseBody
ArrayList<String> getTime(HttpServletRequest request)
{
ArrayList<String> retList = new ArrayList<>();
retList = this.getList();
return retList;
}
}
you have following errors
wrong url
change url : 'ajaxdays.html'to ${pageContext.request.contextPath}/ajaxdays
no parameter passed
you are not passing any data to server side so there is no need to write data: monthSelected
URL mentioned in ajax call should be the context path followed by the controller mapping. And '.html' should not be specified.
url: ${pageContext.request.contextPath}/ajaxdays