I am creating a jsp application in jsp.I am trying to redirect to login page on ajax request if user is not signed in.
My approach
The request is send from javascript that pass some parameters to
url.The server side code checks is user is signed in or not.
The server side code has a function to build sign in url
The Problem where i am stuck is i have to pass this text to client side from server to javascript so that i can use something like window.location.href=url;
Can anyone please explain how do i pass this url and access it in callback function in ajax success function.
Is there any other approach?..
Checking the user is logged in should probably be handled by your JSP code.
That way you can send redirect headers before the page is rendered, rather than having to wait for a ajax response to be returned before redirecting the user. Using ajax will mean they see the page they don't have access to before you redirect them.
There are tons of ways to handle ajax request. The simplest way (not necessarily best) is to create a servlet to handle your ajax request. Below servlet example will return the json string { status: 'not logged in'}:
package mycompany;
public CheckLoginServlet extends HttpServlet {
protected doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
res.setContentType("application/json");
HttpSession session = req.getSession();
// do your stuff to check if user logged in here ..
PrintWriter writer = res.getWriter();
writer.append("{ status: 'not logged in' }");
}
}
Declare & map this servlet on your web.xml deployment descriptor file:
<web-app>
<servlet>
<servlet-class>mycompany.CheckLoginServlet</servlet-class>
<servlet-name>CheckLoginServlet</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>CheckLoginServlet</servlet-name>
<url-pattern>/checklogin</url-pattern>
</servlet-mapping>
</web-app>
The servlet is now mapped to http://myhost/myappname/checklogin. You can then send ajax post request to this servlet via jquery:
$.ajax('checklogin', {
type: 'POST'
}).done(function(res) {
console.log(res.status); // will give you 'not logged in'
});
This approach is ofcourse an old and obsolete approach, but it's good for you to understand servlet basics. If you're building real-life enterprise application consider using web frameworks such as Spring or JSF.
You can send the user status and the sign-in URL in the response as JSON. Let us create a model for your response.
public class Result {
private boolean status;
private String url;
Result() {
}
Result(boolean status, String url) {
this.status = status;
this.url = url;
}
// getters and setters
}
Now in your action where you check the user status and build the sign in url, initialise your model.
Result res = new Result(status, url);
Now we need to send this model as json response. There are many ways to do that but I will be using the Google GSON to serialize the model into json string.
private String result;
public void getResult() {
return this.result;
}
public void setResult(Stringresult) {
this.result = result;
}
Gson gson = new Gson();
result= gson.toJson(res);
==> json is {"status": true,"url":"www.example.com"}
The last part is checking the response in your client side and taking the appropriate action.
$.ajax({
// ...
success: function(response) {
var responseJson = JSON.parse (response.responseText);
if (!responseJson.status) {
window.location.href = responseJson.url;
}
}
});
References : https://sites.google.com/site/gson/gson-user-guide
Related
I have a website through which you can create bundles and add custom or predefined tasks to them.
Everything works okay, I can change all these fields whenever I want. Once all these fields look alright to you, you have to click the "Save" button. Once you click it, the fields are validated through several methods. If all the fields were validated successfully, Ajax sends a post request to my Spring controller which then stores everything into a database. After that, I would like to redirect user to the page which displays all the existing bundles.
I have already tried to do this:
#RequestMapping(value = "/bundle", method = RequestMethod.POST, consumes = {"application/octet-stream", "multipart/form-data"})
public void bundle(MultipartHttpServletRequest request,
HttpServletResponse response) throws IOException {
// Code to store bundles to a database.
// Redirect
response.setHeader("Location", "http://localhost:8080/bundles");
response.setStatus(302); //302 Found
// I have also tried to replace above two statements with this
response.sendRedirect("http://localhost:8080/bundles");
}
The above code does execute and the request is sent to /bundles
But I seem to be stuck on the initial page, no redirect was made.
I had the same problem as you have. I solved the issue by redirecting in the Front-End with Angular.
You can use the answer from your HTTP-Request in javascript and then redirect from there.
My Server-Side code:
#PostMapping(AdminToolConstants.MAPPING_CHECK_USER)
public ResponseEntity checkUser(HttpServletResponse response, #RequestBody UserDto userDto) throws IOException{
if (userService.checkUser(userDto)) {
return new ResponseEntity(HttpStatus.OK);
} else {
return new ResponseEntity(HttpStatus.BAD_REQUEST);
}
}
Client-side javascript:
angular.module('admintool.services', []).factory('UserService', ["$http", "CONSTANTS", function($http, CONSTANTS) {
var service = {};
service.checkUser = function (userDto) {
return $http.post(CONSTANTS.checkUser, userDto).then(function (value) {
window.location.href = "/";
}).catch(function (reason) { window.location.href = "/register" });
};
return service;
}]);
Inside .then I redirect the user when the, for example, login was successfull and inside .catch if the login wasn't successfull.
I'm working with Spring and have 2 controllers, one of them is:
#RequestMapping("/meni/{id}")
public String meni(#PathVariable String id, Model model, HttpServletRequest request, HttpServletResponse response){
cookie = new Cookie("fake_session",id);
cookie.setMaxAge(30*60);
response.addCookie(cookie);
return "meni";
}
Then in the 'meni' static HTML page, I have a post request that goes to:
#PostMapping("/index/{id}")
public void post(#PathVariable String id,#RequestBody TestDTO testDTO, HttpServletResponse response, HttpServletRequest request){
Cookie [] cookies = request.getCookies();
for (int i=0;i<cookies.length;i++){
Cookie cookie = cookies[i];
if (cookie.getName().equals("fake_session")){
System.out.println("Same cookie!");
}
}
However, the if never gets passed. If i go to the get controller twice, it recognizes the cookie, but if i go the post controller, it the if does not get passed. Everything else is running smoothly in the post controller, it does all its other tasks well.
I go to the Post controller by clicking a button that calls a ajax function in my java script that sends a POST request to that URL. Am I suppose to do something with the cookie there maybe ? I always go to the GET controller before going to the post controller so that the cookie gets created.
Try using Spring MVC's #CookieValue(value = "fake_session", defaultValue = "default") to access data set within any HTTP cookie in your post method.
I need to dispatch a web service caller to a new page using Response object:
#Path("controller")
#Stateless
public class ControllerEJB {
HttpSession session;
User user;
String url;
#POST
public Response registerUser(
#QueryParam("fornamn") String fornamn,
#QueryParam("efternamn") String efternamn,
#QueryParam("epost") String epost,
#QueryParam("epost2") String epost2,
#QueryParam("password") String password,
#Context HttpServletRequest request
){
session = request.getSession();
if(user == null)
user = new User();
user.setEmail(epost);
user.setPassword(password);
user.setFornamn(fornamn);
user.setEfternamn(efternamn);
session.setAttribute("user", user);
return Response.status(200)...... // e.g. url is a .jsp
}
What method should I be using?
JAX-RS is designed to build REST services.
REST services should return data, generally serialized using XML or JSON.
I wouldn't recommend to forward JAX-RS requests to a view layer such as JSP or JSF.
That said, i'm not sure you can forward the same way RequestDispatcher.forward(req, res) does.
But you can send a redirection using the following:
return Response.seeOther(new URI("/path/to/your/resource")).build();
But as the documenation says, this should be used in a POST/redirect/GET pattern: you may redirect a POST request to another REST resource using the GET method.
But again, redirecting REST resource to a JSP page is an awkward design.
I have a very weird problem in my Spring MVC application. I am writing a login form and POSTing the data via AJAX into a Spring MVC controller that looks like this:
#Controller
public class LoginResourceController {
private static final Logger log = Logger.getLogger (LoginResourceController.class.getName());
#RequestMapping (value="/login", method = RequestMethod.POST)
public String checkAccount (HttpServletRequest httpRequest, HttpServletResponse httpResponse,
#RequestHeader (value = "User-Agent") String retrievedUserAgent,
#RequestParam("username") String username,
#RequestParam("password") String password,
#RequestParam("rememberMe") String rememberMe)
{
//Check username and password in DB, and then if OK,
return "redirect:/login/redirectToMain";
}
#RequestMapping (value = "/login/redirectToMainpage", method = RequestMethod.GET)
public String redirectControllerToMainPage (HttpServletRequest httpRequest, HttpServletResponse httpResponse)
{
return "mainPage";
}
Now, the problem is, I have the client (browser) upon redirect requesting a URL that contains the entire contents of mainPage.jsp in the URL. So it looks like:
https://localhost:8443/<!DOCTYPE html><html><head><meta charset=utf-8 /><title>Page that the subscriber sees after login</title>....
I am quite confounded by this error. Is this some servlet setting in WEB-INF/web.xml or mvc-dispatcher-servlet.xml that I need to change? I am using Spring 3.0.5.
BTW, my redirect works flawlessly for GET method controllers in the same Spring MVC application. (e.g., when I re-load the main page of my application, the redirect to the logged in mainPage.jsp above works flawlessly). Moreover, other GET methods on other jsps work correctly too (example, redirect to /login page via login.jsp via a GET of https://localhost:8443/.
I have checked the following and they didn't help: 1 2.
Try not to put the redirect in the return of the controller. This seems to either cause the full page to be rendered as the ajax response, or a redirect header is filled in with an url with the full contents of the page as a string in the response body.
As a first approach, try to make the request a normal HTTP request instead of ajax, and it should just work.
Alternativelly try to make the return body empty, and return an HTTP status code to the client. Either 200 OKif the account is OK or 401 Unauthorized:
#RequestMapping (value="/login", method = RequestMethod.POST)
public ResponseEntity checkAccount (HttpServletRequest httpRequest, HttpServletResponse httpResponse,
#RequestHeader (value = "User-Agent") String retrievedUserAgent,
#RequestParam("username") String username,
#RequestParam("password") String password,
#RequestParam("rememberMe") String rememberMe)
{
//Check username and password in DB
....
HttpStatus returnCode = null;
if(usernameAndPasswordOK) {
returnCode = HttpStatus.OK;
}
else {
returnCode = HttpStatus.UNAUTHORIZED;
}
return new ResponseEntity(returnCode);
}
And then on the client redirect with Javascript accordingly.
This was a little tricky for me to figure out, and being a web development noob doesn't help here. Anyway, #jhadesdev's answer above pointed me to the issue.
On my client, I do this:
$("#loginForm").submit(function(evt)
{
evt.preventDefault();
if (loginFormInputIsValid ())
{
$.ajax ({
type: "POST",
url: "/login",
data: $(this).serialize(),
success: function (response)
{
window.location = response;
}
});
}
}
which was the issue--you see, setting the window.location=response; caused the client (browser) to request the server for the funky URL above. I have to change my client call (this is where #jhadesdev's response helped) to make sure I don't do something so wrong.
Thanks for your time, #jhadesdev.
The problem I am trying to solve is having a javascript function that will perform some functions in sequence.
Step 1) Web client/javascript does some functions locally to the browser.
Step 2) The browser calls a java class/application on the webserver which will perform a number of tasks that only the webserver itself (not the client) can perform.
Step 3) Have the results of step two added to the webpage and displayed in the browser without reloading all the HTML
N.B. Step 2 may take several minutes and it is ok for the client to be essentially inactive during this time.
I'd appreciate any advice or walk throughs/tutorials that may be relevant.
Kind Regards
Use jQuery to perform an asynchronous HTTP request(AJAX)
function YOURFUNCTION(){
//Calls servlet
$.post('ServletName',{parameter:value,parameter2:value2,...},function(results) {
//displays results returned from servlet in specific div(resultsDiv)
$('#resultsDiv').html(results);
});
}
You need to include the jQuery library on top of your HTML file as:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
You may find more info here
Simple as that.
i hope this concise explanation will give you an overview and the understanding you expect.
PART A
SERVER SIDE
In your web server application on your server, if using Java, you are to create a Java servlet class to process data that was submitted from client browser via script or form and to provide dynamic content such as the results of a database query from the client.
Read more on Servlets from:
http://docs.oracle.com/javaee/5/tutorial/doc/bnafe.html
http://en.wikipedia.org/wiki/Java_Servlet
What is Java Servlet?
Also read more about how to register your servlet on the server (web.xml for java Projects)
Example of a servlet:
-================-
#WebServlet(name = "MyServlet", urlPatterns = {"/calculator"}, asyncSupported = true)
public class MyServlet extends HttpServlet {
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Enumeration e = request.getParameterNames(); // parsing the string from client
while (e.hasMoreElements()) {
String name = (String) e.nextElement();// eg. "command" from ajax
String value = request.getParameter(name); // eg. getSum
if (value.equals("getSum")) {
// Instantiate a java class and call the method
// that performs the addition and returns the value
Calculator calc = new Calculator();
String answer = (String) calc.getSum();
if (answer != null) {
// Set contentType of response to client or browser
// so that jQuery knows what to expect.
response.setContentType("text/plain");
PrintWriter out = response.getWriter();
// return answer to ajax calling method in browser
out.print(answer);
out.close();
}
}
} // END While LOOP
}
#Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// include method if you call POST in you ajax on client side
}
}
a Java Class for calculations on your server path
public class Calculator {
public int getSum() {
return 10+15;
}
}
-
PART B
CLIENT SIDE – Your Browser
-======================-
You have to visit jQuery website, download and add the jQuery ajax script to your project. “jquery-ui.min.js” is sufficient for this purpose. Add this script to your html or jsp file using the following line:
<script src="resources/ajax/libs/jqueryui/1.8/jquery-ui.min.js" type="text/javascript"></script>
Within your external javascript file or inline javascript include a function to call the servlet and get the sum as follows:
function getSum(){
$.ajax({
type: 'GET', // type of request to make. method doGet of the Servlet will execute
dataType: 'text', // specifying the type of data you're expecting back from the server
url: 'calculator', // the URL to send the request to. see annotation before class declaration
data: "command="+"getSum", // Data to be sent to the server (query string)
// if request fails this method executes
error:
function(e){
alert('Error. Unable to get response from server');
},
// when request is successful, this function executes
// display the data from server in an alert
success:
function(result){
if(result) {
alert(result);
}
}
});
}