JUnit test for servlet, when use HttpSession - java

I have this doPost method:
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) {
response.setContentType("text/html");
try {
HttpSession session = request.getSession();
synchronized (session) {
Class.forName("org.postgresql.Driver");
DataSource storage = DataSource.getInstance();
if (session.getAttribute("role").toString().equals("admin")) {
storage.update(request.getParameter("name"), request.getParameter("email"), request.getParameter("createDate"), request.getParameter("login"), request.getParameter("password"), request.getParameter("role"));
} else if(session.getAttribute("role").toString().equals("user")) {
storage.updateByUser(request.getParameter("name"), request.getParameter("email"), request.getParameter("createDate"), session.getAttribute("login").toString());
}
response.sendRedirect(String.format("%s/editUser", request.getContextPath()));
}
} catch (Exception e) {
e.printStackTrace();
}
}
And i have this test:
#Test
public void editUser() throws SQLException {
ServletEditUser servlet = new ServletEditUser();
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
DataSource.getInstance().add("test", "test", "test", "test", "test", "admin");
when(request.getParameter("role")).thenReturn("admin");
when(request.getParameter("login")).thenReturn("test");
when(request.getParameter("name")).thenReturn("edit");
when(request.getParameter("createDate")).thenReturn("edit");
when(request.getParameter("password")).thenReturn("edit");
servlet.doPost(request, response);
List<User> users = DataSource.getInstance().getList();
assertThat(DataSource.getInstance().getList().get(users.size() - 1).getName(), is("edit"));
}
I'm don't understand, how I should test my doPost method. How I should setAttribute for session on JUnit test?
ANSWER:
In JUnit test, need to add:
HttpSession session = mock(HttpSession.class);
when(request.getSession()).thenReturn(session);
when(request.getSession().getAttribute("role")).thenReturn("admin");

In JUnit test, need to add:
HttpSession session = mock(HttpSession.class);
when(request.getSession()).thenReturn(session);
when(request.getSession().getAttribute("role")).thenReturn("admin");

Related

Getting session from another Servlet

I'm trying to store a User object in session in Servlet1. In Servlet2 I'm trying to get the values from the same logged in session from Servlet1.
Servlet1:
private void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
request.setCharacterEncoding("UTF-8");
String emailFromForm = request.getParameter("email").toLowerCase();
String passwordFromForm = request.getParameter("passWord");
try {
User userThatLogsIn = manager.getUser(emailFromForm);
String passwordFromDB = userThatLogsIn.getPassword();
if (passwordFromDB.equals(passwordFromForm)) {
request.getSession().setAttribute("TheLoggedInUser", userThatLogsIn);
response.sendRedirect("/Slit/welcome.jsp");
} else {
request.setAttribute("error", "Unknown login, try again");
response.sendRedirect("/Slit/LoginFailed.jsp");
}
} catch (NullPointerException nullPointer) {
System.err.println("NullPointerException: " + nullPointer.getMessage());
response.sendRedirect("/Slit/LoginFailed.jsp");
}
}
Servlet2: Im getting a nullpointer sessionaccept fnavn
at Mypage.MyPageServlet.sessionAccept(MyPageServlet.java:40)
private void sessionAccept(HttpServletRequest request, HttpServletResponse response) throws IOException {
HttpSession session = request.getSession();
session.setMaxInactiveInterval(30 * 60);
User loggedInUser = (User) request.getAttribute("TheLoggedInUser");
String fnavn = loggedInUser.getfName();
String enavn = loggedInUser.getlName();
String epost = loggedInUser.getEmail();
request.getSession().setAttribute("messageJSP", "Velkommen" + epost);
response.sendRedirect("Innstillinger.jsp");
}
This line
User loggedInUser = (User) request.getAttribute("TheLoggedInUser");
has to replaced with
User loggedInUser = (User)
request.getSession().getAttribute("TheLoggedInUser");

i am working on servlets, having only one deGet and DoPost method. i wrote one new method in that. . how can i access that new method directly?

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;
...
}
}

Can't call doPost from doGet

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);
}
}
}

Mockito test returning NullInsteadOfMockException

I am trying to test my servlet for login page but the Mock test is throwing an exception
LoginServlet
/**
* #see HttpServlet#HttpServlet()
*/
public LoginServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// TODO Auto-generated method stub
HttpSession session = request.getSession(true);
boolean result = false;
String username = request.getParameter("username");
String password = request.getParameter("password");
result = obj.validateLogin(username, password);
if (result) {
session.setAttribute("username", username);
response.sendRedirect("UserHome.jsp");
} else {
response.sendRedirect("login.jsp");
}
return;
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
MockTest : this is the test case I have written for login
public class LoginServletMockTest {
#Test
public void testServlet() throws Exception {
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
HttpSession session = request.getSession(true);
when(request.getParameter("username")).thenReturn("garwitauday");
when(request.getParameter("password")).thenReturn("123");
when(request.getSession()).thenReturn(session);
doNothing().when(session).setAttribute("username", "garwitauday");
doNothing().when(response).sendRedirect("Userhome.jsp");
LoginServlet loginservlet = new LoginServlet();
loginservlet.doPost(request, response);
verify(session).setAttribute("username", "garwitauday");
verify(response).sendRedirect("Userhome.jsp");
}
}
I am not able to resolve this issue
Create the mockito object for HttpSession also and set the mockito session object in request.
And continue your same do(..).when(..) or when(..).thenReturn(..) to mock the calls.
Make sure to set the attributes and parameters in request and session objects for easy testing.
If your's is mvc based servet, better to use MockMvc and it's builder objects.

java.lang.IllegalStateException: Cannot forward after response has been committed in servletfilter

I am using a filter to determine whether or not a requested page has a valid session or not.
This is my code. web.xml:
<filter>
<filter-name>SessionFilter</filter-name>
<filter-class>
com.imagemanagementutility.filter.SessionFilter
</filter-class>
<init-param>
<param-name>avoid-urls</param-name>
<param-value>index.jsp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Filter class:
public class SessionFilter implements Filter {
private ArrayList<String> urlList;
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String url = request.getServletPath();
boolean allowedRequest = false;
System.out.println(url.replace("/",""));
if (urlList.contains(url)) {
allowedRequest = true;
}
if (!allowedRequest) {
HttpSession session = request.getSession(false);
if (null == session) {
System.out.println("redirect in servlet session filter");
RequestDispatcher dispatcher = request
.getRequestDispatcher("//index.jsp");
dispatcher.forward(request, response);
}
}
chain.doFilter(req, res);
System.out.println("end");
}
public void init(FilterConfig config) throws ServletException {
String urls = config.getInitParameter("avoid-urls");
StringTokenizer token = new StringTokenizer(urls, ",");
urlList = new ArrayList<String>();
while (token.hasMoreTokens()) {
urlList.add(token.nextToken());
}
}
}
I have a login page which is used to check whether or not the user is valid.
If the user is valid then control is transfer to this servlet.
public class MainService extends HttpServlet {
private static final long serialVersionUID = 1L;
static Logger log = Logger.getLogger(MainService.class.getName());
/**
* #see HttpServlet#HttpServlet()
*/
public MainService() {
super();
}
/*
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession(true);
response.setContentType("text/html;charset=UTF-8");
LogUtil.logInfo("i m here");
List<Images> imageList = null;
response.setContentType("text/html");
try {
UserDataService userDataService = new UserDataImpl();
String userId = null;
String username = null;
String password = null;
username = request.getParameter("user");
password = request.getParameter("password");
userId = userDataService.checkUser(username, password);
if (userId!=null) {
System.out.println(userId);
session.setAttribute("userId", userId);
imageList = userDataService.getImages(userId);
session.setAttribute("imageList", imageList);
/*response.sendRedirect("//showUserImages.jsp");*/
RequestDispatcher dispatcher = request
.getRequestDispatcher("//showUserImages.jsp");
dispatcher.forward(request, response);
} else {
/*response.sendRedirect("//index.jsp");*/
RequestDispatcher dispatcher = request
.getRequestDispatcher("//index.jsp");
dispatcher.forward(request, response);
}
} catch (ImageException e) {
e.getMessage();
e.printStackTrace();
}
}
}
This works without the filter, but with the filter shows an error
when I forward control to "//showuserImages.jsp".
Put the invocation of doFilter in an else block:
if (!allowedRequest) {
HttpSession session = request.getSession(false);
if (null == session) {
System.out.println("redirect in servlet session filter");
RequestDispatcher dispatcher = request
.getRequestDispatcher("//index.jsp");
dispatcher.forward(request, response);
}
}else{
chain.doFilter(req, res);
}

Categories

Resources