Spring MVC: Redirect in #ResponseBody - spring

I want to redirect to another .jsp in spring mvc method. I don't want to use javascripts methods like: window.location.replace(url).
My method:
#RequestMapping(value= "loginUser", method=RequestMethod.POST)
public #ResponseBody String loginUser (#RequestParam("name") String name, #RequestParam("password") String password){
return "";
}

You can't do the redirect from Spring when your request expects json response. You can set a parameter for redirect so that when you enter the success block you can check the parameter to redirect using window.location.reload();. For example, from a similar post, check this answer,
Redirect on Ajax Jquery Call
One idea is to let the the browser know that it should redirect by
adding a redirect variable to to the resulting object and checking for
it in JQuery
$(document).ready(function(){
jQuery.ajax({
type: "GET",
url: "populateData.htm",
dataType:"json",
data:"userId=SampleUser",
success:function(response){
if (response.redirect) {
window.location.href = response.redirect;
}
else {
// Process the expected results...
}
},
error: function(xhr, textStatus, errorThrown) {
alert('Error! Status = ' + xhr.status);
}
});
});
You can alternatively add a response header for redirect like response.setHeader("REQUIRES_AUTH", "1") and in jQuery success,
success:function(response){
if (response.getResponseHeader('REQUIRES_AUTH') === '1'){
window.location.href = 'login.htm';
}
else {
// Process the expected results...
}
}
Refer the similar question: Spring Controller redirect to another page

Include an HttpServletResponse parameter and call sendRedirect(String).
Or, don't use #ResponseBody at all, and return the model/view you want to use.

Related

ModelView, Ajax and Json return

In my code, i have two RequestMapper in my Controller which is designed this way :
#Controller
#RequestMapping("/myHostel.html")
public class HostelController
{
#RequestMapping(method = RequestMethod.GET)
public ModelAndView getText()
{
// do some cool stuff but not the point here
}
#RequestMapping(method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public String getMyUrl()
{
String myVariable;
return "{\"myUrl\": \""+myVariable+"\""}";
}
}
And my ajax code :
function openNewTab() {
$.ajax({
url : 'myHostel.html',
type: "POST",
dataType: "json",
beforeSend: function(xhr) {
xhr.setRequestHeader("Accept", "application/json");
},
success : function(response){
console.log(response);
window.open(response.url, '_blank');
},
error: function(jqXHR, exception, errorThrown)
{
console.log(jqXHR.status);
console.log(exception);
console.log(errorThrown);
}
});
}
and my button is kinda like this :
<button tabindex="0" id="mySweetButton" class="btn btn-primary"
onclick="openNewTab();" >
Open a new tab
</button>
And what i get is :
200
parsererror
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
--
I've tried with putting a session variable in the model and a making a window.open(URL_IN_SESSION);
But if you reload the page, it's calling it again.
Making a c:remove on the variable when it's not used to cancel this problem but to no avail.
I have to get a variable from my ModelView after some previous call and open it in ajax (or javascript whatever as long as it works) to have my main page and my new tab with the custom URL.
If anyone has a idea on what i'm doing wrong ? (I need a custom URL made in my controller by previous GET call with user choices.)
Thank you for reading !
Solved by making just another GET requestMapping using no parameters and with value = ("/myHostel.html/getMyUrl.html")
One of the problem was the filters that only allowed .html url for the mapping.
The other was the JSON, just using :
#RequestMapping(method = RequestMethod.GET, value = "/getUrl.html")
public ResponseEntity<String> sendUrl()
{
return new ResponseEntity<>(getMyUrl(), HttpStatus.OK);
}
And parsing the return in ajax :
function openNewTab() {
$.ajax({
url : 'myHostel.html/getUrl.html',
type: 'GET',
dataType: 'text',
success : function(data){
window.open(data, '_blank');
}
});
}
And it solved the problem.

Sending data to MVC Controller with AJAX

I am trying to send data with AJAX to MVC Controller method, but I don't know what am I doing wrong.
Here is the AJAX call
$.ajax({
type: 'POST',
url: invokingControllerActionUrl,
data: "it is just a simple string",
success: function (data) {
window.location.href = link;
}
});
And here is the controller method. It is invoked, but the parameter is always null.
public IActionResult OnPostTest([FromBody] string stringValue)
{
// stringValue is always null :(
}
Change you ajax call to this
$.ajax({
type: 'POST',
url: invokingControllerActionUrl, // Confirm the Path in this variable Otherwise use #Url.Action("OnPostTest", "InvokingController")
data: {stringValue: "it is just a simple string"},
success: function (data) {
window.location.href = link;
}
});
And remove the [FromBody]. ALso its better to define type post. Not necessary though
[HttpPost]
public IActionResult OnPostTest( string stringValue)
{
// stringValue is always null :(
}
Depending on what Content-Type you are sending from JS, you might need to encode your string properly, as a form-value
...
data: 'stringValue="it is just a simple string"',
...
or e.g. JSON:
...
data: '{stringValue: "it is just a simple string"}',
...
See also this discussion
I haven't found an easy way to pass a string of unformatted data via parameter, unfortunately. According to this answer, you can do the following:
public IActionResult OnPostTest()
{
Stream req = Request.Body;
req.Seek(0, System.IO.SeekOrigin.Begin);
string stringValue = new StreamReader(req).ReadToEnd();
...
// process your stringValue here
...
}

Spring MVC using AJAX return page not found

I have create an endpoint to delete a record, yet when i use either POST or GET, i could not reach to that end point, it always said page not found ,i realized there is weird parameter was appended.
example:
http://localhost:8080/admin/panel/case/survey/delete/completion/form/0af9518a-8eea-4e69-94a3-3571c3785215?_=1526048495480
this my end point :
#RequestMapping(value = "/delete/completion/form/${id}", method = RequestMethod.GET)
#ResponseBody
public String deleteCompletionForm(#PathVariable("id") String id) {
return String.valueOf(completionFormService.deleteCompletionFormThenLog(id));
}
this is my ajax :
$('table').on('click', '.delete', function () {
if (confirm('Are you sure you want to remove this record!')) {
var contentPanelId = jQuery(this).attr("id");
$.ajax({
type: "GET",
url: "${pageContext.request.contextPath}/admin/panel/case/survey/delete/completion/form/" + contentPanelId,
cache: false,
timeout: 600000,
success: function (data) {
if (data) {
$(this).parents('tr').remove();
}
},
error: function (e) {
alert("Can not delete the record, please try again!")
}
});
}
});
It is happening due the cache setting you are specifying which will add a timestamp parameter to the URL.
From the Jquery docs (https://api.jquery.com/jQuery.ajax/):
cache (default: true, false for dataType 'script' and 'jsonp')
Type:
Boolean If set to false, it will force requested pages not to be
cached by the browser. Note: Setting cache to false will only work
correctly with HEAD and GET requests. It works by appending
"_={timestamp}" to the GET parameters. The parameter is not needed for
other types of requests, except in IE8 when a POST is made to a URL
that has already been requested by a GET.

How to correctly handle an AJAX request using Spring MVC? Why doesn't this example work in my project?

I am pretty new in Spring MVC and AJAX and I have the following problem.
Into a page my application perform this JavaScript function that perform an AJAX GET request:
function caricaDettaglioRegione(regioneSelezionata) {
var codiceRegione = regioneSelezionata.getAttribute("data-reveal-id");
var nomeRegione = regioneSelezionata.getAttribute("data-nome-regione");
alert("codiceRegione: " + codiceRegione + " - nomeRegione: " + nomeRegione);
$.ajax({
type: "GET",
data: {'codiceRegione' : codiceRegione
},
url: "riepilogoDettaglioRegione",
contentType:"application/json"
}).done(function(response) {
alert("DONE");
}).error(function(xhr) {
alert("ERROR");
manageError(xhr);
});
}
As you can see in the Http GET request is passed the value of the codiceRegione as request paramether (named codiceRegione) by this line:
data: {'codiceRegione' : codiceRegione
},
So now I want to handle this AJAX request and I have implement this controll method into a #Controller class:
#RequestMapping(value = "/riepilogoDettaglioRegione", method = RequestMethod.GET)
public String riepilogoDettaglioRegione(#RequestParam("codiceRegione") String codiceRegione, Model model) {
System.out.println("INTO riepilogoDettaglioRegione()");
return "blabla";
}
As you can see it handle the GET requesto toward previous resource (/riepilogoDettaglioRegione) and I try to retrieve the codiceRegione request parameter by #RequestParam("codiceRegione")
But it can't work and this method is not performed when the previous AJAX request is performed.
What am I missing? How can I solve this issue?
You're explicitly saying that the codiceRegione is a parameter not the request body.
So for that you will need to change your ajax call like:
$.ajax({
type: "GET",
url: "riepilogoDettaglioRegione?codiceRegione=blah",
contentType:"application/json"
}).done(function(response) {
alert("DONE");
}).error(function(xhr) {
alert("ERROR");
manageError(xhr);
});
Or wrap codiceRegione in an object and then change the annotation #RequestParam for #RequestBody.
Hope it helps.
Solved by myself.
The problem was that the project used Spring Security and that this resource have to be accessible also to not logged user so I have to insert something like this
<intercept-url pattern="/riepilogoDettaglioRegione" access="permitAll" />
into the authernticationManager configuration into the spring-security.xml file.

how to send an object from spring controller to jsp through Ajax

I have a transaction object and I am trying to send the object to the front page. I have no problem when I try to send a string, but I couldn't send an object.
So this is my controller:
#RequestMapping(value="/result/helloajax", method=RequestMethod.GET)
#ResponseBody
public MyTransaction helloahjax() {
System.out.println("hello Ajax");
MyTransaction tran = MyTransaction.getInstance();
tran.setId(123);
return tran;
}
#RequestMapping(value="/result", method=RequestMethod.GET)
public String show() {
return "result";
}
and this is my ajax call
button
<div class="result"></div>
function doajax() {
$.ajax({
type : 'GET',
url : '${pageContext.request.contextPath}/result/helloajax',
success : function(response) {
$('.result').html(response.id);
},
error: function() {
alert("asda");
}
});
};
I search around and see that other developers used "response.result.id" but I couldn't make it neither. Any suggestion please.
I would suggest to change your code like below.
1.Include JSON library to your classpath and add produces="application/json" attribute to RequestMapping for the helloahjax method.
#RequestMapping(value="/result/helloajax", method=RequestMethod.GET,produces="application/json")
2.Include dataType in your ajax call,like below
$.ajax({
type : 'GET',
dataType : 'json',
url : '${pageContext.request.contextPath}/result/helloajax',
success : function(response) {
var obj = JSON.parse(response);
//Now you can set data as you want
$('.result').html(obj.id);
},
error: function() {
alert("asda");
}
});
The URL would change to below when you are returning JSON from the controller method. In this case you don't need to parse the response. Instead you can directly access the object variables as response.abc
${pageContext.request.contextPath}/result/helloajax.json

Resources