this is my first time with Java's servlet (and JSP) programming and right now I have a doubt. Imagine that I'm building an online shop with a login page (let's suppose is the starting page) and maybe a shopping page (the "second" one). My servlet contains the code for autenticate the users and if the user is correct the servlet should shows the shopping catalog. My answer is, what's the best method for doing this? This is my servlet code (doGet) now:
nb: userName and password come from the login page...
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().append("Served at: ").append(request.getContextPath());
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String userName = request.getParameter("userName");
String password = request.getParameter("password");
out.println("<html>");
out.println("<body bgcolor = 'green'>");
out.println("<br>" + "Hello " + " " + userName + "<br> LOGGED IN!" + "<br>");
out.println("Your password is : " + " " + password + "<br>");
if(userName.equals("some_correct_user")) {
out.println("<p>Login correct </p>");
response.sendRedirect("/FirstServletExercise/shoppingPage.html");
}
else {
out.println("<p>Access denied</p>");
}
I know it's very simple but is just the concept: it's correct to use "sendRedirect" to display another different page, or I have to upgrade the content of the first page? And how I can do this? Hope I have explained myself well.
Thanks!
I am using Jetty-11 Server standalone/embedded mode. And here is how the Login Servlet looks like.
import java.io.IOException;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
public class LoginServlet extends HttpServlet {
private Logger log = LoggerFactory.getLogger(LoginServlet.class);
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
log.debug("LoginServlet {} userPrincipal: {}", req.getServletPath(), req.getUserPrincipal());
Map<String, String[]> p = req.getParameterMap();
p.forEach((k, v) -> {
log.debug("{} {}", k, v);
});
String un = (p.get("j_username") != null) ? p.get("j_username")[0] : null;
String up = (p.get("j_password") != null) ? p.get("j_password")[0] : null;
try {
if (un != null && up != null) {
req.logout();
req.login(un, up);
}
} catch (Exception e) {
log.error("AuthenticationException: ", e);
}
log.debug("{} userPrincipal: {}", req.getServletPath(), req.getUserPrincipal());
boolean isAuth = (req.getUserPrincipal() == null) ? false : true;
log.debug("isAuth: {}", isAuth);
resp.setContentType("text/html");
if (isAuth) {
/** Session Management */
HttpSession session = req.getSession();
session.setAttribute("user", req.getUserPrincipal().getName());
// setting session to expiry in 30 mins
session.setMaxInactiveInterval(30 * 60);
log.debug("sessionId: {} ", req.getSession().getId());
/** Cookie Management */
Cookie loginCookie = new Cookie("user", req.getUserPrincipal().getName());
loginCookie.setMaxAge(30 * 60);
resp.addCookie(loginCookie);
/** Login Success - so display the Home Page */
resp.sendRedirect("./index.html");
} else {
Cookie loginCookie = new Cookie("user", "unknownUser");
loginCookie.setMaxAge(0);
loginCookie.setPath("/");
resp.addCookie(loginCookie);
req.getRequestDispatcher("./login.html").forward(req, resp);
}
}
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
Related
I have call this method under doGet. Please help me to get out of this.
This is my own method and I wanted to call this.
public void doYourThingHere(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
String[] checkedQues = request.getParameterValues("ttom");
List<String> checkedQuesList = Arrays.asList(checkedQues);
Map<String, String> preferences = new LinkedHashMap<String, String>();
if (session.getAttribute("username") != null) {
List<Question> questionsList = (List<Question>) session
.getAttribute("restaurantQuestionList");
List<Question> questionsListTemp1 = new ArrayList<>();
for (int i = 2; i < 4; i++) {
questionsListTemp1.add(questionsList.get(i));
}
session.setAttribute("tomtomRestaurantQuestionList1",
questionsListTemp1);
for (Question question : questionsList) {
String questionId = String.valueOf(question.getId());
if (checkedQuesList.contains(questionId)) {
String answerId = request.getParameter(questionId);
// PreferenceDAO.storePreferences(questionId, answerId,
// CATEGORY);
preferences.put(questionId, answerId);
System.out.println("queid : " + questionId + "answerid : "
+ answerId);
}
}
String username = (String) session.getAttribute("username");
PreferencesProcessor.process(preferences, username);
RequestDispatcher requestdp = request
.getRequestDispatcher("WEB-INF/jsp/table.jsp");
requestdp.forward(request, response);
} else {
RequestDispatcher requestdp = request
.getRequestDispatcher("WEB-INF/jsp/login.jsp");
requestdp.forward(request, response);
}
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
/**
* #see HttpServlet doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
Servlets map HTTP request headers to predefined methods, such as doGet(), doPost(), and some others.
https://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/http/HttpServlet.html
Since your method modifies data, you should call it with POST.
Most simple way is to forward your doPost() to this method:
public void doPost(HttpServletRequest request, HttpServletResponse response) {
doYourThingHere(request, response);
}
What will happen usually is that you'll add some routing logic to your doPost like that:
public void doPost(...) {
String action = request.getParameter("action");
switch (action) {
case "doSomething":
doSomething(request, response);
break;
case "somethingElse":
doSomethingElse(request, response);
break;
...
}
}
public class Guestbook extends CacheHttpServlet {
/**
*
*/
private static final long serialVersionUID = 1 L;
private Vector < GuestbookEntry > entries = new Vector < GuestbookEntry > ();
private long lastModified = 0; // Time last entry was added
// Display the current entries, then ask for a new entry
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
printHeader(out);
printForm(out);
printMessages(out);
printFooter(out);
}
// Add a new entry, then dispatch back to doGet()
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
handleForm(req, res);
doGet(req, res);
}
private void printHeader(PrintWriter out) throws ServletException {
out.println("<HTML><HEAD><TITLE>Guestbook</TITLE></HEAD>");
out.println("<BODY>");
}
private void printForm(PrintWriter out) throws ServletException {
out.println("<FORM METHOD=POST action='/hello.html'>"); // posts to itself
out.println("<B>Please submit your feedback:</B><BR>");
out.println("Your name: <INPUT TYPE=TEXT NAME=name><BR>");
out.println("Your email: <INPUT TYPE=TEXT NAME=email><BR>");
out.println("Comment: <INPUT TYPE=TEXT SIZE=50 NAME=comment><BR>");
out.println("<INPUT TYPE=SUBMIT VALUE=\"Send Feedback\"><BR>");
out.println("</FORM>");
out.println("<HR>");
}
private void printMessages(PrintWriter out) throws ServletException {
String name, email, comment;
Enumeration < GuestbookEntry > e = entries.elements();
while (e.hasMoreElements()) {
GuestbookEntry entry = (GuestbookEntry) e.nextElement();
name = entry.name;
if (name == null) {
name = "Unknown user";
email = "Unknown email";
}
email = entry.email;
comment = entry.comment;
if (comment == null) comment = "No comment";
out.println("<DL>");
out.println("<DT><B>" + name + "</B> (" + email + ") says");
out.println("<DD><PRE>" + comment + "</PRE>");
out.println("</DL>");
// Sleep for half a second to simulate a slow data source
try {
Thread.sleep(500);
} catch (InterruptedException ignored) {}
}
}
private void printFooter(PrintWriter out) throws ServletException {
out.println("</BODY>");
out.println("</HTML>");
}
private void handleForm(HttpServletRequest req,
HttpServletResponse res) {
GuestbookEntry entry = new GuestbookEntry();
entry.name = req.getParameter("name");
entry.email = req.getParameter("email");
entry.comment = req.getParameter("comment");
entries.addElement(entry);
// Make note we have a new last modified time
lastModified = System.currentTimeMillis();
}
public long getLastModified(HttpServletRequest req) {
return lastModified;
}
}
class GuestbookEntry {
public String name;
public String email;
public String comment;
}
And in the XML file i used
<web-app>
<servlet>
<servlet-name>
GuestBook
</servlet-name>
<servlet-class>
Guestbook
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>
GuestBook
</servlet-name>
<url-pattern>
/hello.html
</url-pattern>
</servlet-mapping>
</web-app>
everything i used are fine but tomcat still gives me a 404 error. although i tried by different methods but still it gives me an error.
if someone will provide a solution then it would be really appreciated.
thanks in advance
we would need to create a separate html page and will write the same content as "PrintForm" method in the code. if we do so then this servlet will work perfectly. Although this servlet used for server cache, i hope it will help you in future.
thank you
When I'm calling doPost directly, it shows me profile page in correct way. But then after login I open new tab in Chrome copy url "http://localhost:8080/17_servlets_jsp/profile" there and it shows me blank page
#WebServlet("/profile")
public class Profile extends HttpServlet {
**private String login;**
private HttpSession httpSession;
private User user;
private Role role;
public static Logger LOGGER = LogManager.getLogger(Profile.class.getName());
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
httpSession = req.getSession();
try (PrintWriter out = resp.getWriter()) {
**if (httpSession.getAttribute("userLoggedIn") == null) {
out.println("<title>Login Page</title>");
out.println("<p>Please follow the link to login</p>");
} else {
login = (String) httpSession.getAttribute("uLogin");
doPost(req, resp);
}**
} catch (IOException | NullPointerException e) {
LOGGER.error(e);
}
}
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
**login = req.getParameter("login");
user = new ImplUserDAO().findByLogin(login);**
httpSession = req.getSession();
resp.setContentType("text/html");
try (PrintWriter out = resp.getWriter()) {
out.println("<title>Profile page</title>");
if (user != null && user.getPassword().equals(req.getParameter("pass"))) {
role = new ImplRoleDAO().findById(user.getRoleId());
httpSession.setAttribute("userLoggedIn", true);
httpSession.setAttribute("uLogin",req.getParameter("login"));
httpSession.setAttribute("uPass",req.getParameter("pass"));
out.println("user id = " + user.getUserId());
out.println("login = " + user.getLogin());
out.println("password = " + user.getPassword());
out.println("role = " + role.getRoleName());
out.println("<form action=\"logout\" method=\"get\"/>" +
"<input type=\"submit\" value=\"Logout\"/>" +
"</form>");
if (role.getRoleName().equals("admin")) {
httpSession.setAttribute("isAdmin", true);
out.println("Go to admin page");
}
} else {
out.println("Wrong login or password");
out.println("Please follow the link to login");
}
} catch (IOException | NullPointerException e) {
LOGGER.error(e);
}
}
}
By calling doPost() you also execute this line:
user = new ImplUserDAO().findByLogin(req.getParameter("login"));
Which will throw an Exception or return null or whatever because your GET request didn't include that parameter. If you want to reuse doPost() you'd need to fetch login from either session or request:
String login = req.getParameter("login");
if(null == login) {
login = (String)httpSession.getAttribute("uLogin");
}
Or similar.
On Attributes and Parameters
In your commented out code, you tried to solve this issue by calling setAttribute("login"... on your request. While this is legal, you can not retrieve that value by calling getParameter(). Instead you'd have to call 'getAttribute()` again - which doesn't make much difference to retrieving directly from the session:
//Retrieve Parameter (been send into the servlet from outside)
String login = req.getParameter("login");
if(null == login) {
//Retrieve Attribute you put into the request in doGet()
login = (String)req.getAttribute("login");
}
Another Edit
You have the same issue with req.getParameter("pass").
You should seriously consider splitting login-process (checking username/password from request) from other functionality (display profile page) or reverse your logic: Do login, set user into session in doPost() and if successful call goGet()?
Full Example Code
Consider these changes to somewhat fix your logic:
#WebServlet("/profile")
public class Profile extends HttpServlet {
// Don't use member variables on Servlets - they get reused for all users!
// private String login;
// private HttpSession httpSession;
// private User user;
// private Role role;
public static Logger LOGGER = LogManager.getLogger(Profile.class.getName());
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
HttpSession httpSession = req.getSession();
try (PrintWriter out = resp.getWriter()) {
if (httpSession.getAttribute("userLoggedIn") == null) {
out.println("<title>Login Page</title>");
out.println("<p>Please follow the link to login</p>");
}
else {
User user = httpSession.getAttribute("userLoggedIn");
Role role = httpSession.getAttribute("userRole");
out.println("<title>Profile page</title>");
out.println("user id = " + user.getUserId());
out.println("login = " + user.getLogin());
out.println("password = " + user.getPassword());
out.println("role = " + role.getRoleName());
out.println("<form action=\"logout\" method=\"get\"/>" +
"<input type=\"submit\" value=\"Logout\"/>" +
"</form>");
if("true".equals(httpSession.getAttribute("isAdmin")) {
httpSession.setAttribute("isAdmin", true);
out.println("Go to admin page");
}
}
} catch (IOException | NullPointerException e) {
LOGGER.error(e);
}
}
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String login = req.getParameter("login");
User user = new ImplUserDAO().findByLogin(login);
HttpSession httpSession = req.getSession();
try (PrintWriter out = resp.getWriter()) {
if (user != null && user.getPassword().equals(req.getParameter("pass"))) {
Role role = new ImplRoleDAO().findById(user.getRoleId());
httpSession.setAttribute("userLoggedIn", user);
httpSession.setAttribute("userRole", role);
if (role.getRoleName().equals("admin")) {
httpSession.setAttribute("isAdmin", true);
}
// Now refer to display part.
goGet(req, resp);
} else {
out.println("Wrong login or password");
out.println("Please follow the link to login");
}
} catch (IOException | NullPointerException e) {
LOGGER.error(e);
}
}
}
Basically my goal for this page I'm working on is for users to type in a stock symbol and this information goes to a post method and send back the data to put on the same html/jsp page. I have been able to get this to work where the form leads to another JSP page, but that has to be a separate page, I'd like to be able to stay on the same page and have the info come up. If you have a resource that could teach me how to deal with this problem, I would appreciate that just as much as a solution. I have been using the Gradle Build Tool.
Here is the form(in index.jsp):
<h1>Search Stock</h1>
<form method="POST" action="DataPage.jsp">
<input type = "text" name = "Symbol">
<input type = "submit" name = "getData">
</form>
Here is the functioning JSP code(DataPage.jsp):
<%
String Ticker = request.getParameter("Symbol");
PrintWriter write = response.getWriter();
if((Ticker == null)){
String message = "Please enter a stock symbol";
write.println(message);
}else{
try{
Company object = Serializing.getCompany(Ticker);
object.updateData();
write.println("data last added" + object.getLastUpdate());
write.println(object.getSentiment());
}catch(NullPointerException x){
Company object = Serializing.getCompany(Ticker);
}
}%>
Here is the servlet I tried writing(DataServlet.java), I have very little experience with servlets, I scavenged this from different sources and questions on stackoverflow:
package Default;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* Created by Ceyer on 9/3/2015.
*/
#javax.servlet.annotation.WebServlet(name = "DataServlet", urlPatterns = ("/"))
public class DataServlet extends javax.servlet.http.HttpServlet {
private static final long serialVersionUID = 1L;
public DataServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
String Ticker = request.getParameter("Symbol");
if ((Ticker == null)||Ticker.trim().isEmpty()) {
String message = "Please enter a stock symbol";
request.setAttribute("data", message);
getServletContext().getRequestDispatcher("/login.jsp").forward(request, response);
} else {
PrintWriter write = response.getWriter();
try {
Company object = Serializing.getCompany(Ticker);
object.updateData();
request.setAttribute("data", object.getSentiment() + "updated last" + object.getLastUpdate());
getServletContext().getRequestDispatcher("/login.jsp").forward(request, response);
} catch (NullPointerException x) {
Company object = Serializing.getCompany(Ticker);
request.setAttribute("data", "We do not have info on this stock");
getServletContext().getRequestDispatcher("/login.jsp").forward(request, response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
If you want to use only one page and with a servlet, I think you can use session and response.sendRedirect() to do it.
This is index.jsp page
<h1>Search Stock</h1>
<form method="POST" action="DataServlet" onsubmit="dataCheck()">
<input type="text" name="Symbol">
<input type="submit" value="getData">
</form>
<%
if(session.getAttribute("data") != null) {
out.print("<p>" + session.getAttribute("data"));
session.removeAttribute("data");
}
%>
<script>
function dataCheck() {
if(document.getElementsByName[0].value == ""){
alert("Symbol is null!");
return false;
}
return true;
}
</script>
This is DataServlet class
public class DataServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String Ticker = request.getParameter("Symbol");
Company object = Serializing.getCompany(Ticker);
if (object != null) {
object.updateData();
request.getSession().setAttribute("data", object.getSentiment() +
"updated last" + object.getLastUpdate());
} else {
request.getSession().setAttribute("data", "We do not have info on this stock");
}
response.sendRedirect("index.jsp");
}
}
I want to do some log in my system, like user action,
and I know in the servelet I can get the request with all the session,parameter..etc
So I want to write the Servlet
public class UserActionCheck extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
Map map = request.getParameterMap();
Set keSet = map.entrySet();
for (Iterator itr = keSet.iterator(); itr.hasNext(); ) {
Map.Entry me = (Map.Entry) itr.next();
Object ok = me.getKey();
Object ov = me.getValue();
String[] value = new String[1];
if (ov instanceof String[]) {
value = (String[]) ov;
} else {
value[0] = ov.toString();
}
for (int k = 0; k < value.length; k++) {
System.out.println(ok + "=" + value[k]);
}
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//HttpSession session = request.getSession();
}
}
then I can see the parameter output in the tomcat console..but I get the blank page..
It seems the page is stop after doGet method..
so how should I make it continue?
use that RequestDispatcher?
also how to handle in the doPost?
For your purpose, the best way would be to use a Filter.
Example :
#WebFilter(filterName = "monitoringFilter", urlPatterns = { "/*" })
public class MonitoringFilter implements Filter
{
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
{
// Right here do your stuff pretty much like in a servlet
request // ... get information you need
// Process request as normal
chain.doFilter(request,response);
}
#Override
public void init(FilterConfig config) throws ServletException
{
}
#Override
public void destroy()
{
}
}
More info :
Filter
You should use log4j and FileAppender to implement logging in your application.
Something like this :::
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
class A{
static Log log = LogFactory.getLog(A.class);
void methodA(){
try{
log.info("I am inside A");
} catch(Exception e) {
log.error("error" , e);
}
}
}