若還沒有看過前面幾篇文章的話建議先去看Struts2 架構配置教學、Struts2+Spring架構配置教學(Spring)、Struts2+Spring+Hibernate架構配置教學(Hibernate)上、Struts2+Spring+Hibernate架構配置教學(Hibernate+JNDI)下、Spring+Hibernate用法教學
再來看這篇文章
討厭鬼會用到struts2 tag的時候
多判是用來套版面的時候~
當然也可以拿來做一些畫面開始必需要做的事情
在這邊要教的東西不多~
只會教一些常用的東西
像是 if iterator 等等之類常用的東西
那麼癈話就不多說了~開始吧
在用Srtus2 tag之前~我們要先重資料庫撈資料出來
先在index()裡查詢
並設置一個全域變數來接收
並了能讓jsp拿到這個變數
需要實作getter
範列
public class IndexAction extends ActionSupport {
/**
*
*/
private static final long serialVersionUID = 1L;
@Resource
private LeatherService leatherService;
List<LeatherType> leatherTypeList;
public String index() {
leatherTypeList = leatherService.doQueryLeatherTypeList();
return SUCCESS;
}
public List<LeatherType> getLeatherTypeList() {
return leatherTypeList;
}
}
在jsp中加入下列就可以列出資料了
我的資料;車中有3筆資料
其中兩筆price >=200
所以下列就只會列出兩筆
<table>
<s:iterator value="leatherTypeList" status="i">
<tr>
<s:if test="price >= 200">
<td><s:property value="typeName"/></td>
<td><s:property value="price"/></td>
</s:if>
</tr>
</s:iterator>
</table>
範列
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!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=UTF-8">
<title>討厭鬼的教學</title>
</head>
<body>
<table>
<s:iterator value="leatherTypeList" status="i">
<tr>
<s:if test="price >= 200">
<td><s:property value="typeName"/></td>
<td><s:property value="price"/></td>
</s:if>
</tr>
</s:iterator>
</table>
</body>
</html>
而像select跟radio的用法也很簡單
可以直接在List的地方寫死如下
<s:select list="#{1:'大皮',2:'中皮',3:'小皮',4:'死皮'}" />
或是直接用map型態的物件就可以了~如下
<s:select list="typeMap" />
而property的用法也可以很多種
例如我在action有物件叫userName與hello也設定getter了~如下
String userName = "nerdy";
String hello = "你好嗎?";
public String getUserName(){
return userName;
}
public String getHello(){
return hello;
}
那我的Struts2 tag
就可以寫成<s:property name="userName"/><s:property name="hello"/>
結果就會變成"nerdy你好嗎?"
也可以寫成<s:property name="userName+hello"/>
結果一樣是"nerdy你好嗎?"
當然也可以用substring
如果型態是int的話~也可以用來加減乘除
切記~如果要讓jsp拿到值
一定要在action的地方設定getter不然的話是取不到值的
基本上在做套版的只要用到if跟iterator就可以做到大部份的事
能用到Struts2 tag的地方盡量用
如果我要做一個連回首頁的
<s:a action="index">連回首頁</s:a>
還有一點是需要注意一點
在使用if時若是判斷字串
應該為
<s:if test='userName == "nerdy" '>
而非
<s:if test="userName == 'nerdy' ">
差別就在於若是用單引號
會認為這是char而判斷錯誤
用雙引號就不會有問題了
預計下次會發Spring transactionmanager的教學

版大安安...學到現在一知半解可否請板大寫個通用範例來連貫這幾個章節的東西 謝謝....
可以~你比較不懂的地方在哪呢? 我再看怎麼寫比較好~
版大安安... 請問在用Srtus2 tag之前~我們要先重資料庫撈資料出來 先在index()裡查詢 並設置一個全域變數來接收 並了能讓jsp拿到這個變數 需要實作getter 程式碼裡面的LeatherService 出現錯誤是還要建一個class嗎還是import 哪邊的型別 private LeatherService leatherService; List leatherTypeList;
public String index() {
leatherTypeList = leatherService.doQueryLeatherTypeList();
return SUCCESS;
}
....感恩謝謝
是要新建一個class叫LeatherService 裡面是在擺商業邏輯的 以這一篇Spring+transaction manager 配置教學為例 裡面有講轉帳的例子 在轉帳service中 你會呼叫台銀dao看台銀裡的錢夠不夠轉帳 夠的話再呼叫台銀dao把台銀的錢減少 再呼叫中郵dao把中郵的錢增加
版大安安 這一篇從資料庫取值我試了好久一直錯誤可否請問板大幫忙看看是哪邊ㄉ問題 以下列出consoleㄉ資訊 2012/6/8 下午 03:17:58 org.apache.catalina.core.AprLifecycleListener init 資訊: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Program Files\Java\jre6\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files (x86)\AMD APP\bin_64;C:\Program Files (x86)\AMD APP\bin;C:\Program Files (x86)\PC Connectivity Solution\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static;C:\Program Files\Java\jdk1.7.0_01\bin;C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\;C:\Program Files\Microsoft SQL Server\100\Tools\Binn\;C:\Program Files\Microsoft SQL Server\100\DTS\Binn\;C:\AppServ\Apache2.2\bin;C:\AppServ\php6;C:\AppServ\MySQL\bin;. 2012/6/8 下午 03:17:58 org.apache.tomcat.util.digester.SetPropertiesRule begin 警告: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:leather' did not find a matching property. 2012/6/8 下午 03:17:58 org.apache.coyote.AbstractProtocol init 資訊: Initializing ProtocolHandler ["http-bio-8080"] 2012/6/8 下午 03:17:58 org.apache.coyote.AbstractProtocol init 資訊: Initializing ProtocolHandler ["ajp-bio-8009"] 2012/6/8 下午 03:17:58 org.apache.catalina.startup.Catalina load 資訊: Initialization processed in 1003 ms 2012/6/8 下午 03:17:58 org.apache.catalina.core.StandardService startInternal 資訊: Starting service Catalina 2012/6/8 下午 03:17:58 org.apache.catalina.core.StandardEngine startInternal 資訊: Starting Servlet Engine: Apache Tomcat/7.0.26 2012/6/8 下午 03:17:59 org.apache.catalina.core.ApplicationContext log 資訊: Initializing Spring root WebApplicationContext 2012/6/8 下午 03:17:59 org.springframework.web.context.ContextLoader initWebApplicationContext 資訊: Root WebApplicationContext: initialization started 2012/6/8 下午 03:17:59 org.springframework.context.support.AbstractApplicationContext prepareRefresh 資訊: Refreshing Root WebApplicationContext: startup date [Fri Jun 08 15:17:59 GMT+08:00 2012]; root of context hierarchy 2012/6/8 下午 03:17:59 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 資訊: Loading XML bean definitions from class path resource [nerdy/config/action-context.xml] 2012/6/8 下午 03:18:00 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 資訊: Loading XML bean definitions from class path resource [nerdy/config/service-context.xml] 2012/6/8 下午 03:18:00 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 資訊: Loading XML bean definitions from class path resource [nerdy/config/dao-context.xml] 2012/6/8 下午 03:18:00 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons 資訊: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@45f8acdc: defining beans [indexAction,sessionFactory,dataSource,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0]; root of factory hierarchy 2012/6/8 下午 03:18:00 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons 資訊: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@45f8acdc: defining beans [indexAction,sessionFactory,dataSource,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.internalPersistenceAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0]; root of factory hierarchy 2012/6/8 下午 03:18:00 org.springframework.web.context.ContextLoader initWebApplicationContext 嚴重的: Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'indexAction': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [nerdy.service.LeatherService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.annotation.Resource(shareable=true, mappedName=, description=, name=, type=class java.lang.Object, authenticationType=CONTAINER)} at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:306) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464) at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:385) at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:284) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4779) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5273) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1566) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1556) at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [nerdy.service.LeatherService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.annotation.Resource(shareable=true, mappedName=, description=, name=, type=class java.lang.Object, authenticationType=CONTAINER)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:924) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:793) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:438) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:416) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:549) at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:150) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:303) ... 23 more 2012/6/8 下午 03:18:00 org.apache.catalina.core.StandardContext listenerStart 嚴重的: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'indexAction': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [nerdy.service.LeatherService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.annotation.Resource(shareable=true, mappedName=, description=, name=, type=class java.lang.Object, authenticationType=CONTAINER)} at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:306) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464) at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:385) at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:284) at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4779) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5273) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1566) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1556) at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [nerdy.service.LeatherService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.annotation.Resource(shareable=true, mappedName=, description=, name=, type=class java.lang.Object, authenticationType=CONTAINER)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:924) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:793) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:438) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:416) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:549) at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:150) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:303) ... 23 more 2012/6/8 下午 03:18:00 org.apache.catalina.core.StandardContext startInternal 嚴重的: Error listenerStart 2012/6/8 下午 03:18:00 org.apache.catalina.core.StandardContext startInternal 嚴重的: Context [/leather] startup failed due to previous errors 2012/6/8 下午 03:18:00 org.apache.catalina.core.ApplicationContext log 資訊: Closing Spring root WebApplicationContext 2012/6/8 下午 03:18:00 org.apache.coyote.AbstractProtocol start 資訊: Starting ProtocolHandler ["http-bio-8080"] 2012/6/8 下午 03:18:00 org.apache.coyote.AbstractProtocol start 資訊: Starting ProtocolHandler ["ajp-bio-8009"] 2012/6/8 下午 03:18:00 org.apache.catalina.startup.Catalina start 資訊: Server startup in 1949 ms 感恩...謝謝...
應該是你的spring設定檔沒有設定完全 你在IndexAction 有加了 @ Resource private LeatherService leatherService; 可是在spring中沒有設定leatherService
你好 從您的教學文從第一篇看到這裡 結果就完全的搞混了OTL 所以想跟你請教一下 我照著在上一篇"Spring+Hibernate用法教學" 建好了LeatherTypeDAO裡面的doQueryLeatherTypeList 正苦惱要怎麼來確認是否正確時 看到這篇 所以照著這篇在IndexAction呼叫doQueryLeatherTypeList 然後在照著這篇 在jsp想把資料顯示出來 但目前遇到狀況是java.lang.NullPointerException 而且eclipse沒有什麼例外訊息 怪怪... 剛剛看到你的回應說 要新建一個class叫LeatherService 那請問跟LeatherTypeDAO有什麼不同呢 兩邊不都是要有doQueryLeatherTypeList嗎 還是把LeatherTypeDAO複製過去就好呢? 不好意思實在是看不懂OTL 先謝謝你了
LeatherTypeDAO的doQueryLeatherTypeList 跟LeatherService的doQueryLeatherTypeList 是兩個不同的東西 DAO是對資料庫做增刪改查 Service是透過DAO對資料庫做增刪改查 DAO是單純對資料庫做增刪改查 Service是商業邏輯 ex: 上網下訂單 Service的邏輯為 先查詢有沒有庫存 有的話庫存減掉下訂數量 新增一筆訂單 沒有的話交易失敗 在這邊 DAO就是單純的query庫存 跟add訂單 而Service就會有一連串的處理 而討厭鬼的範例是因為比較單純 Service只是把DAO撈到的資料再往前丟到Action而已
了解 原來是這樣 謝謝你OTL 那想請問說 有辦法直接對DAO測試嗎? 因為做到"Spring+Hibernate用法教學"時 想知道到底DAO那塊有沒有完成了 請問有辦法直接從jsp那邊 呼叫LeatherTypeDAO裡面的doQueryLeatherTypeList嗎 然後顯示出來嗎? 還是沒辦法 只能多寫個Service這樣? 那請問Service那邊怎麼實現呢 謝謝!!
關於這點~可以參考一下討厭鬼的JUnit4+Spring(JNDI)+Ant自動化測試 教學 這篇可以對dao做測試 service實現的方法在Struts2+Spring架構配置教學(Spring) 這篇可以找到解答 當初會說要設3個spring設定檔就是為了一個層級一個設定檔 action的在action-layer service在service-layer dao在dao-layer 而在這篇是只寫了action的設定 service的設定是一樣的
了解 原來是這樣 謝謝您 後來找了其他教學文交叉的學 才大概有點進入狀況 謝謝OTL
有幫到忙就好~
感謝詳細的解說!
您好,最近開始研究SSH架構,照著您的方法實做後跑出來發現 public List getLeatherTypeList() 這個method 沒有進去跑
當然jsp也就沒有結果出來
想請教一下有可能是因為甚麼原因呢?
可以的話,可以提供錯誤訊息給討厭鬼嗎? 信箱:nerdy.chen@gmail.com