I have a form which when submitted stores data from it's fields to the database. The action forward in the struts-config maps back to the same page on Success/Failure of data insertion into the database. I would like to alert the user once this is successfully completed, so I set a session attribute(i.e. success/failure) in the method of the action class for the form. I then get and print out this session attribute once the jsp page has been accessed again.
So far I have done this in the Action Class:
public static void setJavaScriptNotification(HttpServletRequest request, String notificationText) {
HttpSession session = request.getSession(true);
session.setAttribute("notification_javascript", notificationText);
}
And in the jsp file that contains the form I have:
<% String notificationJavaScript = (String) request.getSession().getAttribute("notification_javascript");
pageContext.setAttribute("notification_javascript", notificationJavaScript);
request.getSession().removeAttribute("notification_javascript"); %>
<html>
<head>
<logic:present name="notification_javascript">
<script type="text/javascript" language="JavaScript">
function showAlerts() {
alert("<bean:write name="notification_javascript"/>");
}
</script>
</logic:present>
</head>
<body onload="doPreOnload(); showAlerts();">
When I print out the session attributes in the jsp, I can't find the notification_javascript attribute. I'm new to HTTP, so I could be doing something wrong there.
After setting notification_javascript in session in setJavaScriptNotification() do the request is forwarded to jsp where notification_javascript is accessed.
If yes, then session.getAttribute("notification_javascript") will do the job.
request.setAttribute() vs session.setAttribute()
request.setAttribute() will make the key available in following page.
session.setAttribute() will make the key available in all pages.
Related
For context I have a jsp called "withdraw.jsp" that calls a servlet that processes a withdrawal. In this servlet I would like to pass a string message if the transaction is successful or not and I would like to send this message to the same jsp that called the servlet (which is still "withdraw.jsp". Here is what I did so far
//In the servlet
RequestDispatcher view = request.getRequestDispatcher("registeredUser/withdraw.jsp");
String error = (String)ex.getMessage();
request.setAttribute("errorMessage", error);
view.include(request,response); // i also tried forward here
//In the jsp
<% if(request.getParameter("errorMessage") != null){ %>
<p> <%=(String)request.getParameter("errorMessage")%> </p>
<% } %>
If I run this code, the jsp wouldn't retrieve the errorMessage since it is null despite being set as an attribute by the servlet. Any help?
You are confusing attributes with parameters.
The message is always null in your JSP because you have set an attribute in you servlet, but in your JSP you are looking for a parameter. They are different things.
Things to do:
.forward(...) to your JSP using the RequestDispatcher;
make sure you retrieve an attribute in your JSP;
do not use scriptlets. Depending on your JSP version you can use EL expressions or JSTL.
Could you help me to come up with solution.
There are JSP-page which sends form parameters to servlet.
Usually I parse parameters by HttpServletRequest.getParameter() which works fine for forms with tiny parameter numbers.
Now I'm developing application which has a lot of JSPs with number of parameters and the standard way of form processing is inconvenient.
I think that possible solution might be by using -action.
I don't understand whether it works for me.
I browsed a lot of materials but find nothing about it.
I mean that there is any information regarding possibility to get form parameters in jsp by ,
automatically create instance of the entity class,
map all the parameters to entity-properties and send the entity-instance to the servlet.
Please take a look at the code:
index.jsp
<html>
<head>
<title></title>
</head>
<body>
<form method="post" action="NewFormServlet" enctype="application/x-www-form-urlencoded">
<jsp:useBean id="client-bean" class="model.entity.Client" scope="request"/>
<h3>Please enter client information</h3><br>
Client first name<input type="text" name="first-name"/><br>
<jsp:setProperty name="client-bean" property="firstName" value="${requestScope.first-name}"/>
Client last name<input type="text" name="last-name"/><br>
<jsp:setProperty name="client-bean" property="lastName" value="${requestScope.last-name}"/>
Client address<input type="text" name="address" size="100"/><br>
<jsp:setProperty name="client-bean" property="address" value="${requestScope.address}"/>
Client city<input type="text" name="city"/><br>
<jsp:setProperty name="client-bean" property="city" param="${requestScope.city}"/>
Client postal code<input type="text" name="postal-code"><br>
<jsp:setProperty name="client-bean" property="postalCode" value="${requestScope.postal-code}"/>
<input type="hidden" name="jsp-identifier" value="client-form">
<input type="submit" value="Submit">
</form>
</body>
</html>
What is incorrect in this code? Thank you in advance.
You should first think about what occurs on server and what occurs in browser, as well as what is transmitted via HTTP. A form submission uses many phases :
on server : the JSP is executed using servlet context, session, and request attributes, with still full access at the previous request (parameters, ...) => all that generates a HTML page (with eventually css or javascript linked or included)
on browser : the browser gets and parses the HTML page, optionnaly gets linked resources (images, etc.), and display the form to the user
on browser : the user fills the input fields of the form and clicks the input button
on browser : the browser collates data form input fields, generate an new HTTP request (usually a POST one) and sends it to server
on server : the servlet container pre-processes the request (until that is is only a stream of bytes conforming to HTTP protocol) and calls the appropriate servlet method with a new HttpServletRequest reflecting current HTTP request, and a HttpServletResponse to prepare what will be sent back to browser after processing
All that means that anything you can do to request attributes in the JSP part will be lost at the time of processing of the submitted form by the servlet. You can only rely on session attributes, and on input form fields that will be accessible as request parameters.
So with your current JSP, the Servlet will find nothing in request attributes (it is a different HttpServletRequest) and will only be able to use parameters with names firstName, lastName, address, city, etc.
I can understand it is not the expected answer, but HTTP protocol is like that ...
EDIT per comment :
You can put the attribute in session, and then the servlet will use the same session as the JSP. But read again what I wrote above and think when things happen :
on server, when executing the JSP, you create an empty Client bean that you put in session scope, and use its value to initialize the form fields. Stop for the server part
on client, user fills the input fields - the server knows nothing on that - and submit the form through a new request
on server, the servlet has the values in request parameters, but the session still contains the previous values and so the Client bean has null values
I'm sorry but there's not enough magic for the server to automatically find in its attributes (either request or session) what comes from form submission : it only exists in request parameters, and it is the servlet job to process them and eventually put them in attributes.
Edit:
It appears that jsp:useBean is an old school way to collect up a group of parameter values for easier display on a page.
It does not add an attribute when the request is posted.
Based on that,
I see little value in the jsp:useBean tag,
since you can use el expressions to access attributes that you set in a servlet.
This does not help you get the posted parameter values into a bean in the servlet.
You can write a method on the bean to extract the parameter values from the request (visitor pattern).
For example:
class bean
{
private String value;
public void loadFromHttpServletRequest(final HttpServletRequest request)
{
value = request.getParameter("value");
}
}
Consider using a package like spring-mvc.
I am using spring 3 MVC and i have below classes.
External system would call my application using below URL:
http://somehost/root/param1/param2/param3
I have a spring MVC controller method as below:
public ModelAndView showPage(#PathVariable("param1") String paramOne, #PathVariable("param2") String paramTwo, #PathVariable("param3") String paramThree, HttpServletResponse response) {
SomeModel model = new SomeModel(paramOne, paramTwo, paramThree);
return new ModelAndView("SomeJsp", "model", model);
}
SomeModel.java
public class SomeModel{
private String paramOne;
private String paramTwo;
private String paramThree;
//constructor
//setters and getters
}
SomeJsp.jsp
//In this Jsp i have a div with few elements. Div is not visible by default.
//This jsp has externalJavascript included.
//I enable div and set the data into div elements using jquery.
externalJs.js
$(document).ready(function() {
//Here i need the model returned using ModelAndView
//I can get data from model and set into div elements.
});
In external java script file, is it possible to get the model content?
Thanks!
In the jsp page you may define global js variable and access those variables from the external js like:
jsp file
<script>
myModel=[];
myModel.paramOne='${model.paramOne}';
myModel.paramTwo='${model.paramTwo}';
myModel.paramThree='${model.paramThree}';
</script>
All server side scripts been rendered at server side and those value will be hardcoded once rendered. Once page loaded in the browser, global variables will be created with the rendered hardcoded value.
And my myModel can be access in the external file also.
EDIT:
Here is the someJsp.jsp file
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE>
<html>
<head>
<script>
myModel=[];
myModel.paramOne='${model.paramOne}';
myModel.paramTwo='${model.paramTwo}';
myModel.paramThree='${model.paramThree}';
</script>
<script src="externalJs.js"></script>
</head>
<body>
<!--content-->
</body>
and externalJs.js
$(document).ready(function() {
// myModel will be accessible from here because it's globally declared
alert(myModel);
});
I have this strange problem with sendRedirect function which i can't explain.
I have a header page as Header.jsp as :
<%# page contentType="text/html; charset=iso-8859-1" language="java" import="java.sql.*,java.util.*" errorPage="" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Online Exam Portal</title>
<style type="text/css">
body{
background-color : lightgreen;
}
</style>
</head>
<body>
<%
if(session.getAttribute("userid")==null)
{
response.sendRedirect("signup.html");
}
%>
<img src="exam_header01.jpg"/>
<br />
Welcome <%=session.getAttribute("userid")+"This is Working"%>
Change Password
Logout
<hr/>
i have included this header page in all the pages, i did this since i wanted to prevent the users who don't have valid session and redirect to signup page but it doesn't redirects
instead it shows Welcome null and also :
1> If i write anything inside that if statement it works fine! , like :
if(session.getAttribute("userid")==null)
{
response.sendRedirect("signup.html");//this is not executed
out.println("This Runs");//this String is printed
}
2> If i write the same code inside the main page(i.e after header page) it works fine!
3> And most importantly the code works when i replace it by :
<jsp:forward page="signup.html"/>
What could be the problem here. it would be really appreciated if anyone can explain with examples.
Update :-
Even If i print to my page after Redirect it will work if i use if statement use after including the Header :
<jsp:include page="Header.jsp"/>
<%if(session.getAttribute("userid")==null)
{
response.sendRedirect("signup.html");
out.println("I cant See this because page is redirected ");
}
%>
</body>
</html>
As others have said, this isn't the best way to achieve what you want to achieve.
That said, the problem you are seeing is as a result of using the wrong type of include. You are using request time include (<jsp:include page="..." />) which processes the included page and inserts the output (if any) into the current page. If you call response.sendRedirect() from an included page it is ignored. Hence your current solution doesn't work.
You would need to use a translation time include (<%# include file=... %>) which takes the source of the included page, inserts it into the source of the current page and then processed the current page as if it was a single JSP.
From the javadoc:
After using this method, the response should be considered to be committed and should not be written to.
You don't respect this, since you continue to print to the response after sendRedirect().
The main problem is in your architecture. JSPs are view components. They should not contain scriptlets, and should not redirect. They should only generate HTML markup from beans stored in request attributes by a controller, written in Java, as a servlet or action of your preferred MVC framework. And to generate this markup, they should only use the JSP EL, the JSTL and other custom tags.
Instead of repeating the login check in every JSP, which is extremely error-prone and repetitive, you should have a servlet filter which intercepts all the requests, makes the check, and let the next component (a controller) do its job of the user is authenticated.
request --> authentication filter --- if authenticated ---> controller --- forward to ---> JSP
|
|--- if not authenticated --- redirect to --> authentication controller --- forward to ---> login.jsp
For authentication purposes, use Filters.
A Filter is nothing but a Java class that is used to preprocess the request before it is forwarded to the resource the user asked for.
Eg. if you have mapped your filter class with a servlet, then as and when the request comes in for this servlet, it is initially intercepted by the filter class(which contains your authentication code) and if it succeeds in authentication then only the request is forwarded to the servlet. This makes the authentication more easy and flexible.
For this, you need to map your filter class with the servlet inside web.xml.
In short, response.sendRedirect() would not serve your purpose and you have to ultimately rely on filters.
I have this little java project in which I have to use jsp files.
I have an html with a login button that triggers the following function:
var loginCall = "user/login";
var logoutCall = "user/logout";
var signupCall = "user/signup";
function login() {
var login = baseUrl + loginCall + "?";
var loginFormElements = document.forms.loginForm.elements;
login = addParam(login, USER_NAME, loginFormElements.userName.value, false);
login = addParam(login, PASSWORD, loginFormElements.password.value, true);
simpleHttpRequest(login, function(responseText){
var status = evalJSON(responseText);
if (status.errorCode == 200) {
var res = status.results;
var sessionId = res[0].sessionId;
setCookie(SESSION_ID,sessionId);
window.location="http://localhost:8080/"+baseUrl+"/main.html";
} else {
showError(status.errorCode, "Username or password was incorrect.")
}
}, function(status, statusText){console.log('z');
showError(status, statusText);
});
}
As far as I can see a httpRequest is made and sent with data to baseUrl + loginCall, meaning localhost/something/user/login?name=somename&pass=somepass
This is where I'm stuck, do I have to make a java file somewhere somehow, that takes the request information, works it up with the database and returns an answer?
If so, where, how? Do I have to name it login/user.java?
Can anyone point me to the right direction, if not give me some code example or explanation of what I have to do next?
You need to have another look at the JSP MVC
The jsp page should hold the html and javascript and java code. If you want to call a separate .java class, you need to write that class as a servlet then call it.
So in your .jsp you have you html and javascript just like you have it there, then any java you include in these brackets <% %>
Have a look at the tutorials here http://www.jsptut.com/
And i see your doing a login page. I used this brilliant tutorial for creating a log in system which helped me understand how jsp and servlets worked.
http://met.guc.edu.eg/OnlineTutorials/JSP%20-%20Servlets/Full%20Login%20Example.aspx
Also check out this image which should help you understand the concept. Remember servlets are pure java classes, used for mostly java but can also output html, jsp's are used for mostly html (& javascript) but can include jsp. So the servlets do the work, then the jsp gets the computed values so that they can be utilized by JavaScript. that's how i think of it anyway, may be wrong
http://met.guc.edu.eg/OnlineTutorials/static/article_media/jsp%20-%20servlets/LoginExample%20[4].jpg
All the best
If you are not using any MVC framework then best approach would be to extending HttpServlet classes for handling requests and doing all heavy lifting tasks such as business logic processing,accessing/updating databases etc. and then dispatching the request to .jsp files for presentation.In .jsp.You can also add custom objects to request scope that you wish to access on '.jsp' pages + using expression language you can access most request related implicit objects
I taken a typical example of flow in brief.You may can an idea and explore in deep yourself.
Here is java servlet class that will handle a posted form.
public class doLogin extends HttpServlet{
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException {
String username= request.getParameter("username"); // get username/pasword from form
String password = request.getParameter("password");
// This is your imaginary method for checking user authentication from database
if(checkUserAuthentication(username,password)){
/*
user is authenticated.Now fetch data for user to be shown on homepage
User is another class that holds user info. Initialize it with data received from database
*/
user userData = new User;
user.setName(...);
user.setAge(...);
user.setInfo(...);
// etc
}
RequestDispatcher view = req.getRequestDispatcher("login.jsp");
req.setAttribute("userdata", userData); // set user object in current request scope
view.forward(req, resp);//forward to login.jsp
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException {
}
but you need a form with some action to invoke above ServletClass
<form action="/checkLogin" method="POST">
<input type="text" name="username" value="">
<input type="password" name="password" value="">
<input type="submit" name="login" value="Login">
</form>
To tell your Servlet container to invoke doLogin class on form login button click
you have to configure it in deployment descriptor file web.xml which is part of standard dynamic web application in java
In web.xml' following xml snippet make apllication server aware ofdoLogin` class
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.yourdomain.doLogin</servlet-class>
</servlet>
But its not mapped to any url yet,It is configured as below in <servlet-mapping> section in web.xml
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/checkLogin</url-pattern>
</servlet-mapping>
Now any post request to url /checkLogin will invole doPost method on doLogin class
After successful login request will be trasfered to 'login.jsp' page.
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
You can use java code in sciptlet <% %> syntax to access userData object
<%
User data = (User)request.getAttribute('userData');
%>
Better and tidy approach is to use expression language
${ pageContext.request.userData.name }
Above expression calls getName() method on object of User class using java beans naming conventions
Here, you can learn more about expression language
May be some time later I can improve this and provide you more insight.Hope that helps :)