Java servlet not redirecting properly - java

I have two pages jsp pages First one is AppLogin.jsp and other one is Login.jsp
I want that when i click on Submit button of AppLogin.jsp page, i want redirect to Login.jsp page with password value
and check this value on page load of Login.jsp page.
For this i did following code
but the below code did not work.
I don't want to use Session and append value on url.
AppLogin.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>App Login</title>
</head>
<body>
<form action="loginServlet" method="post">
<table>
<tr>
<td>Application Name</td>
<td><input type="text" value="" name="txtApplication" /></td>
</tr>
<tr>
<td>Username</td>
<td><input type="text" value="" name="txtUsername" /></td>
</tr>
<tr>
<td>Password</td>
<td><input type="text" value="" name="txtPassword" /></td>
</tr>
<tr align="center">
<td colspan="2"><input type="submit" value="Submit" /></td>
</tr>
</table>
</form>
</body>
</html>
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, ClientProtocolException {
try {
String password = req.getParameter("txtPassword");
req.setAttribute("crendential",password);
RequestDispatcher rd = req.getRequestDispatcher("Login.jsp");
rd.forward(req,res);
}
catch (Exception e) {
System.out.println("LoginServletException>>>>>>>>>>" + e);
}
}
}
Login.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Login</title>
</head>
<body>
<form action="saveServlet" method="post">
<table>
<tr>
<td>Application :</td>
<td><input type="text" value="" name="txtApplication" /></td>
</tr>
<tr>
<td>Username :</td>
<td><input type="text" value="" name="txtUsername" /></td>
</tr>
<tr>
<td>Password :</td>
<td><input type="text" value="" name="txtPassword" /></td>
</tr>
<tr align="center">
<td colspan="2"><input type="submit" value="Submit" /></td>
</tr>
</table>
</form>
</body>
</html>
public class SaveServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException {
try {
String crendential = (String) req.getAttribute("crendential");
System.out.println("crendential>>>>>>>>>>" + crendential);
}
catch (Exception e) {
System.out.println("LoginServletException>>>>>>>>>>" + e);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String crendential = (String) req.getAttribute("crendential");
System.out.println("crendential>>>>>>>>>>" + crendential);
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>xyz</display-name>
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>xyz.io.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/loginServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>save</servlet-name>
<servlet-class>xyz.io.SaveServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>save</servlet-name>
<url-pattern>/Login.jsp</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>AppLogin.jsp</welcome-file>
</welcome-file-list>
</web-app>
I am using Java with Eclipse Mars.

Login.jsp has a request attribute "credentials." To pass this value to the saveServlet there would be two possibilities:
Store the credentials instead as session attribute
Pass the credentials on in Login.jsp, say as hidden form input field.
<input type="hidden" name="credentials" value="${credentials}">
Correction:
I did miss the somewhat hard to digest web.xml with its servlet mappings.
In general how it often is done
A servlet mapping:
xyz.io.DisplayLoginServlet
/login
xyz.io.ProcessLoginServlet
/authorize
DisplayLoginServlet
doGet
prepares the form data (request attributes)
forwards to some displayLogin.jsp
doPost
validates the form, possibly redisplays the form with error messages (doGet)
otherwise when successfully done,
set session attributes
and redirect to the home page.
displayLogin.jsp
(posts to the same servlet)
And so on.
The mapped servlet URLs do not relate to JSPs.
The servlet is the entry point, the controller. It prepares the data model, puts them in the request attributes, and forwards to some JSP, the view. The servlet can on successfull login use an other JSP for instance.
Here we redirect after a successfull post. That is the brower is told to get the redirected page as answer. The effect is that the user cannot reload the page and effectively re-post the HTML form.
I think making a clean distinction will already help.

Related

How to save records and update the same page with recorded values in java

I'm trying to create a page that register new products and show the results list in same page.
This is my product.jsp page.
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
<script src="//code.jquery.com/jquery-1.10.2.js" type="text/javascript"></script>
</head>
<body>
<table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Description</th>
<th>Price</th>
</tr>
<div>
<c:forEach items="${products}" var="product">
<tr>
<td>${product.id}</td>
<td><c:out value="${product.name}" /></td>
<td><c:out value="${product.description}" /></td>
<td><c:out value="${product.price}" /></td>
</tr>
</c:forEach>
</div>
</table>
<br/><br/>
<form id="form1" action="${pageContext.request.contextPath}/" method="post">
<table>
<tr> <td>Product Name : <input type="text" name="pname" id="pname" /></td></tr>
<tr> <td>Product Description : <input type="text" name="pdesc" id="pdesc"/></td></tr>
<tr><td>Product Price : <input type="text" name="price" id="price"/></td></tr>
<tr><td> <input type="submit" value="save"/></td></tr>
</table>
<h4 style="color: red" id="result"><c:out value="${msg}"/></h4>
</form>
<script>
$(document).ready(function () {
$('#form1').submit(function () { .
$form = $(this);
$.post($form.attr('action'),
$form.serialize(),
function (responseText) {
$('#result').text(responseText);
$('#pname').val('');
$('#pdesc').val('');
$('#price').val('');
});
return false;
});
});
</script>
</body>
</html>
And here is my products.java servlet.
doGet() method usually calls when the page is loaded and it returns the registered item list.
doPost() method on the other hand save the records and returns the results back to the product.jsp page.
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
List<Product> products = productDAO.list();
request.setAttribute("products", products);
request.getRequestDispatcher("/products.jsp").forward(request, response);
} catch (SQLException e) {
throw new ServletException("Cannot obtain products from DB", e);
}
}
#Override
protected void doPost(HttpServletRequest requset, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");
try {
Product p = new Product();
p.setName(requset.getParameter("pname"));
p.setDescription(requset.getParameter("pdesc"));
p.setPrice(new BigDecimal(requset.getParameter("price")));
if (productDAO.Save(p) > 0) {
response.getWriter().write(String.valueOf("sucess"));
} else {
response.getWriter().write(String.valueOf("saved fail"));
}
} catch (Exception e) {
e.printStackTrace();
response.getWriter().write(String.valueOf(e));
}
Also this is my web.xml file that indicate products.java servlet file load in the startup of the application.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<servlet>
<servlet-name>products</servlet-name>
<servlet-class>com.shop.controller.products</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>products</servlet-name>
<url-pattern/>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/MyDatasource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
This web page is working finely, but the problem that I have is I want to update the given list after registration of the item.
Currently I only send a successful or error message only. I got an suggestion saying that I should use json. But to my knowledge it won't update the same given table.
Please help. Thank you.
Check out BalusC's answer here, it's a godsend. As you can see from it there are many different ways to handle your response data. Below i'll give you an example using your code.
For example, you could do something like this:
product.jsp
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
<script src="//code.jquery.com/jquery-1.10.2.js" type="text/javascript"></script>
</head>
<body>
<table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Description</th>
<th>Price</th>
</tr>
<div>
<c:forEach items="${products}" var="product">
<tr>
<td>${product.id}</td>
<td><c:out value="${product.name}" /></td>
<td><c:out value="${product.description}" /></td>
<td><c:out value="${product.price}" /></td>
</tr>
</c:forEach>
</div>
</table>
<br/><br/>
<form id="form1" action="YourProductsServlet" method="post">
<table>
<tr> <td>Product Name : <input type="text" name="pname" id="pname" /></td></tr>
<tr> <td>Product Description : <input type="text" name="pdesc" id="pdesc"/></td></tr>
<tr><td>Product Price : <input type="text" name="price" id="price"/></td></tr>
<tr><td> <input type="submit" value="save"/></td></tr>
</table>
<div style="color: red" id="result"></div>
</form>
<script>
//ajaxifying an existing form
$(document).on("submit", "#form1", function(event) {
var $form = $(this);
$.post($form.attr("action"), $form.serialize(), function(responseJson) {
// handle response data
var $table = $("<table>").appendTo($("#result")); // Create HTML <table> element and append it to HTML DOM element with ID "result".
$.each(responseJson, function(index, product) { // Iterate over the JSON array.
$("<tr>").appendTo($table) // Create HTML <tr> element, set its text content with currently iterated item and append it to the <table>.
.append($("<td>").text(product.id)) // Create HTML <td> element, set its text content with id of currently iterated product and append it to the <tr>.
.append($("<td>").text(product.name)) // Create HTML <td> element, set its text content with name of currently iterated product and append it to the <tr>.
.append($("<td>").text(product.price)); // Create HTML <td> element, set its text content with price of currently iterated product and append it to the <tr>.
});
});
event.preventDefault(); // Important! Prevents submitting the form.
});
</script>
</body>
</html>
products.java
Note: Servlets by convention start with a capital letter. Also in your
web.xml there is no url mapping set.. So as shown in the form above
i'm going to assume it's set as "YourProductsServlet"
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//in this case we are going to use this doGet method to handle your ajax response and when you initially load your data so we need to check if it's ajax or not, we can do that with this:
boolean ajax = "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
try {
List<Product> products = productDAO.list();
request.setAttribute("products", products);
if (ajax) {
//where the magic happens
//Returning List<Entity> as JSON
String json = new Gson().toJson(products);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(json);
}else{
//not an ajax request so process normally
request.getRequestDispatcher("/products.jsp").forward(request, response);
}
} catch (SQLException e) {
throw new ServletException("Cannot obtain products from DB", e);
}
}
#Override
protected void doPost(HttpServletRequest requset, HttpServletResponse response) throws ServletException, IOException {
//your form submits your new product to here, where you will save in your database
try {
Product p = new Product();
p.setName(requset.getParameter("pname"));
p.setDescription(requset.getParameter("pdesc"));
p.setPrice(new BigDecimal(requset.getParameter("price")));
productDAO.Save(p);
//if (productDAO.Save(p) > 0) {
//response.getWriter().write(String.valueOf("sucess"));
//} else {
//response.getWriter().write(String.valueOf("saved fail"));
//}
} catch (Exception e) {
e.printStackTrace();
//response.getWriter().write(String.valueOf(e));
}
doGet(request,response); //forward request and response to doGet method
}
Let me know if that works/helps or if you have questions.
Your code is indeed working correctly and as intended.
What you need to do, is to either trigger a reload of the page on the success callback (not very user-friendly) or update your table using JavaScript to modify the DOM of the page (how most modern systems work).
Such tasks are easier to accomplish using a JavaScript framework to dynamically render and keep the page updated based on changes in the server. There are very simple and easy-to-use libraries like Backbone.js, and more advanced ones like AngularJS and React.

I am having http status 404 while running my jsp which is linked to servlet

This is my jsp code:-
<%#page import="java.sql.*"%>
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<body>
<div id="header">
<center>
<div id="over">
<p> <font size="18" color="Brown"><b>UBONA Technologies</b></font></p>
</div>
</center>
</div>
<br><br><br><br><br><br>
<form method="get" action="controller.java">
<div class="container">
<center>
<table tableborder=0>
<tr><td><label><font size="5" color="BLACK"><b>USERNAME</b></font></label></td>
<br>
<td><input type="text" placeholder="Enter User Name" name="username" class="inputi" required></td>
</tr><br>
<tr><td><label><font size="5" color="BLACK"><b>PASSWORD</b></font></label></td>
<br>
<td><input type="password" placeholder="Enter Password" name="password" class="inputi" required></td>
</tr><br>
</table><br>
<input type="submit" class="button" name="submit" value="LOGIN" />
</center></div>
</form>
</body>
</html>
This is my Servlets code :-
import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.sql.*;
//#WebServlet("/controller")
public class controller extends HttpServlet
{
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
try
{
Class.forName("com.mysql.jdbc.Driver");
}
catch(Exception e)
{
}
try
{
String uname = request.getParameter("username");
String paswd = request.getParameter("password");
Connection con= null;
con=DriverManager.getConnection("jdbc:mysql://localhost:3306/database","root","6q190No6#");
Statement s = con.createStatement();
ResultSet rs=s.executeQuery("select * from credentials");
rs.next();
String username1 = rs.getString("username");
String password2 = rs.getString("password");
if(uname.equals(username1) && paswd.equals(password2))
{
response.sendRedirect("welcome.jsp");
}
else
{
response.sendRedirect("wrongpas.jsp");
}
rs.close();
}
catch(SQLException sqe)
{
System.out.println("home"+sqe);
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
}
}
this is my web.xml :-
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<servlet>
<servlet-name>controller</servlet-name>
<servlet-class>controller</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>controller</servlet-name>
<url-pattern>/controller</url-pattern>
</servlet-mapping>
</web-app>
I have changed the location of tomcat server as suggested in some videos.
As I saw some replies to the same question which were saying that save class to the root folder/ web-inf/classes i am unable to find that folder too.
If you don't have WEB-INF/classes create it manually and save your class there.
Put your needed jars into WEB-INF/lib/.
First modify your form tag to
<form id="login" action="${pageContext.request.contextPath}/controller" method="GET">
Add id attribute
<input type="text" placeholder="Enter User Name" name="username" id="username" class="inputi" required>
also in here
<input type="password" placeholder="Enter Password" name="password" id="username" class="inputi" required>
Second remove your comment on annotation
//#WebServlet("/controller")
Make it
#WebServlet(name = "controller", urlPatterns = {"/controller"})
Import annotations
import javax.servlet.annotation.WebServlet;
Remove doPost it does nothing in your case.
You don't need web.xml also.
Recommends
Your class name should start with capital letter.
urlPatterns should be different from your class name.
Following changes will resolve your issue:
In JSP code:
<form role="form" method="get" action="${pageContext.request.contextPath}/controller">
In Servlet code:
#WebServlet("/controller")
Adding above line of code will prompt you to import Webservlet annotations library:
import javax.servlet.annotation.WebServlet;
Also it is considered a good practice to begin Java class names with Uppercase
i.e controller.java should be Controller.java

Java set servlet request into jsp page

I have to load some values from servlet to jsp page
My "order_processing.jsp" JSP Page code is given below
<%#page import="test.abc.io.User_Objects"%>
<%# page import="java.util.Date" %>
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Order Processing</title>
</head>
<body>
<form name="OrderProcessing" action="order_processing" method="post" onsubmit="return validateForm();">
<table align="center">
<tr align="center">
<td colspan="2">
<img src="images/otn_logo.jpg"/>
</td>
</tr>
<tr>
<td>First Name :</td>
<td><input type="text" id="txtFirstname" name="txtFirstname" value="${reqObj.firstname}" /></td>
</tr>
<tr>
<td>Last Name :</td>
<td><input type="text" id="txtLastname" name="txtLastname" value="${reqObj.lastname}" /></td>
</tr>
<tr>
<td>Communication Email :</td>
<td><input type="text" id="txtCommunicationEmail" name="txtCommunicationEmail" value="${reqObj.commEmail}" />
<label style="color: red;">*</label></td>
</tr>
<tr align="left">
<td colspan="2"><input type="submit" value="Submit" /></td>
</tr>
</table>
</form>
</body>
</html>
My User_Objects code
public class User_Objects {
public String firstname;
public String lastname;
public String commEmail;
}
My "OrderProcessing" code
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class OrderProcessing extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
User_Objects fillObj = new User_Objects();
fillObj.firstname = "Test";
fillObj.lastname = "User1";
fillObj.commEmail = "tuser01#xyz.com";
request.setAttribute("reqObj", fillObj);
RequestDispatcher view = request.getRequestDispatcher("/order_processing.jsp");
view.forward(request, response);
} catch (Exception e) {
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("into OrderProcessing java");
}
}
My web.xml code
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>OrderProcessing</display-name>
<welcome-file-list>
<welcome-file>order_processing.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>order_processing</servlet-name>
<servlet-class>test.abc.io.OrderProcessing</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>order_processing</servlet-name>
<url-pattern>/order_processing</url-pattern>
</servlet-mapping>
</web-app>
When i debug this project and click on Submit button its gives the following error:
SEVERE: Servlet.service() for servlet jsp threw exception
javax.el.PropertyNotFoundException: Property 'firstname' not found on type test.abc.io.User_Objects
and I also want to do some task on "order_processing.jsp" page load.
but when i run this project, my order_processing.jsp page display successfully but on that case my doGet method of OrderProcessing.java did not call.
I am using JAVA with Eclipse Mars.
The object "User_Objects" is no java bean:
firstname, lastName and commEMail are fields and not properties.
Try to add a getter / setter for firstName, lastName and commEMail

Spring MVC second Post method #ModelAttribute is null

I have a form that has two buttons, a submit button and an update button.
Here is the JSP:
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<!-- Bootstrap core CSS !-->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<!-- Custom scripts/styles for this page !-->
<script type="text/javascript" src="${pageContext.request.contextPath}/static/script/jquery.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/static/script/script.js"></script>
<link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath}/static/css/style.css" />
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Test</title>
</head>
<body>
<!-- General Information Form -->
<form:form id="form" method="POST" action="${pageContext.request.contextPath}/create" modelAttribute="task">
<div id="general">
<table style="width: 224px;">
<tr>
<td colspan="2"><form:select id="systemType" path="systemType" items="${systemTypes}" /></td>
</tr>
<tr>
<td id="buffer"></td>
</tr>
<tr>
<td colspan="2"><form:select id="userName" path="user.fullName" items="${userFullNames}" /></td>
</tr>
<tr>
<td id="buffer"></td>
</tr>
<tr>
<td style="width: 50%;"><label for=line><b>Line: </b></label></td>
<td><form:select path="location.line" items="${lines}" id="line"/></td>
</tr>
<tr>
<td id="buffer"></td>
</tr>
<tr>
<td style="width: 50%;"><label for=position><b>Position: </b></label></td>
<td><form:select path="location.position" items="${positions}" id="position" /></td>
</tr>
<tr>
<td id="buffer"></td>
</tr>
<tr>
<td colspan="2">
<input id="submitButton" type="submit" name="submit" value=Submit />
<input style="display:none;" id="updateButton" type="submit" name="update" value="Update" />
<input id="cancel" style="float: right;" type="Reset" value="Cancel" />
</td>
</tr>
</table>
</div>
</form:form>
</body>
</html>
Here is my controller:
#Controller
#RequestMapping("/")
public class HomeController {
private TaskService taskService;
#Autowired
public void setTaskService(TaskService taskService) {
this.taskService = taskService;
}
#RequestMapping(value = "/", method = RequestMethod.GET)
public String initForm(Model model, HttpServletRequest request) {
Task task = new Task();
model.addAttribute("task", task);
return "home";
}
#RequestMapping(value="/create", params="submit", method = RequestMethod.POST)
public String submitForm(#ModelAttribute("task")Task task,BindingResult result, Model model) {
taskService.create(task);
return "redirect:/";
}
#RequestMapping(value="/create", params="update", method = RequestMethod.POST)
public String updateForm(#ModelAttribute("task")Task task, BindingResult result, Model model) {
System.out.println("Updating: " + task.toString());
taskService.update(task);
return "redirect:/";
}
The idea being that hitting the submit button will make a new item, and the update button will edit an existing one. The two .POST methods have different parameters specified to distinguish them.
The submit button is working as expected. However when the update button is pressed a Task object is delivered to the updateForm controller method - but all of its fields are null.
I am not sure why the form is binding the fields to the Task correctly on the submit method, but seemingly creating a new Task and not binding it at all in the update method.
I am inclined to just combine these methods into a single controller method and use some Java logic to determine whether to submit/update based on the parameter - but am curious as to what I'm missing and why this doesn't work.
Ok, I feel very stupid. This was not a SpringMVC issue at all. The problem was caused by a Jquery method that was disabling a part of the form. This gave the appearance that the form was not binding, but actually it was just binding to null values.

Custom AuthenticationProvider cannot read extra field from login

In a Spring MVC app using Spring Security, I have a custom login view that asks for three fields (username, password, and pin). I also have a custom AuthenticationProvider, but somehow the custom AuthenticationProvider is not able to read in the pin code that the user submitted, and is thus not able to provide custom authentication. What do I need to change or add in order for the custom AuthenticationProvider to be able to access and use the pin code entered by the user?
Here is CustomAuthenticationProvider.java:
public class CustomAuthenticationProvider implements AuthenticationProvider{
#Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String name = authentication.getName();
String password = authentication.getCredentials().toString();
String details = authentication.getDetails().toString();
System.out.println("----------- Inside Custom Authentication Provider -----------");
System.out.println("name is: "+name);
System.out.println("password is: "+password);
System.out.println("details is: "+details);
List<GrantedAuthority> grantedAuths = new ArrayList<>();
if (name.equals("admin") && password.equals("system")) {
grantedAuths.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
}
if(pincodeEntered(name)){
grantedAuths.add(new SimpleGrantedAuthority("registered"));
}
Authentication auth = new UsernamePasswordAuthenticationToken(name, password, grantedAuths);
return auth;
}
#Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
private boolean pincodeEntered(String userName){
// Lookup can be added here when the pincode becomes available
return true;
}
}
Note: The SYSO from the CustomAuthenticationProvider prints the username and password (along with details of ip address and sessionId) when the user tries to authenticate, but the pin code is not printed out.
Here is the login.jsp:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Custom Login page</title>
<style>.error {color: red;}</style>
</head>
<body>
<div class="container">
<h1>Custom Login page</h1>
<p>
<c:if test="${error == true}">
<b class="error">Invalid login or password.</b>
</c:if>
</p>
<form method="post" action="<c:url value='j_spring_security_check'/>" >
<table>
<tbody>
<tr>
<td>Login:</td>
<td><input type="text" name="j_username" id="j_username"size="30" maxlength="40" /></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="password" name="j_password" id="j_password" size="30" maxlength="32" /></td>
</tr>
<tr>
<td>Pin:</td>
<td><input type="text" name="pin" id="pin"size="30" maxlength="40" /></td>
</tr>
<tr>
<td colspan=2>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="Login" /></td>
</tr>
</tbody>
</table>
</form>
</div>
</body>
</html>

Categories

Resources