Add constraint check on save/update
This commit is contained in:
parent
6d977fc447
commit
cfeb8d56ab
13 changed files with 184 additions and 75 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -14,7 +14,7 @@
|
||||||
<body>
|
<body>
|
||||||
<%@include file="header.jsp" %>
|
<%@include file="header.jsp" %>
|
||||||
|
|
||||||
<h1>${confirm} </h1>
|
<h1>${error != null ? error : confirm} </h1>
|
||||||
<form action="list.htm" method="POST">
|
<form action="list.htm" method="POST">
|
||||||
<input hidden type="text" name="type" value="${type}" />
|
<input hidden type="text" name="type" value="${type}" />
|
||||||
<input type="submit" value="Afficher tous les enregistrements" />
|
<input type="submit" value="Afficher tous les enregistrements" />
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
<label for="discountCode">Remise</label>
|
<label for="discountCode">Remise</label>
|
||||||
<select name="discountCode" id="discountCode">
|
<select name="discountCode" id="discountCode">
|
||||||
<c:forEach items="${code}" var="dc">
|
<c:forEach items="${code}" var="dc">
|
||||||
<option <c:if test="${dc.discountCode==result.discountCode}"> selected </c:if> value="${dc.discountCode}}">${dc.discountCode} - ${dc.rate}%</option>
|
<option <c:if test="${dc.discountCode==result.discountCode}"> selected </c:if> value="${dc.discountCode}">${dc.discountCode} - ${dc.rate}%</option>
|
||||||
</c:forEach>
|
</c:forEach>
|
||||||
</select>
|
</select>
|
||||||
</p>
|
</p>
|
||||||
|
@ -175,7 +175,7 @@
|
||||||
<label for="discountCode">Remise</label>
|
<label for="discountCode">Remise</label>
|
||||||
<select name="discountCode" id="discountCode">
|
<select name="discountCode" id="discountCode">
|
||||||
<c:forEach items="${code}" var="dc">
|
<c:forEach items="${code}" var="dc">
|
||||||
<option <c:if test="${dc.discountCode==result.discountCode}"> selected </c:if> value="${dc.discountCode}}">${dc.discountCode} - ${dc.rate}%</option>
|
<option <c:if test="${dc.discountCode==result.discountCode}"> selected </c:if> value="${dc.discountCode}">${dc.discountCode} - ${dc.rate}%</option>
|
||||||
</c:forEach>
|
</c:forEach>
|
||||||
</select>
|
</select>
|
||||||
</p>
|
</p>
|
||||||
|
@ -189,7 +189,7 @@
|
||||||
<input hidden type="text" name="type" value="${type}" />
|
<input hidden type="text" name="type" value="${type}" />
|
||||||
<c:choose>
|
<c:choose>
|
||||||
<c:when test="${save != null}">
|
<c:when test="${save != null}">
|
||||||
<input type="submit" value="Add" formaction="add.htm" />
|
<input type="submit" value="Add" formaction="save.htm" />
|
||||||
</c:when>
|
</c:when>
|
||||||
<c:otherwise>
|
<c:otherwise>
|
||||||
<input type="submit" value="Edit" formaction="update.htm" />
|
<input type="submit" value="Edit" formaction="update.htm" />
|
||||||
|
@ -199,8 +199,6 @@
|
||||||
</c:if>
|
</c:if>
|
||||||
</c:otherwise>
|
</c:otherwise>
|
||||||
</c:choose>
|
</c:choose>
|
||||||
|
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
<h1>${error}</h1>
|
<h1>${error}</h1>
|
||||||
</c:when>
|
</c:when>
|
||||||
<c:otherwise>
|
<c:otherwise>
|
||||||
<form name="Add" action="detail.htm" method="POST">
|
<form name="Add" action="formAdd.htm" method="POST">
|
||||||
<input hidden type="text" name="type" value="${type}"/>
|
<input hidden type="text" name="type" value="${type}"/>
|
||||||
<input type=submit value="Add" />
|
<input type=submit value="Add" />
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<body>
|
<body>
|
||||||
<%@include file="header.jsp" %>
|
<%@include file="header.jsp" %>
|
||||||
|
|
||||||
<h1>${confirm} </h1>
|
<h1>${error != null ? error : confirm} </h1>
|
||||||
<form action="list.htm" method="POST">
|
<form action="list.htm" method="POST">
|
||||||
<input hidden type="text" name="type" value="${type}" />
|
<input hidden type="text" name="type" value="${type}" />
|
||||||
<input type="submit" value="Afficher tous les enregistrements" />
|
<input type="submit" value="Afficher tous les enregistrements" />
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
<label for="discountCode">Remise</label>
|
<label for="discountCode">Remise</label>
|
||||||
<select name="discountCode" id="discountCode">
|
<select name="discountCode" id="discountCode">
|
||||||
<c:forEach items="${code}" var="dc">
|
<c:forEach items="${code}" var="dc">
|
||||||
<option <c:if test="${dc.discountCode==result.discountCode}"> selected </c:if> value="${dc.discountCode}}">${dc.discountCode} - ${dc.rate}%</option>
|
<option <c:if test="${dc.discountCode==result.discountCode}"> selected </c:if> value="${dc.discountCode}">${dc.discountCode} - ${dc.rate}%</option>
|
||||||
</c:forEach>
|
</c:forEach>
|
||||||
</select>
|
</select>
|
||||||
</p>
|
</p>
|
||||||
|
@ -175,7 +175,7 @@
|
||||||
<label for="discountCode">Remise</label>
|
<label for="discountCode">Remise</label>
|
||||||
<select name="discountCode" id="discountCode">
|
<select name="discountCode" id="discountCode">
|
||||||
<c:forEach items="${code}" var="dc">
|
<c:forEach items="${code}" var="dc">
|
||||||
<option <c:if test="${dc.discountCode==result.discountCode}"> selected </c:if> value="${dc.discountCode}}">${dc.discountCode} - ${dc.rate}%</option>
|
<option <c:if test="${dc.discountCode==result.discountCode}"> selected </c:if> value="${dc.discountCode}">${dc.discountCode} - ${dc.rate}%</option>
|
||||||
</c:forEach>
|
</c:forEach>
|
||||||
</select>
|
</select>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -8,6 +8,7 @@ import org.hibernate.*;
|
||||||
import org.hibernate.cfg.Configuration;
|
import org.hibernate.cfg.Configuration;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
|
import org.hibernate.exception.ConstraintViolationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -393,8 +394,7 @@ public void add (Object data) {
|
||||||
tx=session.beginTransaction();
|
tx=session.beginTransaction();
|
||||||
session.save(data);
|
session.save(data);
|
||||||
tx.commit();
|
tx.commit();
|
||||||
}
|
} catch (Exception e) {
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
tx.rollback();
|
tx.rollback();
|
||||||
throw e;
|
throw e;
|
||||||
|
|
16
src/java/Exceptions/InvalidParameter.java
Normal file
16
src/java/Exceptions/InvalidParameter.java
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package Exceptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author flifloo
|
||||||
|
*/
|
||||||
|
public class InvalidParameter extends Exception {
|
||||||
|
public InvalidParameter(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
package controller;
|
package controller;
|
||||||
import DAO.*;
|
import DAO.*;
|
||||||
|
import Exceptions.InvalidParameter;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import service.User;
|
import service.User;
|
||||||
|
@ -17,6 +18,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||||
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
|
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
|
||||||
import javax.servlet.http.*;
|
import javax.servlet.http.*;
|
||||||
import javax.servlet.*;
|
import javax.servlet.*;
|
||||||
|
import org.hibernate.exception.ConstraintViolationException;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -252,65 +254,147 @@ public class BddController extends MultiActionController {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private char paramChar(HttpServletRequest request, String name) throws InvalidParameter {
|
||||||
|
String param = paramNotNull(request, name);
|
||||||
|
if (param.length() > 1)
|
||||||
|
throw new InvalidParameter("Invalid ".concat(name));
|
||||||
|
return param.charAt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int parseParamInt(HttpServletRequest request, String name) throws InvalidParameter {
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(request.getParameter(name));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new InvalidParameter("Invalid numer for ".concat(name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int parseParamInt(String param, String name) throws InvalidParameter {
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(param);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new InvalidParameter("Invalid numer for ".concat(name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BigDecimal parseParamBigDecimal(HttpServletRequest request, String name, int precision) throws InvalidParameter {
|
||||||
|
BigDecimal bc;
|
||||||
|
try {
|
||||||
|
bc = BigDecimal.valueOf(Long.parseLong(request.getParameter("rate")));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new InvalidParameter("Invalid big int for ".concat(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bc.precision() > precision)
|
||||||
|
throw new InvalidParameter("Precision for ".concat(name).concat(" shounld be over ".concat(String.valueOf(precision))));
|
||||||
|
return bc;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Short parseParamShort(HttpServletRequest request, String name) throws InvalidParameter {
|
||||||
|
try {
|
||||||
|
return Short.valueOf(request.getParameter("rate"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new InvalidParameter("Invalid short number for ".concat(name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String paramNotNull(HttpServletRequest request, String name) throws InvalidParameter {
|
||||||
|
String param = request.getParameter(name);
|
||||||
|
if (param == null || param.isEmpty())
|
||||||
|
throw new InvalidParameter(name.concat(" should not be empty"));
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String paramLength(HttpServletRequest request, String name, int length) throws InvalidParameter {
|
||||||
|
String param = request.getParameter(name);
|
||||||
|
if (param.length() > length)
|
||||||
|
throw new InvalidParameter(name.concat(" should not be more than ".concat(String.valueOf(length)).concat(" characters")));
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String paramLength(String param, String name, int length) throws InvalidParameter {
|
||||||
|
if (param.length() > length)
|
||||||
|
throw new InvalidParameter(name.concat(" should not be more than ".concat(String.valueOf(length)).concat(" characters")));
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String paramAvailable(HttpServletRequest request, String name) throws InvalidParameter {
|
||||||
|
String param = request.getParameter(name).toUpperCase();
|
||||||
|
if (!param.equals("TRUE") && !param.equals("FALSE"))
|
||||||
|
throw new InvalidParameter("It's true or false for ".concat(name));
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Date paramDate(HttpServletRequest request, String name) throws InvalidParameter {
|
||||||
|
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
try {
|
||||||
|
return format.parse(request.getParameter(name));
|
||||||
|
} catch(Exception e) {
|
||||||
|
throw new InvalidParameter("Invalid date for ".concat(name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Object fetchDetailsData(HttpServletRequest request, ModelAndView mv) throws Exception {
|
private Object fetchDetailsData(HttpServletRequest request, ModelAndView mv) throws Exception {
|
||||||
String type = request.getParameter("type");
|
String type = request.getParameter("type");
|
||||||
Object data = null;
|
Object data = null;
|
||||||
|
|
||||||
|
try {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "customer":
|
case "customer":
|
||||||
int customerId = Integer.parseInt(request.getParameter("customerId"));
|
int customerId = parseParamInt(request, "customerId");
|
||||||
char discountCode = request.getParameter("discountCode").charAt(0);
|
char discountCode = paramChar(request, "discountCode");
|
||||||
String zip = request.getParameter("zip");
|
String zip = paramLength(paramNotNull(request, "zip"), "zip", 10);
|
||||||
String name = request.getParameter("name");
|
String name = paramLength(request, "name", 30);
|
||||||
String addressline1 = request.getParameter("addressline1");
|
String addressline1 = paramLength(request, "addressline1", 30);
|
||||||
String addressline2 = request.getParameter("addressline2");
|
String addressline2 = paramLength(request, "addressline2", 30);
|
||||||
String city = request.getParameter("city");
|
String city = paramLength(request, "city", 25);
|
||||||
String state = request.getParameter("state");
|
String state = paramLength(request, "state", 2);
|
||||||
String phone = request.getParameter("phone");
|
String phone = paramLength(request, "phone", 12);
|
||||||
String fax = request.getParameter("fax");
|
String fax = paramLength(request, "fax", 12);
|
||||||
String email = request.getParameter("email");
|
String email = paramLength(request, "email", 40);
|
||||||
int creditLimit = Integer.parseInt(request.getParameter("creditLimit"));
|
int creditLimit = parseParamInt(request, "creditLimit");
|
||||||
data = new Customer(customerId, discountCode, zip, name, addressline1, addressline2, city, state, phone, fax, email, creditLimit);
|
data = new Customer(customerId, discountCode, zip, name, addressline1, addressline2, city, state, phone, fax, email, creditLimit);
|
||||||
break;
|
break;
|
||||||
case "product":
|
case "product":
|
||||||
int productId = Integer.parseInt(request.getParameter("productId"));
|
int productId = parseParamInt(request, "productId");
|
||||||
int manufacturerId = Integer.parseInt(request.getParameter("manufacturerId"));
|
int manufacturerId = parseParamInt(paramNotNull(request, "manufacturerId"), "manufacturerId");
|
||||||
String productCode = request.getParameter("productCode");
|
String productCode = paramLength(paramNotNull(request, "productCode"), "productCode", 2);
|
||||||
BigDecimal purchaseCost = BigDecimal.valueOf(Double.parseDouble(request.getParameter("purchaseCost")));
|
BigDecimal purchaseCost = parseParamBigDecimal(request, "purchaseCost", 12);
|
||||||
int quantityOnHand = Integer.parseInt(request.getParameter("quantityOnHand"));
|
int quantityOnHand = parseParamInt(request, "quantityOnHand");
|
||||||
BigDecimal markup = BigDecimal.valueOf(Double.parseDouble(request.getParameter("markup")));
|
BigDecimal markup = parseParamBigDecimal(request, "markup", 12);
|
||||||
String available = request.getParameter("available");
|
String available = paramAvailable(request, "available");
|
||||||
String description = request.getParameter("description");
|
String description = paramLength(request, "description", 50);
|
||||||
data = new Product(productId, manufacturerId, productCode, purchaseCost, quantityOnHand, markup, available, description);
|
data = new Product(productId, manufacturerId, productCode, purchaseCost, quantityOnHand, markup, available, description);
|
||||||
break;
|
break;
|
||||||
case "purchase":
|
case "purchase":
|
||||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
|
int orderNum = parseParamInt(request, "orderNum");
|
||||||
|
customerId = parseParamInt(paramNotNull(request, "customerId"), "customerId");
|
||||||
int orderNum = Integer.parseInt(request.getParameter("orderNum"));
|
productId = parseParamInt(paramNotNull(request, "productId"), "productId");
|
||||||
customerId = Integer.parseInt(request.getParameter("customerId"));
|
Short quantity = parseParamShort(request, "quantity");
|
||||||
productId = Integer.parseInt(request.getParameter("productId"));
|
BigDecimal shippingCost = parseParamBigDecimal(request, "shippingCost", 12);
|
||||||
Short quantity = Short.parseShort(request.getParameter("quantity"));
|
Date salesDate = paramDate(request, "salesDate");
|
||||||
BigDecimal shippingCost = BigDecimal.valueOf(Double.parseDouble(request.getParameter("shippingCost")));
|
Date shippingDate = paramDate(request, "shippingDate");
|
||||||
Date salesDate = format.parse(request.getParameter("salesDate"));
|
String freightCompany = paramLength(request, "freightCompany", 30);
|
||||||
Date shippingDate = format.parse(request.getParameter("shippingDate"));
|
|
||||||
String freightCompany = request.getParameter("freightCompany");
|
|
||||||
data = new PurchaseOrder(orderNum, customerId, productId, quantity, shippingCost, salesDate, shippingDate, freightCompany);
|
data = new PurchaseOrder(orderNum, customerId, productId, quantity, shippingCost, salesDate, shippingDate, freightCompany);
|
||||||
break;
|
break;
|
||||||
case "discount":
|
case "discount":
|
||||||
discountCode = request.getParameter("discountCode").charAt(0);
|
discountCode = paramChar(request, "discountCode");
|
||||||
BigDecimal rate = BigDecimal.valueOf(Double.parseDouble(request.getParameter("rate")));
|
BigDecimal rate = parseParamBigDecimal(request, "rate", 4);
|
||||||
data = new DiscountCode(discountCode, rate);
|
data = new DiscountCode(discountCode, rate);
|
||||||
break;
|
break;
|
||||||
case "prodCode":
|
case "prodCode":
|
||||||
productCode = request.getParameter("prodCode");
|
productCode = paramLength(request, "prodCode", 2);
|
||||||
discountCode = request.getParameter("discountCode").charAt(0);
|
discountCode = paramChar(request, "discountCode");
|
||||||
description = request.getParameter("description");
|
description = paramLength(request, "description", 10);
|
||||||
data = new ProductCode(productCode, discountCode, description);
|
data = new ProductCode(productCode, discountCode, description);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
mv.addObject("error", "Type not found");
|
mv.addObject("error", "Type not found");
|
||||||
return mv;
|
return mv;
|
||||||
}
|
}
|
||||||
|
} catch (InvalidParameter e) {
|
||||||
|
mv.addObject("error", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
@ -324,8 +408,16 @@ public class BddController extends MultiActionController {
|
||||||
mv.addObject("type", type);
|
mv.addObject("type", type);
|
||||||
Object data = fetchDetailsData(request, mv);
|
Object data = fetchDetailsData(request, mv);
|
||||||
|
|
||||||
|
if (data != null) {
|
||||||
|
try {
|
||||||
new MagasinHelper().add(data);
|
new MagasinHelper().add(data);
|
||||||
mv.addObject("confirm","Save completed");
|
mv.addObject("confirm","Save completed");
|
||||||
|
} catch (ConstraintViolationException e) {
|
||||||
|
mv.addObject("error", e.getSQLException().getMessage());
|
||||||
|
} catch (Exception e) {
|
||||||
|
mv.addObject("error", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
return mv;
|
return mv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,11 +430,14 @@ public class BddController extends MultiActionController {
|
||||||
mv.addObject("type", type);
|
mv.addObject("type", type);
|
||||||
Object data = fetchDetailsData(request, mv);
|
Object data = fetchDetailsData(request, mv);
|
||||||
|
|
||||||
|
if (data != null) {
|
||||||
|
try {
|
||||||
new MagasinHelper().update(data);
|
new MagasinHelper().update(data);
|
||||||
mv.addObject("confirm","Update completed");
|
mv.addObject("confirm","Update completed");
|
||||||
|
} catch (Exception e) {
|
||||||
|
mv.addObject("error", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
return mv;
|
return mv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<body>
|
<body>
|
||||||
<%@include file="header.jsp" %>
|
<%@include file="header.jsp" %>
|
||||||
|
|
||||||
<h1>${confirm} </h1>
|
<h1>${error != null ? error : confirm} </h1>
|
||||||
<form action="list.htm" method="POST">
|
<form action="list.htm" method="POST">
|
||||||
<input hidden type="text" name="type" value="${type}" />
|
<input hidden type="text" name="type" value="${type}" />
|
||||||
<input type="submit" value="Afficher tous les enregistrements" />
|
<input type="submit" value="Afficher tous les enregistrements" />
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
<label for="discountCode">Remise</label>
|
<label for="discountCode">Remise</label>
|
||||||
<select name="discountCode" id="discountCode">
|
<select name="discountCode" id="discountCode">
|
||||||
<c:forEach items="${code}" var="dc">
|
<c:forEach items="${code}" var="dc">
|
||||||
<option <c:if test="${dc.discountCode==result.discountCode}"> selected </c:if> value="${dc.discountCode}}">${dc.discountCode} - ${dc.rate}%</option>
|
<option <c:if test="${dc.discountCode==result.discountCode}"> selected </c:if> value="${dc.discountCode}">${dc.discountCode} - ${dc.rate}%</option>
|
||||||
</c:forEach>
|
</c:forEach>
|
||||||
</select>
|
</select>
|
||||||
</p>
|
</p>
|
||||||
|
@ -175,7 +175,7 @@
|
||||||
<label for="discountCode">Remise</label>
|
<label for="discountCode">Remise</label>
|
||||||
<select name="discountCode" id="discountCode">
|
<select name="discountCode" id="discountCode">
|
||||||
<c:forEach items="${code}" var="dc">
|
<c:forEach items="${code}" var="dc">
|
||||||
<option <c:if test="${dc.discountCode==result.discountCode}"> selected </c:if> value="${dc.discountCode}}">${dc.discountCode} - ${dc.rate}%</option>
|
<option <c:if test="${dc.discountCode==result.discountCode}"> selected </c:if> value="${dc.discountCode}">${dc.discountCode} - ${dc.rate}%</option>
|
||||||
</c:forEach>
|
</c:forEach>
|
||||||
</select>
|
</select>
|
||||||
</p>
|
</p>
|
||||||
|
|
Reference in a new issue