Browsed the forum but didn't find solution which can solve my problem. There are 2 pages: index.jsp - start page which includes form to be populated and the list of results; edit.jsp - allows to edit data of any row from the list of results provided by index.jsp.
When I fill in the form all the data subbmitted successfully, when I try to edit any row in the list of results I redirected to edit.jsp but if I submit the changes an exception is thrown: HTTP Status 405 - Request method 'POST' not supported. I would appreciate any idea how to treat the issue.
index.jsp
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<%#taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%#taglib prefix="s" uri="http://www.springframework.org/tags" %>
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title></title>
</head>
<body>
<form:form method="post" action="add" modelAttribute="account">
<table>
<tr>
<td><form:label path="number">Number</form:label></td>
<td><form:input path="number"/></td>
</tr>
<tr>
<td><form:label path="amount">Amount</form:label></td>
<td><form:input path="amount"/></td>
</tr>
<tr>
<td><form:label path="currency">Currency</form:label></td>
<td><form:input path="currency"/></td>
</tr>
<tr>
<td><form:label path="date">Date</form:label></td>
<td><form:input path="date" type="date"/>
</tr>
</table>
<input type="submit" value="Submit"/>
</form:form>
<table>
<tr border="1">
<td>Number</td>
<td>Amount</td>
<td>Currency</td>
<td>Date</td>
</tr>
<c:forEach items="${listOfAccounts}" var="items">
<tr border="1">
<td>${items.number}</td>
<td>${items.amount}</td>
<td>${items.currency}</td>
<td>${items.date}</td>
<td>edit</td>
</tr>
</c:forEach>
</body>
</html>
edit.jsp
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Edit Account</title>
</head>
<body>
<form:form modelAttribute="account" method="post" action="edited">
<form:hidden path="id" value="${account.id}"></form:hidden>
<form:label path="number">Number</form:label>
<form:input path="number" value="${account.number}"/><br>
<form:label path="amount">Amount</form:label>
<form:input path="amount" value="${account.amount}"/><br>
<form:label path="currency">Currency</form:label>
<form:input path="currency" value="${account.currency}"/><br>
<form:label path="date">Date</form:label>
<form:input path="date" type="date" value="${account.date}"/>
<input type="submit" value="Submit"/>
</form:form>
</body>
</html>
Controller.java
#Controller
public class AccountController {
#Autowired
private AccountService accountService;
private Account account;
#RequestMapping(value="/", method = RequestMethod.GET)
public String welcomeMethod(ModelMap map) {
Account account = new Account();
map.addAttribute("account", account);
map.addAttribute("listOfAccounts", accountService.getListOfAccounts());
return "index";
}
#RequestMapping(value="add", method = RequestMethod.POST)
public String addAccount(#ModelAttribute(value="account") Account account, ModelMap map) {
accountService.addAccount(account);
map.addAttribute("listOfAccounts", accountService.getListOfAccounts());
return "index";
}
#RequestMapping(value="edit/{id}", method = RequestMethod.GET)
public String editAccount(#PathVariable("id") int id, ModelMap model) {
Account account = accountService.getAccountById(id);
model.addAttribute("account", account);
return "edit";
}
#RequestMapping(value="edited", method = RequestMethod.POST)
public String updateAccount(#ModelAttribute(value="account") Account account, ModelMap map) {
accountService.updateAccount(account);
map.addAttribute("listOfAccounts", accountService.getListOfAccounts());
return "index";
}
}
Your problem is that you are using relative mappings in your form, when you click on edit, your URL becomes /edit/{someid} and your edit.jsp form is loaded. When you edit the data and click submit, your URL will become /edit/{someid}/edited, the mapping will match the /edit/{someid} handler method witch is using a GET method and that is why you get your error.
To solve it, in your edit.jsp simple add a backslash to action, action="/edited"
Hope it helps
Related
How it would be better to get value from dropdown list in JSP in such case? Now 400 status error appears after pressing Submit button. I tried to search for the solution in Google, but there was no any variant which would helped me.
There are some fragments of code, which belongs to this issue.
First class:
public class Item1 {
private int id;
private Item2 item2;
//getters, setters
}
Second class:
public class Item2 {
private int id;
private String description;
//getters, setters
}
First class controller:
#Controller
public class Item1Controller {
#Autowired
private Item1DAO item1DAO;
#RequestMapping(value = "/saveItem1", method = RequestMethod.POST)
public ModelAndView saveItem1 (#ModelAttribute Item1 item1) {
item1DAO.addOrUpdateCourse(item1);
return new ModelAndView("redirect:/item1List");
}
}
JSP Form:
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%# page contentType="text/html;charset=UTF-8" language="java" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%#page isELIgnored="false" %>
<html>
<head>
<title>Add New Item1</title>
</head>
<body>
<form:form method="POST" action="/saveItem1" modelAttribute="item1">
<table>
<form:hidden path="id"/>
<tr>
<td><form:label path="Item2">Item2</form:label></td>
<td>
<form:select path="item2">
<form:option value="null">No Item2</form:option>
<form:options items="${item2List}"/>
</form:select>
</td>
</tr>
<tr>
<td>
<input type="submit" value="Save Item1"/>
</td>
</tr>
</table>
</form:form>
</body>
</html>
You should put "get" and "set" methods (public) into the Item classes. A public constructor would be a good thing.
I would try to write the same path attribute value: description
You have multiple mistakes in the form paths. Each must reference a simple field, not a complex object.
For example, you need:
<form:input path="item2.description"/> <!-- not path="description", no description in the Item1 model -->
<form:label path="item2.id"> <!-- not "Item2" by itself, and wrong case -->
<form:select path="item2.id"> <!-- not "item2" by itself -->
I have an application where in a JSP page i am displaying a drop down list but i am getting an exception in my code.
public class ExpenseCreationBean {
private String color;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
Controller Class:-
#RequestMapping(value = "/addDetails", method = RequestMethod.GET)
public String getExpenseEntryPage(Model model) {
ExpenseCreationBean expenseCreationBean = new ExpenseCreationBean();
model.addAttribute("expenseCreationBean", expenseCreationBean);
List<String> coloursList = new ArrayList<String>();
coloursList.add("red");
coloursList.add("green");
coloursList.add("yellow");
coloursList.add("pink");
coloursList.add("blue");
model.addAttribute("colours", coloursList);
System.out.println("I was here!!");
return "addDetails";
}
addDetails.jsp Page
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<html>
<head>
<title>Add Details</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$(function() {
$("#datepicker").datepicker({
showOn : "button",
buttonImage : "images/calendar.png",
buttonImageOnly : true,
buttonText : "Select date"
});
});
</script>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
</head>
<body>
<h1>Expense Entry Details</h1>
<form:form method="post" action="savedata" modelAttribute="expenseCreationBean">
<table border="6px" cellspacing="10px" cellpadding="10px">
<tr>
<td>Date Of Purchase: <input type="text" id="datepicker"
name="date_of_purchase"></td>
<td>Item Name:<input type="text" name="description"></td>
<td>Please select:</td>
<td><form:select path="color">
<form:option value="" label="...." />
<form:options items="${colours}" />
</form:select>
</td>
<td>Paid By: <select name="paid_by"></td>
<td>Amount Paid:<input type="text" name="total_price"
id="total_price"></td>
<td>Quantity:<input type="text" name="quantity_purchased"></td>
<td>Unit:<input type="text" name="unit"></td>
</tr>
<tr>
<tr>
<tr>
<tr>
<td>Exclude:</td>
<td><input TYPE="checkbox" name="exclude">
</tr>
<tr>
<td>Comments:<textarea rows="3" cols="25" name="comments"></textarea>
</td>
</tr>
<tr>
<td><input type="submit" value="Save" align="middle"></td>
</table>
</form:form>
</body>
</html>
I am getting the below exception :-
javax.servlet.jsp.JspException: Type [java.lang.String] is not valid for option items
org.springframework.web.servlet.tags.form.OptionWriter.writeOptions(OptionWriter.java:143)
org.springframework.web.servlet.tags.form.OptionsTag.writeTagContent(OptionsTag.java:157)
org.springframework.web.servlet.tags.form.AbstractFormTag.doStartTagInternal(AbstractFormTag.java:84)
It is just a Spring MVC Web application where i am trying to display the drow down list pre-populated with the colors data.
Any help is highly appreciated.
I added the below line on teh top of addDetails.jsp file and it worked:-
Try to add into Map, instead of ArrayList.
Map<String,String> coloursList = new HashMap<String,String>();
coloursList.put("R","red");
coloursList.put("R","green");
coloursList.put("Y","yellow");
coloursList.put("P","pink");
I have searched this forum and net for this, found many example but still i am not able to populate the select box in jsp.
I have written a jsp servlet, where servlet returns an arraylist and in jsp uhsing jstl i am trying to create a select box and populating option with arraylist values.
Following is my code.
Servlet Code:
#SuppressWarnings("unchecked")
public void doGet(HttpServletRequest request, HttpServletResponse response) {
UserService userService = new UserServiceImpl();
try {
String[] questions = userService.getQNA().getQuestions();
List<String> ques = new ArrayList<String>();
ques = Arrays.asList(questions);
request.setAttribute("questionDTO", ques);
response.sendRedirect("forms/enrollMigrationUser.jsp");
} catch (IOException e) {
log.error("request failed "+ e.getMessage());
}
}
JSP code :
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!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>Enroll Migration Users</title>
</head>
<body>
<form method="post" action="/nycb/enrolluser" name="enrollForm">
<table>
<tr>
<td>User setup</td>
<td></td>
</tr>
<tr>
<td>UserId :</td>
<td><input type="text" name="userName" id="userName"/></td>
</tr>
<tr>
<td>Password :</td>
<td><input type="password" name="password" id="password"/></td>
</tr>
<tr>
<td><input type="checkbox" name="computerType" value="public">Authorize this computer</td>
<td></td>
</tr>
<tr>
<td>
<select name='role'>
<c:forEach items="<%=request.getAttribute(\"questionDTO\") %>" var="question">
<option value="<c:out value="${question}"/>"><c:out value="${question}"/></option>
</c:forEach>
</select>
</td>
<td><input type="text" name="qna6" id="qna6"/></td>
</tr>
<tr>
<td>
<select name='role'>
<c:forEach items="${questionDTO}" var="question">
<option value="<c:out value="${question}"/>"><c:out value="${question}"/></option>
</c:forEach>
</select>
</td>
<td><input type="text" name="qna6" id="qna6"/></td>
</tr>
</table>
<input type="submit" value="click" name="dropdown" id="dropdown">
</form>
I am not able to populate the select box, the option field is empty.
Can anyone please let me know where i am going wrong?
sendRedirect() creates a new request and any attribute set in request will not be available in redirected JSP page.
Try any one
You can use RequestDispatcher#forward or RequestDispatcher#include in this case.
You can save it in session as attribute.
Sample code:
RequestDispatcher view = request.getRequestDispatcher("forms/enrollMigrationUser.jsp");
view.forward(request, response);
OR
HttpSession session = request.getSession();
session.setAttribute("questionDTO", ques);
response.sendRedirect("forms/enrollMigrationUser.jsp");
Always try to avoid Scriplet elements instead use JSTL & EL.
You can do in this to read an attribute from any scope in order page, request, session and finally applicaion
<c:forEach items="${questionDTO}" var="question">
OR read from specific scope.
<c:forEach items="${requestScope.questionDTO}" var="question">
I'm new to Spring MVC. I am writing a small app to learn. I am working on some basic CRUD. I am writing the same code more than once to edit/display a domain class. What would be a better/proper way to implement the edit and save method?
Thanks
The controller:
#RequestMapping(value="/userInfo/create/{id}")
public ModelAndView edit(#PathVariable Integer id, Model model)
{
logger.info("UserInfo edit {}", id);
UserInfo userInfo = userInfoService.get(id);
model.addAttribute("userInfo", userInfo);
model.addAttribute("parent" , userInfoService.get(userInfo.getParentId()));
model.addAttribute("allUsers", userInfoService.list());
model.addAttribute("affInfos", affInfoService.findAllByUserInfo(userInfo));
ModelAndView mv = new ModelAndView("userInfo/create", "command", model);
return mv;
}
#RequestMapping(value="/userInfo/save", method=RequestMethod.POST)
public ModelAndView save(#Valid #ModelAttribute("userInfo")UserInfo userInfo, BindingResult result, Model model)
{
logger.info("UserInfo save");
model.addAttribute("userInfo", userInfo);
model.addAttribute("parent" , userInfoService.get(userInfo.getParentId()));
model.addAttribute("allUsers", userInfoService.list());
model.addAttribute("affInfos", affInfoService.findAllByUserInfo(userInfo));
ModelAndView mv = new ModelAndView("userInfo/create", "command", model);
if(!result.hasErrors())
{
userInfoService.saveOrUpdate(userInfo);
model.addAttribute("flashMsg", "UserInfo saved!");
}
else
{
model.addAttribute("flashMsg", "Could not save.");
}
return mv;
}
The View:
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%#taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
<title>Create/Edit UserInfo</title>
</head>
<body>
<div style="margin-left:100px;font-weight: bold;font-size:16px;margin-bottom:20px;margin-top: 10px;">User Information</div>
<c:if test="${flashMsg != null}">
<div>${flashMsg }</div>
</c:if>
<form:form modelAttribute="userInfo" action="${pageContext.request.contextPath}/userInfo/save" method="post" >
<form:hidden path="id"/>
<div style="width:200px;margin-left:100px;margin-bottom:10px;">
<div style="margin-bottom:4px;font-weight: bold;">Name</div>
<div><form:input path="name"/></div>
</div>
<div style="width:200px;margin-left:100px;margin-bottom:10px;">
<div style="margin-bottom:4px;font-weight: bold;">Parent</div>
<div>
<form:select path="parentId" itemLabel="name" itemValue="id" >
<form:option value="-1">Choose Parent</form:option>
<form:options items="${allUsers}" itemLabel="name" itemValue="id"/>
</form:select>
</div>
</div>
<c:if test="${affInfos != null }">
<div>
<table style="width:600px;border:1px solid #ccc;" class="center ui-corner-all shadow zebra-striped">
<thead>
<tr>
<th>Macro</th>
<th>AffID</th>
<th><button type="button" class="btn shadow">New</button></th>
</tr>
</thead>
<tbody>
<c:forEach var="affInfo" varStatus="i" items="${affInfos }">
<tr>
<td><input type="text" name="macro_${affInfo.id}" id="macro_${affInfo.id}" value="${affInfo.macro}"></td>
<td><input type="text" name="affid_${affInfo.id}" id="affid_${affInfo.id}" value="${affInfo.affid}"></td>
<td><button class="btn shadow" type="button">Delete</button></td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</c:if>
<div style="margin-left:100px;margin-top:10px;" >
<form:button class="btn shadow">Submit</form:button>
</div>
</form:form>
</body>
</html>
First you could of course create a method like this one :
private method init(){
model.addAttribute("userInfo", userInfo);
model.addAttribute("parent" , userInfoService.get(userInfo.getParentId()));
model.addAttribute("allUsers", userInfoService.list());
model.addAttribute("affInfos", affInfoService.findAllByUserInfo(userInfo));
}
But, if your controller is used for only one JSP page (JSPX is the recommend page type), you can use something like that for each attribute on your JSP Page :
#ModelAttribute("allUsers")
public List<User> populateUserInfoList() {
return userInfoService.list();
}
It will automatically add to the ModelAndView the attribute wich name is in the #ModelAttribute annotation. But be careful , this will be called each time you use your controller, wich could create useless called to the database if your controller do more than calling always the same kind of JSP which need the same data.
With this you don't need anymore this line :
model.addAttribute("allUsers", userInfoService.list());
Hope it helps you
Getting error:
java.lang.IllegalStateException: getAttributeNames: Session already invalidated.After logout from parent window.
LogOutUserAction.java
public String execute() throws Exception {
System.out.println("inside :: LogOutUserAction------");
//HttpServletRequest request = null;
HttpServletRequest request = ServletActionContext.getRequest();
HttpSession session =request.getSession(true);
session.removeAttribute("loggedInUser");
request.getSession(false).invalidate();
session=null;
return "logout";
}
LoginInterceptor
public String intercept(ActionInvocation invocation) throws Exception {
final ActionContext context = invocation.getInvocationContext();
HttpServletRequest request = (HttpServletRequest) context
.get(HTTP_REQUEST);
HttpServletResponse response = (HttpServletResponse) context
.get(HTTP_RESPONSE);
HttpSession session = request.getSession(true);
response.setHeader("Cache-Control", "no-store");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
/*user logged out from the parent window then set the message
for click on the popup window*/
if(session == null){
System.out.println("set the attribute");
request.setAttribute("SessionExpired","Your have already logged out");
}
Object user = session.getAttribute(USER_HANDLE);
String loginOut = request.getParameter(LOGIN_OUT);
System.out.println("loginOut---->"+loginOut);
if (user == null) {
// The user has not logged in yet.
System.out.println(" inside if ");
// Is the user attempting to log in right now?
String loginAttempt = request.getParameter(LOGIN_ATTEMPT);
/* The user is attempting to log in. */
if (!StringUtils.isBlank(loginAttempt)) {
return invocation.invoke();
}
return "login";
} else {
return invocation.invoke();
}
}
login.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="s" uri="/struts-tags"%>
<%# taglib prefix="sx" uri="/struts-dojo-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%
if (request.getAttribute("SessionExpired")!= null)
{
System.out.println("After Session invalid");
}
%>
<html>
<head>
<title>Login</title>
<sx:head cache="true"/>
<script type="text/javascript">
</script>
<script type="text/javascript" language="javascript" src="js/login.js"></script>
<style type="text/css">
.style1 {font-family: Verdana, Arial, Helvetica, sans-serif}
.style2 {
color: #000099
}
</style>
</head>
<body bgcolor="#CODFFD" background="<%request.getContextPath();%>images/watermark_new.jpg">
<br>
<br>
<br>
<br>
<br>
<br>
<div align="center"><span class="style1">USER LOGIN</span>
<br>
<br>
<br>
<s:form action="checkUserLogin.action" validate="true" name = "loginForm">
<s:hidden name="loginAttempt" value="%{'1'}" />
<table border="0" cellspacing="1" cellpadding="0" width="350" >
<tr>
<td align="center">
<b>Login ID</b>
</td>
<td>
<table>
<s:textfield id="id" name="loginId" value="" />
</table>
</td>
</tr>
<tr>
<td align="center">
<b>Password</b>
</td>
<td>
<table>
<s:password id="password" name="loginPassword" value="" showPassword="true"/>
</table>
</td>
</tr>
<tr><td colspan="2" align="center">
<table>
<s:submit value="Login" onclick = "return getRoleList()"/>
</table>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<table>
<s:a href="changePasswordScreen.action" >Change Password</s:a>
</table>
</td>
</tr>
</table>
</s:form>
</div>
<br>
<br>
<br>
</body>
</html>
Need to display message on popup window (when i click on any link) as i mentioned on my login jsp after logout from parent window.
Interceptors can execute code before and after an Action is invoked. When is yours being invoked? I would imagine what's happening is this:
In LogOutUserAction.java you invalidate the session
LoginInterceptor.intercept is then executed. This tries to get an attribute from the session object that you invalidated hence the IllegalStateException.
Why are you invalidating the session? Your LoginInterceptor is using the presence of the USER_HANDLE attribute to indicate whether or not the user is logged in. I would remove this attribute in your LogOutUserAction but don't invalidate the session.