2008年5月23日金曜日

Springフレームワークの続き(リベンジ)

前回失敗したrequestデータの受け渡しを(ベタですが)HttpSessionを使って実装し、とりあえずリベンジしました。

いろいろ調べていると"SimpleFormController"はformBackingObjectで画面を描画し"onSubmit"でその画面に入力された処理を行うという、ある特定の一画面を処理するのに特化したコントローラのようです。

画面間でデータを受け渡すには以下の方法があって、
1.DBやHttpSessionを使う
2.AbstractWizardFormControllerとSpring WebFlowを使う
ということのようです。

(参考ページ)getSuccessView() and formBackingObject() [Archive] dsklyut氏の投稿より

前回は「Postされたデータが取れない」と嘆きましたが、どうやらSimpleFormControllerはFormも(恐らくはRequestも)次画面に遷移する時はクリアしてしまうらしいですね。納得できる説明です。

以下が変更した内容です。

SelectProduct.java(太字部分が追加)
Requestから直でIDを取るからいらないか、と思って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 SelectProduct {
/** Logger for this class and subclasses */
protected final Log logger = LogFactory.getLog(getClass());

private List products = null;

private int id = 0;

public int getId() {
return id;
}

public void setId(int id) {
logger.info("id:" + id + " set.");
this.id = id;
}

public List getProducts() {
return products;
}

public void setProducts(List products) {
this.products = products;
}
}

SelectInventoryFormController
HttpServletRequest引数を持つonSubmitに変え、SessionにObjectを詰めています。
package springapp.web;

import org.springframework.validation.BindException;
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 javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import springapp.service.ProductManager;
import springapp.service.SelectProduct;

public class SelectInventoryFormController extends SimpleFormController {
/** Logger for this class and subclasses */
protected final Log logger = LogFactory.getLog(getClass());
private ProductManager productManager;

protected Object formBackingObject(HttpServletRequest request)
throws ServletException {
SelectProduct selectProduct = new SelectProduct();
logger.info("productManager:" + productManager.getProducts().size());
selectProduct.setProducts(productManager.getProducts());
logger.info("selectProd:" + selectProduct.getProducts().size());
return selectProduct;
}

@Override
protected ModelAndView onSubmit(HttpServletRequest request,
HttpServletResponse response, Object command, BindException errors)
throws Exception {
logger.info("Executed.");
SelectProduct sp = (SelectProduct) command;
logger.info("SelectProduct.getId():" + sp.getId());
HttpSession session = request.getSession();
session.setAttribute("SelectProduct", sp);
return new ModelAndView(new RedirectView(getSuccessView()));
}

public void setProductManager(ProductManager productManager) {
this.productManager = productManager;
}

public ProductManager getProductManager() {
return productManager;
}

}

SetPriceFormController
formBackingObjectの中でSessionを参照し、前画面の結果を貰っています。
package springapp.web;

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.ProductManager;
import springapp.service.SelectProduct;
import springapp.service.SetPrice;

public class SetPriceFormController 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 {
int id = ((SetPrice) command).getId();
double price = ((SetPrice) command).getPrice();

productManager.setPrice(id, price);
logger.info("Update prices by " + price + ". Id is " + id + ".");
logger.info("returning from PriceIncreaseForm view to "
+ getSuccessView());

return new ModelAndView(new RedirectView(getSuccessView()));
}

protected Object formBackingObject(HttpServletRequest request)
throws ServletException {
SetPrice ret = new SetPrice();
SelectProduct sp = (SelectProduct) request.getSession().getAttribute(
"SelectProduct");
int i = sp.getId();

for (Product product : productManager.getProducts()) {
if (product.getId() == i) {
ret.setId(i);
ret.setDescription(product.getDescription());
ret.setPrice(product.getPrice());
break;
}
}
return ret;
}

public void setProductManager(ProductManager productManager) {
this.productManager = productManager;
}

public ProductManager getProductManager() {
return productManager;
}

}


まずは一段落。Springの評価が少し上がりました(私の誤解が解けただけですけどね)。

0 件のコメント: