今度はサクサク行きました。注意点はcheckboxからのデータ取得だけです。
spring:bindでDeleteProducts.product.idをbindするとcheckboxで選択した値が取れません(選択されたものだけでなく、全てとれてしまいます)。
そのため"targets"というint配列をBeanに追加し、jsp上でid="targets"、name="targets"というタグを書き込んでいます。
【手順概要】
ProductDAOにインターフェースdeleteProductを追加します。
JdbcProductDaoでdeleteProductを実装します。
JdbcProductDaoTestsにテストメソッドを追加します。
ProductManagerにdeleteProductインターフェースを追加します。
SimpleProductManagerでdeleteProductメソッドを実装します。
DeleteProducts Beanを追加します。
DelteProductValidatorを追加します。
DeleteProductFormControllerを追加します。
deleteProduct画面を追加します。
springapp-servlet.xml、メッセージ、リンクにエントリーを追加します。
【手順詳細】
ProductDAOにインターフェースdeleteProductを追加します。
public void deleteProduct(Product prod);
JdbcProductDaoでdeleteProductを実装します。
@Override
public void deleteProduct(Product prod) {
logger.info("Delete product: " + prod.getDescription());
int count = getSimpleJdbcTemplate().update(
"delete from products where id = :id",
new MapSqlParameterSource().addValue("id", prod.getId()));
logger.info("Deleted: " + count);
}
JdbcProductDaoTestsにテストメソッドを追加します。
public void testDeleteProduct() {
List<Product> products = new ArrayList<Product>();
Product p1 = createProduct(200, "dummy10", 100.10);
Product p2 = createProduct(201, "dummy11", 100.20);
products.add(p1);
products.add(p2);
for (Product p : products) {
productDao.insertProduct(p);
}
List<Product> insertedProducts = productDao.getProductList();
boolean checked1 = false;
boolean checked2 = false;
for (Product p : insertedProducts) {
if (p.getId() == p1.getId()) {
dumpProduct(p);
dumpProduct(p1);
assertEquals(true, p.equals(p1));
checked1 = true;
}
if (p.getId() == p2.getId()) {
dumpProduct(p);
dumpProduct(p2);
assertEquals(true, p.equals(p2));
checked2 = true;
}
}
if (!checked1 || !checked2) {
fail("Product not inserted.");
}
productDao.deleteProduct(p1);
productDao.deleteProduct(p2);
List<Product> afterDelete = productDao.getProductList();
for (Product p : afterDelete) {
if (p.getId() == p1.getId()) {
fail("Product p1 not deleted.");
}
if (p.getId() == p2.getId()) {
fail("Product p2 not deleted.");
}
}
}
ProductManagerにdeleteProductインターフェースを追加します。
public void deleteProduct(Product product);
SimpleProductManagerでdeleteProductメソッドを実装します。
@Override
public void deleteProduct(Product product) {
productDao.deleteProduct(product);
}
DeleteProducts Beanを追加します。
package springapp.service;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import springapp.domain.Product;
public class DeleteProducts {
/** Logger for this class and subclasses */
protected final Log logger = LogFactory.getLog(getClass());
private List<Product> products = null;
int [] targets = null; // ポイント
public void setProducts(List<Product> products) {
this.products = products;
}
public List<Product> getProducts() {
return products;
}
public int[] getTargets() {
return targets;
}
public void setTargets(int[] targets) {
this.targets = targets;
StringBuffer log = new StringBuffer();
log.append("Targets set:");
for(int i = 0; i < targets.length; i++) {
log.append(targets[i]);
log.append(":");
}
logger.info(log);
}
}
DelteProductValidatorを追加します。
package springapp.service;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class DeleteProductsValidator implements Validator {
/** Logger for this class and subclasses */
protected final Log logger = LogFactory.getLog(getClass());
public boolean supports(Class clazz) {
return DeleteProducts.class.equals(clazz);
}
public void validate(Object obj, Errors errors) {
DeleteProducts dp = (DeleteProducts) obj;
logger.info("Validating ...");
int[] targets = dp.getTargets();
if (targets == null || targets.length == 0) {
logger.info("Delete target not selected.");
errors.rejectValue("products", "error.target-not-specified", null,
"Value required.");
}
logger.info("Validation end.");
}
}
DeleteProductFormControllerを追加します。
package springapp.web;
import java.util.List;
import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import springapp.domain.Product;
import springapp.service.DeleteProducts;
import springapp.service.ProductManager;
public class DeleteProductsFormController extends SimpleFormController {
/** Logger for this class and subclasses */
protected final Log logger = LogFactory.getLog(getClass());
private ProductManager productManager;
public ModelAndView onSubmit(Object command) throws ServletException {
DeleteProducts dp = (DeleteProducts) command;
List<Product> products = dp.getProducts();
int[] targets = dp.getTargets();
for (int i = 0; i < targets.length; i++) {
for (Product product : products) {
if (targets[i] == product.getId()) {
productManager.deleteProduct(product);
logger.info("Deleted:" + product);
continue;
}
}
}
return new ModelAndView(new RedirectView(getSuccessView()));
}
protected Object formBackingObject(HttpServletRequest request)
throws ServletException {
DeleteProducts dp = new DeleteProducts();
dp.setProducts(productManager.getProducts());
return dp;
}
public void setProductManager(ProductManager productManager) {
this.productManager = productManager;
}
public ProductManager getProductManager() {
return productManager;
}
}
deleteProduct画面を追加します。
<%@ include file="/WEB-INF/jsp/include.jsp" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<html>
<head>
<title><fmt:message key="title"/></title>
<style>
.error { color: red; }
</style>
</head>
<body>
<h1><fmt:message key="deleteproducts.heading"/></h1>
<form:form method="post" commandName="deleteProducts">
<c:forEach items="${deleteProducts.products}" varStatus="row">
<spring:bind path="deleteProducts.products[${row.index}].id">
<input type="checkbox"
<!-- "id"ではチェックボックスの値が取得できません -->
name="targets"
id="targets"
value="<c:out value="${status.value}"/>" />
</spring:bind>
<spring:bind path="deleteProducts.products[${row.index}].description">
<c:out value="${status.value}"/>
</spring:bind>
<spring:bind path="deleteProducts.products[${row.index}].price">
<i>$<c:out value="${status.value}"/></i>
</spring:bind>
<br>
</c:forEach>
<form:errors path="products" cssClass="error"/>
<br>
<input type="submit" align="center" value="Execute">
</form:form>
<a href="<c:url value="hello.htm"/>">Home</a>
</body>
</html>
springapp-servlet.xml
<bean name="/deleteproducts.htm" class="springapp.web.DeleteProductsFormController">
<property name="sessionForm" value="true"/>
<property name="commandName" value="deleteProducts"/>
<property name="commandClass" value="springapp.service.DeleteProducts"/>
<property name="validator">
<bean class="springapp.service.DeleteProductsValidator"/>
</property>
<property name="formView" value="deleteproducts"/>
<property name="successView" value="hello.htm"/>
<property name="productManager" ref="productManager"/>
</bean>
メッセージ
deleteproducts.heading=Delete products :: SpringApp
error.target-not-specified=Target not specified!!!
hello.jspからのリンク
<br><a href="<c:url value="deleteproducts.htm"/>">Delete products</a>
以上
0 件のコメント:
コメントを投稿