如下爲須要準備的文件清單,從相應網址下載到本地,表格中列出的版本號是截止到2012年5月6日的最新版本。 javascript
序號 html |
庫類型 java |
版本 jquery |
文件名 web |
下載地址 spring |
1 sql |
Struts2 數據庫 |
2.3.3 express |
struts-2.3.3-all.gz apache |
http://struts.apache.org/ |
2 |
Spring |
3.1.0 |
spring-framework-3.1.1.RELEASE-with-docs.zip |
http://springframework.org/ |
3 |
Mybatis |
3.1.1 |
mybatis-3.1.1-bundle.zip mybatis-spring-1.1.1-bundle.zip mybatis-generator-core-1.3.1-bundle.zip |
http://code.google.com/p/mybatis/ |
4 |
jquery |
1.7.2 |
jquery-1.7.2.js |
http://jquery.com/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
Eclipse |
eclipse-jee-indigo-SR2-win32.zip |
http://www.eclipse.org/downloads/ |
|
5 |
tomcat |
7.0.27 |
apache-tomcat-7.0.27-windows-x86.zip |
http://tomcat.apache.org/ |
下載包含了庫和代碼、例子的全包:spring-framework-3.1.1.RELEASE-with-docs.zip
選擇WEB下Dynamic Web Project類型的工程:
工程命名爲EMS,其它選項保持默認。
文件夾名保持默認
勾上生成web.xml選項,其它保持默認。
最後獲得一個以下組織的WEB工程.
補充:
在Java Resources/src目錄上經過右鍵菜單將JAVA代碼下編譯輸出目錄修改至WebContent/WEB-INF/classes目錄,與myEclipse的默認方式保持一致,便於實時發佈,若是不作這一步class等文件不會自動輸出到WEB-INF下。
切換Servers頁籤:
※ 建議不採用eclipse的應用發佈功能,改用修改Tomcat配置文件的方式來實現發佈,所以這裏暫時不做選擇。
在Eclipse中測試啓動Tomcat服務器:
採用修改Tomcat配置的方式來發布應用(建議採用,這是相對快捷的發佈
1、雙擊tomcat服務器,打開配置選項,將Server Location選項置爲第二個:
2、用文本編輯器打開:D:\tomcat\apache-tomcat-7.0.27\conf\server.xml文件,在Host節點之上增長虛擬目錄描述:
…
<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t "%r" %s %b" prefix="localhost_access_log." suffix=".txt"/>
<Context path="/ems" docBase="E:\workspace\EMS\WebContent" reloadable="true"/>
</Host>
</Engine>
</Service>
</Server>
3、在WebContent目錄下新建一個默認JSP頁面:NewFile.jsp,打印一行信息:Hello World!
<html> <head> <metahttp-equiv="Content-Type"content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> Hello World!
</body> </html> |
4、在eclipse中重啓tomcat,在瀏覽器中敲入URL:http://localhost:8080/ems/NewFile.jsp
驗證是否看到正確的輸出信息。
配置TOMCAT管理界面
打開:D:\tomcat\apache-tomcat-7.0.27\conf\tomcat-users.xml文件,加入:
<tomcat-users>
<role rolename="manager-gui"/>
<role rolename="admin-gui"/>
<user username="admin" password="admin" roles="manager-gui,admin-gui"/>
</tomcat-users>
以後經過admin/admin便可登錄管理界面。
從已下載的struts-2.3.3-all.gz文件中解壓出自帶的一個空例程:struts2-blank,直接從展開的文件夾中複製內容過來:
1) 複製struts2-blank\WEB-INF\lib目錄下的全部JAR包到該工程的WEB-INF/lib目錄下
2) 打開struts2-blank\WEB-INF\web.xml,複製其中過濾器到該工程相同目錄下web.xml,,讓struts2在tomcat啓動的時候加載:
… <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter>
<filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> … |
3) 重啓Tomcat服務,觀察輸出的日誌,當發現啓動日誌中包含有「org.apache.struts2」關鍵字,且無異常拋出,說明struts2的裝載過程正常。
1) 在src下新建action包:com.jsdz.action,包中新建測試action類,該類繼承至ActionSupport,命名爲:LoginAction,用做登錄跳轉:
packagecom.jsdz.action;
import com.opensymphony.xwork2.ActionSupport;
publicclassLoginActionextendsActionSupport {
private String username ;
private String password ;
@Override public String execute() throws Exception {
System.out.println("LoginAction execute invoked!");
if(username.equals("admin") &&password.equals("1234") ) { System.out.println("user ok");
returnSUCCESS; } else { System.out.println("user invalid"); returnINPUT ; } }
public String getUsername() { returnusername; }
publicvoidsetUsername(String username) { this.username = username; }
public String getPassword() { returnpassword; }
publicvoidsetPassword(String password) { this.password = password; } } |
2) 在將LoginAction類配置到struts2的配置文件中,該文件一樣能夠從例程工程中拷貝過來簡單修改:
<?xmlversion="1.0"encoding="UTF-8"?> <!DOCTYPEstrutsPUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts> <packagename="emspkg"extends="struts-default">
<actionname="login"class="com.jsdz.action.LoginAction"> <resultname="success">/main.jsp</result> <resultname="input">/login.jsp</result> </action>
</package> </struts> |
注意:此時的action實例仍是由struts本身來維護,class取值包含完整的路徑。
3) 新建兩個JSP頁面:login.jsp(登錄頁面)、main.jsp(登錄成功頁面,提示用戶登錄成功).流程說明:用戶輸入用戶名和密碼,必須是admin/1234纔給驗證經過轉到main.jsp頁面,不然仍然返回到login.jsp頁面。
login.jsp
<%@pagelanguage="java"contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%> <%@taglibprefix="s"uri="/struts-tags"%>
<!DOCTYPEhtmlPUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"> <html> <head>
<metahttp-equiv="Content-Type"content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body>
<s:formaction="login"namespace="/"theme="simple"> username:<s:textfieldname="username"size="20"/><br> password:<s:passwordname="password"size="20"/><br> <s:submitlabel="submit"></s:submit> </s:form>
</body> </html> |
※注意:標紅的部分容易出錯,namespace都帶上相同的取值,s:form的action上不帶.action.
main.jsp
<%@pagelanguage="java"contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPEhtmlPUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <metahttp-equiv="Content-Type"content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> 用戶:${requestScope.username },歡迎您登錄 </body> </html> |
4) 在瀏覽器中敲入http://localhost:8080/ems/login.jsp進行驗證.
採用struts2自有的異常處理機制,避免全部地方加上try/catch。
1) 增長包com.jsdz.exception,並在其中增長自定義業務異常類BusinessException.java。
packagecom.jsdz.exception;
publicclassBusinessExceptionextendsRuntimeException {
privatestaticfinallongserialVersionUID = 0xc1a865c45ffdc5f9L;
publicBusinessException(String frdMessage) { super(createFriendlyErrMsg(frdMessage)); }
publicBusinessException(Throwablethrowable) { super(throwable); }
publicBusinessException(Throwablethrowable, String frdMessage) { super(throwable); }
privatestatic String createFriendlyErrMsg(String msgBody) { String prefixStr = "抱歉,"; String suffixStr = " 請稍後再試或與管理員聯繫!"; StringBufferfriendlyErrMsg = newStringBuffer(""); friendlyErrMsg.append(prefixStr); friendlyErrMsg.append(msgBody); friendlyErrMsg.append(suffixStr); returnfriendlyErrMsg.toString(); } } |
2) 增長包com.jsdz. interceptor,增長一個異常轉化的攔截器類:BusinessInterceptor.java。
packagecom.jsdz.interceptor;
importjava.io.IOException; importjava.sql.SQLException;
importcom.jsdz.exception.BusinessException; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
publicclassBusinessInterceptorextendsAbstractInterceptor {
@Override public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("BusinessInterceptor intercept() invoked! ");
before(invocation);
String result = "";
try { result = invocation.invoke(); } catch (DataAccessException ex) { throw new BusinessException("數據庫操做失敗!"); } catch (NullPointerException ex) { thrownewBusinessException("調用了未經初始化的對象或者是不存在的對象!"); } catch (IOException ex) { thrownewBusinessException("IO異常!"); } catch (ClassNotFoundException ex) { thrownewBusinessException("指定的類不存在!"); } catch (ArithmeticException ex) { thrownewBusinessException("數學運算異常!"); } catch (ArrayIndexOutOfBoundsException ex) { thrownewBusinessException("數組下標越界!"); } catch (IllegalArgumentException ex) { thrownewBusinessException("方法的參數錯誤!"); } catch (ClassCastException ex) { thrownewBusinessException("類型強制轉換錯誤!"); } catch (SecurityException ex) { thrownewBusinessException("違背安全原則異常!"); } catch (SQLException ex) { thrownewBusinessException("操做數據庫異常!"); } catch (NoSuchMethodError ex) { thrownewBusinessException("方法末找到異常!"); } catch (InternalError ex) { thrownewBusinessException("Java虛擬機發生了內部錯誤"); } catch (Exception ex) { thrownewBusinessException("程序內部錯誤,操做失敗!"); }
after(invocation, result);
return result ; }
/** * 驗證登錄等... * @param invocation * @return * @throws Exception */ publicvoid before(ActionInvocation invocation) throws Exception { //... }
/** * 記錄日誌等... * @param invocation * @return * @throws Exception */ publicvoid after(ActionInvocationinvocation,String result) throws Exception{ //... } } |
3) 在WebContent目錄下新建error.jsp,表明出錯跳轉的頁面:
<%@pagelanguage="java"contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%> <%@taglibprefix="s"uri="/struts-tags"%>
<!DOCTYPEhtmlPUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <metahttp-equiv="Content-Type"content="text/html; charset=UTF-8"> <title>error</title> </head> <s:propertyvalue="exception.message"/> <body>
</body> </html> |
頁面簡單的打印出異常信息。
4) 在struts.xml配置文件中加入攔截器及錯誤跳轉指示:
<?xmlversion="1.0"encoding="UTF-8"?> <!DOCTYPEstrutsPUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts> <packagename="emspkg"namespace=""extends="struts-default">
<!--註冊攔截器--> <interceptors> <interceptor name="businessInterceptor" class="com.jsdz.interceptor.BusinessInterceptor"/> <interceptor-stack name="mystack"> <interceptor-ref name="defaultStack"/> <interceptor-ref name="businessInterceptor"/> </interceptor-stack> </interceptors>
<!-- 設置默認攔截器棧 --> <default-interceptor-ref name="mystack"/>
<!-- 全局跳轉頁面 --> <global-results> <result name="error">/error.jsp</result> </global-results>
<!-- 全局異常 --> <global-exception-mappings> <exception-mapping result="error" exception="java.lang.Exception"/> </global-exception-mappings>
<actionname="login"class="loginAction"> <resultname="success">/main.jsp</result> <resultname="input">/login.jsp</result> </action>
</package> </struts> |
5) 在LoginAction的execute方法中故意加入會產生異常的代碼,測試頁面轉向:
inti= 10/0;
結果跳轉至error.jsp,並顯示「抱歉,數學運算異常!請稍後再試或與管理員聯繫!」。
從struts-2.3.3-all.gz包中複製struts2-spring-plugin-2.3.3.jar、commons-logging-1.1.1.jar兩個JAR文件到該工程的WEB-INF/lib目錄下:
從spring-framework-3.1.1.RELEASE-with-docs.zip包中複製spring相關的JAR文件(6個)該工程的WEB-INF/lib目錄下:
在文件中增長spring監聽器配置信息,讓spring在tomcat啓動的時候加載:
… <!-- spring監聽器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
<!-- spring監聽器,使用scrope=request 時必須加上 --> <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener> … |
注:若是要使用request or session scope bean,那麼在web.xml裏須要加上下面這段設置:
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
不然就會出現org.springframework.beans.factory.BeanCreationException: Scope 'request' is not active for the current thread
這個時候啓動一下tomcat,會報錯,此時還缺乏spring的配置文件:applicationContext.xml
在WEB-INF目錄下建立文件名:applicationContext.xml,內容以下,先保持空:
<?xmlversion="1.0"encoding="UTF-8"?> <beansxmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
</beans> |
測試重啓tomcat服務,驗證啓動過程沒有異常。
在Java Resources -》src下新建出以下package:
l com.jsdz.action --action
l com.jsdz.dao--數據庫訪問
l com.jsdz.exception--自定義異常
l com.jsdz.interceptor--攔截器
l com.jsdz.model--模型對象
l com.jsdz.service --業務接口
l com.jsdz.service.impl--業務接口實現
l com.jsdz.test --測試目錄
l com.jsdz.util --工具類
l com.jsdz.xml--mybatis映射XML
這裏配置成spring中註解+自動掃描方式,相對XML文件配置簡化得多。
@Repository:DAO層組件,@Service:業務層組件,@Controller:控制層組件
<?xmlversion="1.0"encoding="UTF-8"?> <beansxmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scanbase-package="com.jsdz"use-default-filters="false"> <context:include-filtertype="annotation"expression="org.springframework.stereotype.Controller"/> <context:include-filtertype="annotation"expression="org.springframework.stereotype.Service"/> <context:include-filtertype="annotation"expression="org.springframework.stereotype.Repository"/> </context:component-scan>
</beans> |
經過這部分設置相應幾類組件都自動裝載注入,但依賴於代碼上添加有註解。
修改LoginAction.java代碼,添加註解,使之可以被spring自動建立。
packagecom.jsdz.action;
importorg.springframework.context.annotation.Scope; importorg.springframework.stereotype.Controller; import com.opensymphony.xwork2.ActionSupport;
@Scope("request") @Controller("loginAction") publicclassLoginActionextendsActionSupport {
private String username ;
private String password ;
@Override public String execute() throws Exception {
System.out.println("LoginAction execute invoked!");
if(username.equals("admin") &&password.equals("1234") ) { System.out.println("user ok");
returnSUCCESS; } else { System.out.println("user invalid"); returnINPUT ; } }
public String getUsername() { returnusername; }
publicvoidsetUsername(String username) { this.username = username; }
public String getPassword() { returnpassword; }
publicvoidsetPassword(String password) { this.password = password; } } |
修改struts.xml配置文件,使action的建立託管給spring。
<?xmlversion="1.0"encoding="UTF-8"?> <!DOCTYPEstrutsPUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts> <packagename="emspkg"namespace="/"extends="struts-default">
<actionname="login"class="loginAction"> <resultname="success">/main.jsp</result> <resultname="input">/login.jsp</result> </action>
</package> </struts> |
上面的class取值保持與@Controller("loginAction")括號中的值一致,默認是類名首字母小寫。
到此能夠作兩種測試:
1) 去掉LoginAction.java中的註解,驗證spring是否能建立對象實例;
2) 修改LoginAction.java中註解的命名,驗證login.jsp是否能訪問到對應的action
1. 建立業務組件接口以及兩個實現類:LoginService、LoginServiceImpl,LoginServiceImpl2在action中再也不本身負責邏輯判斷,提交給LoginService來處理業務。這裏建立兩個實現類主要是驗證當有多個實現類時如何選擇注入。
LoginService.java
packagecom.jsdz.service;
import …
@Scope("singleton") @Service ("loginService")
publicinterfaceLoginService {
booleanIsLogin(String userName,StringpassWord ) ; } |
因爲這個業務類中不包含任何成員變量,屬於無狀態類,所以能夠定義建立爲單實例。
LoginServiceImpl.java
packagecom.jsdz.service.impl;
import …
@Scope("singleton") @Service ("loginServiceImpl") publicclassLoginServiceImplimplementsLoginService {
@Override publicbooleanIsLogin(String userName, String passWord) {
System.out.println("LoginServiceImplIsLogin invoked!");
if(userName.equals("admin") &&passWord.equals("1234")) returntrue;
returnfalse; } } |
LoginServiceImpl2.java
packagecom.jsdz.service.impl;
import…
@Scope("singleton") @Service ("loginServiceImpl2") publicclass LoginServiceImpl2 implementsLoginService {
@Override publicbooleanIsLogin(String userName, String passWord) { System.out.println("LoginServiceImpl2 IsLogin invoked!");
if(userName.equals("admin") &&passWord.equals("admin")) returntrue;
returnfalse; } }
|
修改LoginAction.java
packagecom.jsdz.action; …. @Scope("request") @Controller("loginAction") publicclassLoginActionextendsActionSupport {
private String username ;
private String password ;
@Autowired @Qualifier("loginServiceImpl2") privateLoginServiceloginService ;
@Override public String execute() throws Exception {
System.out.println("LoginAction execute invoked!");
//if(username.equals("admin") &&password.equals("1234") ) if(loginService.IsLogin(username, password)) { System.out.println("user ok");
returnSUCCESS; } else { System.out.println("user invalid"); returnINPUT ; } }
publicLoginServicegetLoginService() { returnloginService; }
publicvoidsetLoginService(LoginServiceloginService) { this.loginService = loginService; } …….. } |
@Autowired:自動注入
@Qualifier:多個相同類型時選擇注入哪個。
從mybatis-3.1.1-bundle.zip包中複製mybatis-3.1.1.jar,加lib目錄下6個JAR文件到該工程的WEB-INF/lib目錄下。
(其中commons-logging-1.1.1.jar直接覆蓋現有的)
該插件安裝後能基於數據庫表生成mybatis的相關文件,省下很多手動編碼的功夫。安裝參考說明:http://code.google.com/p/mybatis/wiki/Generator
插件更新地址是:http://mybatis.googlecode.com/svn/sub-projects/generator/trunk/eclipse/UpdateSite/
插件安裝好以後,能在新建項目中找到圖示條目:
這裏使用的是ORACLE數據庫。
--建立數據庫模式 createuser ems identified by"ems"; grant connect to ems; grant resource to ems; grant unlimited tablespace to ems;
--建立表 createtable T_USER ( USERID NUMBER(8) notnull, USERNAME VARCHAR2(30), PASSWORD VARCHAR2(30), STATE NUMBER(3) default 0 ); altertable T_USER addconstraint PK_USER primarykey (USERID);
comment ontable T_USER is'用戶表'; comment oncolumn T_USER.USERID is'用戶標識'; comment oncolumn T_USER.USERNAME is'用戶名'; comment oncolumn T_USER.PASSWORD is'密碼'; comment oncolumn T_USER.STATE is'狀態';
insertintot_user(userid,username,password,state) values(1,'admin','1234',0) ; insertintot_user(userid,username,password,state) values(2,'root','1234',0) ; insertintot_user(userid,username,password,state) values(3,'tom','1',0) ; insertintot_user(userid,username,password,state) values(4,'scott','tiger',0) ; insertintot_user(userid,username,password,state) values(5,'system','manger',0) ; commit; |
<?xmlversion="1.0"encoding="UTF-8"?> <!DOCTYPEgeneratorConfiguration PUBLIC"-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration> <!-- 驅動程序(在classpath中已存在驅動的狀況下不須要) --> <classPathEntrylocation="D:\\ojdbc14.jar"/>
<contextid="context1"targetRuntime="MyBatis3">
<!-- 註釋--> <commentGenerator> <propertyname="suppressAllComments"value="true"/> <propertyname="suppressDate"value="true"/> </commentGenerator>
<!-- 數據庫鏈接 --> <jdbcConnectiondriverClass="oracle.jdbc.driver.OracleDriver" connectionURL="jdbc:oracle:thin:@127.0.0.1 :1521:orcl" userId="ems" password="ems"/>
<!--容許數值類型轉換成不一樣類型,不然都映射爲BigDecimal --> <javaTypeResolver> <propertyname="forceBigDecimals"value="false"/> </javaTypeResolver>
<!-- 模型文件 --> <javaModelGeneratortargetPackage="com.jsdz.model"targetProject="EMS/src"> <propertyname="enableSubPackages"value="false"/> <!-- 當爲true時,產生的代碼文件將按照schema產生子文件夾 --> <propertyname="trimStrings"value="true"/> <!-- set變量時自動剔除空白 --> </javaModelGenerator>
<!-- XML映射文件 --> <sqlMapGeneratortargetPackage="com.jsdz.xml"targetProject="EMS/src"> <propertyname="enableSubPackages"value="false"/> </sqlMapGenerator>
<!-- DAO文件(mapper接口) --> <javaClientGeneratortargetPackage="com.jsdz.dao"targetProject="EMS/src"type="XMLMAPPER"> <propertyname="enableSubPackages"value="false"/> </javaClientGenerator>
<!-- 數據庫表 --> <tableschema="ems"tableName="T_USER"domainObjectName="User"> <propertyname="useActualColumnNames"value="false"/> </table>
</context> </generatorConfiguration> |
在generatorConfig.xml上右鍵菜單,執行」Generate MyBatis/iBATIS Artifacts」項,自動在:xml,domain,dao三個文件夾中生成映射文件、模型pojo、DAO接口類。
複製JDBC驅動 JAR包到工程中,這裏是ORACLEojdbc14.jar
在src根目錄下新建出mybatis-config.xml文件,內容以下:
<?xmlversion="1.0"encoding="UTF-8"?> <!DOCTYPEconfiguration PUBLIC"-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration> <environmentsdefault="development"> <environmentid="development"> <transactionManagertype="JDBC"/> <dataSourcetype="POOLED"> <propertyname="driver"value="oracle.jdbc.driver.OracleDriver"/> <propertyname="url"value="jdbc:oracle:thin:@127.0.0.1 :1521:orcl"/> <propertyname="username"value="ems"/> <propertyname="password"value="ems"/> </dataSource> </environment> </environments>
<mappers> <mapperresource="com/jsdz/xml/UserMapper.xml"/> </mappers>
</configuration> |
以上配置文件中的內容僅用做單獨測試mybatis時使用,到最後與spring整合后里面的內容基本用不上,能夠直接註釋掉。
1) 準備一個工具類:MyBatisUtil.java 。這個文件在官方文檔和各種教程中都有涉及到,主要用做建立session,到最後與spring整合後基本用不上。
MyBatisUtil.java
packagecom.jsdz.util;
importjava.io.IOException; importjava.io.Reader;
importorg.apache.ibatis.io.Resources; importorg.apache.ibatis.session.SqlSessionFactory; importorg.apache.ibatis.session.SqlSessionFactoryBuilder;
publicclassMyBatisUtil {
privatefinalstaticSqlSessionFactorysqlSessionFactory ;
static { String resouce = "mybatis-config.xml";
Reader reader = null;
try { reader = Resources.getResourceAsReader(resouce);
} catch (IOException e) { System.out.println(e.getMessage()); }
sqlSessionFactory = newSqlSessionFactoryBuilder().build(reader); }
publicstaticSqlSessionFactorygetSqlSessionFactory() { returnsqlSessionFactory ; } } |
2) 準備兩個測試樁文件,一個爲主測試類Test.java,調各個具體的測試類,從此能夠複用,另一個面向UserMapper類的測試。
TestMapperUser.java
packagecom.jsdz.test;
import …
publicclassTestMapperUser { staticSqlSessionFactorysqlSessionFactory = null ;
static { sqlSessionFactory = MyBatisUtil.getSqlSessionFactory(); }
voidtestQueryByUserNameAndPassword() {
SqlSessionsqlSession = sqlSessionFactory.openSession();
try{ UserMapper mapper = sqlSession.getMapper(UserMapper.class) ; UserExample example = newUserExample();
example.clear(); example.or().andUsernameEqualTo("admin").andPasswordEqualTo("1234") ; List<User>lst = mapper.selectByExample(example) ;
System.out.println("query item count:" + lst.size() ); for(User user:lst) { System.out.println(user.getUserid() + "," + user.getUsername() + "," + user.getPassword() ) ; } }finally{ sqlSession.close(); } } // end of testQueryByCondition } |
Test.java
packagecom.jsdz.test; import …
publicclass Test { publicstaticvoid main(String[] args) { TestMapperUsertestMapperUser = newTestMapperUser(); testMapperUser.testQueryByUserNameAndPassword();
System.exit(0); } } |
3) 以Application方式運行Test.java文件,輸出:
log4j:WARN No appenders could be found for logger (org.apache.ibatis.logging.LogFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
query item count:1
1,admin,1234
說明能夠查詢到記錄。
日誌中提示log4j的告警,解決方法:
在src目錄下建立文件:log4j.properties,內容以下
# Rules reminder: # DEBUG < INFO < WARN < ERROR < FATAL
# Global logging configuration log4j.rootLogger=INFO,stdout
# My logging configuration... log4j.logger.java.sql=DEBUG log4j.logger.org.apache.mybatis=DEBUG
## Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p%d%C:%m%n |
以上設置sql輸出和mybatis級別DEBUG模式,保證了日誌中能打印出mybatis執行的SQL語句,方便跟蹤。
目標:
l 由 spring來建立session,避免過多的session建立、銷燬代碼編寫;
l 由spring來管理事務
l 將mapper接口的實例化建立交由spring管理
1) 安裝整合插件:從mybatis-spring-1.1.1-bundle.zip包中複製包到WEB-INF/lib目錄下:
主JAR包是mybatis-spring-1.1.1.jar
lib子目錄下依賴包也一併拷貝進去,Spring的包在前面過程當中已導入了一部分,這裏重複的部分剔除掉。
2) 複製數據庫鏈接池相關的JAR包到WEB-INF/lib目錄下:
這兩個包能夠從apache的官方網站上找到。
3) 修改spring的配置文件:applicationContext.xml,把下面的內容增長上去:
…. <!-- 定義數據源鏈接 --> <beanid="dataSource"class="org.apache.commons.dbcp.BasicDataSource"> <propertyname="driverClassName"value="oracle.jdbc.OracleDriver"/> <propertyname="url"value="jdbc:oracle:thin:@127.0.0.1 :1521:orcl"/> <propertyname="username"value="busimon"/> <propertyname="password"value="busimon"/> <propertyname="maxActive"value="100"/> <propertyname="maxIdle"value="30"/> <propertyname="maxWait"value="500"/> <propertyname="defaultAutoCommit"value="true"/> </bean>
<!-- 定義全局的事務控制 --> <beanid="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <propertyname="dataSource"ref="dataSource"/> </bean>
<!-- 開啓註解方式聲明事務 --> <tx:annotation-driven/>
<!-- 定義SqlSessionFactory --> <beanid="sqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean"> <propertyname="dataSource"ref="dataSource"/> <propertyname="mapperLocations"value="classpath*:com/jsdz/xml/*.xml"/> <propertyname="typeAliasesPackage"value="com.mybatis.model"/> </bean>
<!-- 自動掃描mapper,容許自動注入(根據類型匹配),不須要逐個配置mapper --> <beanclass="org.mybatis.spring.mapper.MapperScannerConfigurer"> <propertyname="basePackage"value="com.jsdz.dao"/> </bean>
…. |
此時重啓tomcat服務驗證能正確啓動起來。
因爲已託管給spring來處理,mybatis-config.xml文件中的內容已經能夠註釋掉,僅保留頭部便可。
<?xmlversion="1.0"encoding="UTF-8"?> <!DOCTYPEconfiguration PUBLIC"-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration> <!-- <environments default="development"> --> <!-- <environment id="development"> --> <!-- <transactionManager type="JDBC" /> --> <!-- <dataSource type="POOLED"> --> <!-- <property name="driver" value="oracle.jdbc.driver.OracleDriver" /> --> <!-- <property name="url" value="jdbc:oracle:thin:@127.0.0.1 :1521:orcl" /> --> <!-- <property name="username" value="ems" /> --> <!-- <property name="password" value="ems" /> --> <!-- </dataSource> --> <!-- </environment> --> <!-- </environments> -->
<!-- <mappers> --> <!-- <mapper resource="com/jsdz/xml/UserMapper.xml" /> --> <!-- </mappers> -->
</configuration> |
到此,struts2、spring、MyBatis的整合宣告成功!
1) 複製jquery-1.7.2.js文件到WebContent目錄下,並更名爲:jquery.js;
2) 編寫測試JSP文件:
<!DOCTYPEhtmlPUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <metahttp-equiv="Content-Type"content="text/html; charset=UTF-8"> <title>JQuery測試</title>
<scripttype="text/javascript"src="jquery.js"></script> <scripttype="text/javascript"> $(document).ready(function() { $("p").click(function() { $(this).hide(); }); }); </script>
</head>
<body> <p>點擊我自動消失.</p>
</body> </html> |
3)啓動服務,測試URL:http://localhost:8080/ems/testjq.html
1) 從struts2壓縮包中複製struts2-json-plugin-2.3.3.jar插件包到WEB-INF 的lib目錄下;
2) 編寫一個測試返回JSON消息的ACTION:
GetJsonUserAction.java
packagecom.jsdz.action;
import org.apache.struts2.json.annotations.JSON; importorg.springframework.context.annotation.Scope; importorg.springframework.stereotype.Controller;
importcom.jsdz.model.User; import com.opensymphony.xwork2.ActionSupport;
@Scope("request") @Controller("getJsonUserAction") @SuppressWarnings("serial") publicclassGetJsonUserActionextendsActionSupport {
private String username; // 入參
private User user; // 返回客戶端
@Override public String execute() throws Exception {
this.user = new User();
if (username.equals("jack")) { this.user.setUserid(101); this.user.setUsername(username); this.user.setPassword("world"); this.user.setState((short) 0); } else { this.user.setUserid(100); this.user.setUsername(username); this.user.setPassword("hello"); this.user.setState((short) 1); } returnSUCCESS; }
@JSON (name = "USER") public User getUser() { returnuser; }
publicvoidsetUser(User user) { this.user = user; }
public String getUsername() { returnusername; }
publicvoidsetUsername(String username) { this.username = username; } } |
struts.xml文件修改:
<packagename="emspkg"namespace=""extends="json-default">
<actionname="getJsonUser"class="getJsonUserAction"> <resulttype="json"> <paramname="excludeProperties">username</param> </result> </action>
|
jsonuser.jsp
<%@pagelanguage="java"contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%> <!DOCTYPEhtmlPUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <metahttp-equiv="Content-Type"content="text/html; charset=UTF-8"> <title>json user</title>
<scripttype="text/javascript"src="jquery.js"></script> <scripttype="text/javascript">
functiongetUser() { $.post("getJsonUser", { username: $("#username").val() } , function( returnedData,status) { varuserid = returnedData.USER.userid; var username = returnedData.USER.username; var password = returnedData.USER.password; var state = returnedData.USER.state;
var result = "<table border='1'><tr><th>userid</th><th>username</th><th>password</th><th>state</th></tr>" + "<tr><td>"+ userid +"</td><td>"+ username +"</td><td>"+ password +"</td><td>"+ state +"</td></tr></table>" ;
$("#gsonDIV").html(result) ; } ); }
</script>
</head> <body>
<selectid="username"> <optionvalue="tom">tom</option> <optionvalue="jack">jack</option> </select>
<inputtype="button"onclick="getUser()"value="click to get user info"></input>
<divid="gsonDIV"></div>
</body> </html> |
測試JSP調用。
3) 編寫一個返回son對象列表的ACTION:
從google code上下載gson包到WEB-INF/lib目錄下:gson-2.1.jar
編寫ACTION:
GetJsonUserListAction.java
packagecom.jsdz.action;
importjava.util.ArrayList; importjava.util.List;
importorg.springframework.context.annotation.Scope; importorg.springframework.stereotype.Controller;
importcom.google.gson.Gson; importcom.jsdz.model.User; import com.opensymphony.xwork2.ActionSupport;
@Controller("getJsonUserListAction") @Scope("request")
publicclassGetJsonUserListActionextendsActionSupport {
/* 用於存放JSON生成後的字符串結果 */ private String jsonResult ;
@Override public String execute() throws Exception {
List<User>userList = newArrayList<User>();
User user = new User(); user.setUserid(1); user.setUsername("ZHANG"); user.setPassword("1"); user.setState((short)0); userList.add(user);
user = null ; user = new User(); user.setUserid(2); user.setUsername("Lee"); user.setPassword("12"); user.setState((short)0); userList.add(user);
Gsongson = newGson();
java.lang.reflect.Type type = newcom.google.gson.reflect.TypeToken<List<User>>() {}.getType(); String jsonStr = gson.toJson(userList,type) ;
System.out.println("jsonStr=" +jsonStr );
this.jsonResult= jsonStr ;
returnSUCCESS ; }
publicStringgetJsonResult() { returnjsonResult; }
publicvoidsetJsonResult(String jsonResult) { this.jsonResult = jsonResult; } } |
修改stucts.xml
<actionname="getJsonUserList"class="getJsonUserListAction"> <resulttype="json"></result> </action>
|
增長測試JSP文件:
<%@pagelanguage="java"contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%> <!DOCTYPEhtmlPUBLIC"-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <metahttp-equiv="Content-Type"content="text/html; charset=UTF-8"> <title>json user list</title>
<scripttype="text/javascript"src="jquery.js"></script> <scripttype="text/javascript">
functiongetUser() { $.post("getJsonUserList", { } , function(returnedData,status) {
var result = "<table border='1'><tr><th>userid</th><th>username</th><th>password</th><th>state</th></tr>" ;
varuserList = eval('(' + returnedData.jsonResult + ")") ;
for(vari=0; i<userList.length;i++) { varuserid = userList[i].userid; var username = userList[i].username; var password = userList[i].password; var state = userList[i].state;
result = result+ "<tr><td>"+ userid +"</td><td>"+ username +"</td><td>"+ password +"</td><td>"+ state +"</td></tr>" ; } result = result + "</table>" ;
$("#gsonDIV").html(result) ; } ); } </script>
</head> <body> <inputtype="button"onclick="getUser()"value="click to get user info"></input> <divid="gsonDIV"></div> </body> </html> |