<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-4  評論-14  文章-0  trackbacks-0
     

    一、新建項目
    先在eclipse中新建一個maven項目,如下圖:

    填寫id、version等,點finish。項目就建好了。下面是項目建好之后的樣子:

    二、配置環(huán)境

    1、添加依賴包

    選中項目,右鍵——Maven2——Add Dependency,如下圖:

    打開添加依賴包界面后添加包:struts2.0.11、spring2.0.6、hibernate-annotations3.2、hibernate-entitymanager3.2、hibernate3.2、servlet2.4、javax-persistence、mysql-connector-java5.0.4、spring-aop2.0.6、aspectjweaver1.5.3、struts2-spring-plugin2.0.11、junit、spring-mock2.0.6。

    2、配置web.xml文件

    在WEB-INF下新建文件web.xml
    輸入如下內(nèi)容:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app id="WebApp_9" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>Struts 2</display-name>
    <filter>
    <filter-name>struts2</filter-name>
    <filter-class>
    org.apache.struts2.dispatcher.FilterDispatcher
    </filter-class>
    </filter>
    <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
    </filter-mapping>
    <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    </welcome-file-list>
    </web-app>

    用過struts1.x的人會發(fā)現(xiàn)這里沒有了servlet,而是一個filter,是的,這是struts2和struts1的一個不同之處。

    在src/main/resource下新建文件struts.xml,這里是和struts1.x不一樣的地方。
    輸入如下內(nèi)容:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
    <struts>
    <constant name="struts.devMode" value="true" />
    <package name="Struts2_MESSAGE" extends="struts-default"
    namespace="/message">
    </package>
    </struts>

    簡單解釋一下,constant的作用是自定義一些struts2的屬性,在struts2的包里帶了一個struts.properties文件,里邊設(shè)定了很多默認的struts2的運行參數(shù),但是這些有時候是需要改變一下的,因此就提供了constant來覆蓋struts.properties中屬性。而package的作用可以簡單的看做把應(yīng)用分模塊。package有個屬性叫namespace,上面我們配置為/message,假設(shè)這個package中還有一個名叫hello的action,那么我們訪問這個action的url就是:http://域名/message.hello.action。

    本文的示例程序是一個簡單的留言添刪改查,所以取名叫message。

    3、配置spring

    在WEB-INF下新建文件applicationContext.xml,輸入如下內(nèi)容:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
    </beans>

    在web.xml文件中加入如下內(nèi)容:

    <listener>
    <listener-class>
    org.springframework.web.context.ContextLoaderListener
    </listener-class>
    </listener>

     用過spring的人應(yīng)該知道這個listener的作用是啟動spring容器。

    4、配置jpa和spring的jpa支持

    在src/main/resource下新建文件夾META-INF,然后在這個文件夾中新建文件persistence.xml,輸入如下內(nèi)容:

    <?xml version="1.0" encoding="utf-8"?>
    <persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
    version="1.0">
    <persistence-unit name="app-unit"
    transaction-type="RESOURCE_LOCAL">
    </persistence-unit>
    </persistence>

    可能有人會發(fā)現(xiàn),怎么jpa的配置文件只有這么點了,這其實是因為我們用的spring的jpa支持,數(shù)據(jù)庫配置信息都放到spring的配置文件里了,后面就會看到。

    然后打開前面新建的文件applicationContext.xml,在beans節(jié)點內(nèi)添加如下內(nèi)容:

    <bean
    class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
    <bean id="transactionManager"
    class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory"
    ref="entityManagerFactory" />
    </bean>
    <bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url"
    value="jdbc:mysql://localhost/message?createDatabaseIfNotExist=true" />
    <property name="username" value="root" />
    <property name="password" value="123" />
    </bean>
    <bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="jpaVendorAdapter">
    <bean
    class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    <property name="database" value="MYSQL" />
    <property name="generateDdl" value="false" />
    <property name="showSql" value="true" />
    </bean>
    </property>
    </bean>

    看,數(shù)據(jù)庫配置信息出現(xiàn)了

    這里的username和password需要根據(jù)你的實際情況修改。

    5、集成struts2和spring

    打開struts.xml文件,添加如下內(nèi)容:

    <constant name="struts.objectFactory" value="spring" />
    <constant name="struts.objectFactory.spring.autoWire" value="type" />

     到這里,配置基本完成。

    三、新建域模型

    我們先創(chuàng)建一個域模型Message,包括name、title、ip、content、inputTime等字段,代碼如下:

    package com.struts.sample.domain;
    import java.util.Date;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    @Entity
    public class Message {
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    private Long id;
    private String name;
    private String title;
    private String ip;
    private String content;
    private Date inputTime;
    getter and setter...
    }

    @Entity是jpa的注解,表示這個類與一個表對應(yīng),如果沒有知名表明,那么就和message這個表對應(yīng),系統(tǒng)啟動是jpa會自動創(chuàng)建這個表。
    @Id也是jpa注解,標識這個字段是主鍵。
    @GeneratedValue(strategy = GenerationType.TABLE)是指定一個主鍵生成策略。

    四、Service層的實現(xiàn)

    接口就不帖出來了,直接把實現(xiàn)類寫出來。

    package com.struts.sample.service;
    import java.util.List;
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    import javax.persistence.Query;
    import com.struts.sample.domain.Message;
    public class MessageServiceImpl implements MessageService {
    @PersistenceContext EntityManager em;
    public void setEm(EntityManager em) {
    this.em = em;
    }
    public List<Message> find(final String queryString, final int rowStartIdx, final int rowCount,
    final Object... values){
    Query query = em.createQuery(queryString);
    if (values != null)
    for (int i = 0; i < values.length; i++)
    query.setParameter(i + 1, values[i]);
    if(rowStartIdx>0){
    query.setFirstResult(rowCount);
    }
    if(rowCount>0){
    query.setMaxResults(rowCount);
    }
    return query.getResultList();
    }
    public void save(Message msg){
    this.em.persist(msg);
    }
    public void del(Long id){
    this.em.remove(this.get(id));
    }
    public Message get(Long id){
    return this.em.find(Message.class, id);
    }
    public void update(Message msg){
    this.em.merge(msg);
    }
    public Message getBy(String field, Object value) {
    String queryString = "select msg from Message msg where msg."+field+"=:value";
    Query query = this.em.createQuery(queryString).setParameter("value", value);
    List<Message> msgs = query.getResultList();
    if(msgs.size()>1){
    throw new java.lang.IllegalStateException(
    "worning  --more than one object find!!");
    }else if(msgs.size()==1){
    return msgs.get(0);
    }else{
    return null;
    }
    }
    }

    注意這一句@PersistenceContext EntityManager em;容器啟動的時候會去創(chuàng)建messageService,創(chuàng)建的時候會發(fā)現(xiàn)這個注解:@PersistenceContext,然后容器會把EntityManager注入到這里。
    接下來我們需要讓spring知道我們有這樣一個bean需要它來加載。打開配置文件applicationContext.xml,加上如下內(nèi)容:

    <bean id="messageService" class="com.struts.sample.service.MessageServiceImpl" />

    現(xiàn)在我們來寫測試用例,spring為我們測試jpa提供了一個基類:org.springframework.test.jpa.AbstractJpaTests。
    首先,我們在src/test/resource目錄下新建一個文件applicationContext.xml,內(nèi)容與src/main/resource/applicationContext.xml的內(nèi)容一樣。
    接下來我們寫一個測試用例AbstractJpaTests ,代碼如下:

    package com.struts.sample.service;
    import java.util.Date;
    import org.springframework.test.jpa.AbstractJpaTests;
    import com.struts.sample.domain.Message;
    public class MessageServiceImplTest extends AbstractJpaTests {
    @Override
    protected String[] getConfigLocations() {
    return new String[]{"classpath:applicationContext.xml"};
    }
    private MessageService service;
    public void setService(MessageService service) {
    this.service = service;
    }
    public void testSave(){
    Message msg = new Message();
    msg.setContent("xxxxxxxxxxxxxxxxx");
    msg.setName("tianyi");
    msg.setInputTime(new Date());
    msg.setTitle("www.easyjf.com");
    msg.setIp("123.123.132.123");
    service.save(msg);
    assertNotNull(msg.getId());
    Message msg2 = service.getBy("name", "tianyi");
    assertNotNull(msg);
    }
    }

    運行這個測試程序,當你看到綠色的條條,說明你測試成功了。

    五、Action層的實現(xiàn)

    Service層已經(jīng)實現(xiàn)并測試通過,接下來我們該寫Action了。Struts2支持POJO的action,不需要繼承或者實現(xiàn)任何類或者接口,可以很方便的測試。這個例子中我們就采用POJO式的action。代碼如下:

    package com.struts.sample.action;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import com.struts.sample.domain.Message;
    import com.struts.sample.service.MessageService;
    public class MessageAction {
    private Message message;
    private Long id;
    private MessageService service;
    private List<Message> msgs = new ArrayList<Message>();
    private Integer pages = 0;
    private Integer pageSize = 0;
    public List<Message> getMsgs() {
    return msgs;
    }
    public void setMsgs(List<Message> msgs) {
    this.msgs = msgs;
    }
    public Long getId() {
    return id;
    }
    public void setId(Long id) {
    this.id = id;
    }
    public Integer getPages() {
    return pages;
    }
    public void setPages(Integer pages) {
    this.pages = pages;
    }
    public Integer getPageSize() {
    return pageSize;
    }
    public void setPageSize(Integer pageSize) {
    this.pageSize = pageSize;
    }
    public Message getMessage() {
    return message;
    }
    public void setMessage(Message message) {
    this.message = message;
    }
    public String List(){
    this.msgs = this.service.find("select msg from Message msg", pages, pageSize, null);
    return "success";
    }
    public String Save(){
    message.setInputTime(new Date());
    if(message.getId()!=null){
    this.service.update(message);
    }else{
    this.service.save(message);
    }
    return this.List();
    }
    public String Del(){
    if(id==null){
    return "error";
    }else{
    this.service.del(id);
    }
    return this.List();
    }
    public String Edit(){
    if(id==null){
    return "error";
    }else{
    this.message = this.service.get(id);
    }
    return "success";
    }
    public void setService(MessageService service) {
    this.service = service;
    }
    }

    代碼很簡單,但是卻實現(xiàn)了添刪改查的功能,struts2確實比struts1好用多了。Struts2中可以將一個POJO作為action,就像上面的action。在用戶訪問到這個action的時候struts2會根據(jù)前臺提交進來的數(shù)據(jù)自動將必要的字段進行注入。
    以save為例,當我們訪問到這個方法的時候,前臺表單域會有message.title、message.name、message.content等變量,struts2會根據(jù)這些前臺變量的名字將他們注入到MessageAction中的message中。而如果我們是執(zhí)行的修改操作,那么前臺還會傳遞一個id到服務(wù)端,struts2又會自動將這個值注入到id中。
    需要注意的是,如果你希望某個字段被注入,那么你應(yīng)該提供一個setter,如果你同時希望這個字段能在頁面中被訪問,那么你還應(yīng)該為它提供一個getter。

    接下來我們來配置struts2,前面我們只是將struts2運行所需的環(huán)境配置起來了,現(xiàn)在我們需要配置新添加的Action。
    打開struts.xml文件,在package節(jié)點中添加如下內(nèi)容:

    <action name="message_*" class="com.struts.sample.action.MessageAction" method="{1}">
    <result>List.jsp</result>
    </action>

    這個配置文件大家可能有點不明白,怎么還有“*”、“{1}”這種東西。現(xiàn)在我簡單解釋一下。struts2的action配置中支持通配符,message_*大家應(yīng)該能明白,“*”就代表任意的東西,訪問的時候可以用message_aaa、message_bbb等,這些請求都會被交給MessageAction來處理,但是會不會有正確的結(jié)果還要看后面的method="{1}"這個東西。method屬性使得一個action中的一個方法就可以處理一個請求,這意味著我們不需要寫大量的action,而可以把一些相關(guān)的處理放到一個action中。現(xiàn)在我們來說說這個“{1}”,實際上“{1}”是代表前面name中的通配符的位置,struts會將第一個“*”代表的那一串字符串截取下來,作為method的值。在這個例子中,假設(shè)我們用message_aaa.action來訪問的話,那么struts會調(diào)用MessageAction的aaa方法。struts2的這種通配符可以支持多個,如果有兩個,那么"{1}"就代表第一個"*"所匹配的字符串,"{2}"就代表第二個"*"匹配的字符串,以此類推。

    后臺的東西到這里就差不多了,剩下的就是頁面了。

    六、頁面

    是一個很簡單的示例,只有一個個頁面。在webapp目錄下新建目錄message,在message目錄下新建文件List.jsp,輸入如下內(nèi)容:

    <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
    <%@ taglib prefix="s" uri="/struts-tags" %>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>message</title>
    </head>
    <body>
    <s:iterator value="msgs">
    <table style="border:1px solid #cccccc; margin-top:10px;" width="700">
    <tr>
    <td>標題:<s:property value="title" /></td>
    <td>發(fā)表時間:<s:property value="inputTime" /></td>
    </tr>
    <tr>
    <td colspan="2" height="100" style="padding:10px;">留言內(nèi)容:
    <div style="border:1px dotted #dddddd">
    <p>  <s:property value="content" /></p>
    </div></td>
    </tr>
    <tr>
    <td>作者:<s:property value="name" /></td>
    <td>操作:<a href='<s:url action="message_Edit">
    <s:param name="id" value="id" /></s:url>'>Edit</a>
    <a href='<s:url action="message_Del">
    <s:param name="id" value="id" /></s:url>'>
    Delete
    </a></td>
    </tr>
    </table>
    <hl/>
    </s:iterator>
    <s:form action="message_Save" >
    <s:hidden name="message.id" />
    <s:textfield name="message.title" label="標題" />
    <s:textarea name="message.content" label="內(nèi)容" />
    <s:textfield name="message.name" label="作者" />
    <s:submit label="提交" />
    </s:form>
    </body>
    </html>

    到這里基本完工了,我們運行一下,看看結(jié)果。
    打開瀏覽器輸入http://localhost:8080/message/message_List.action,居然是錯誤界面,錯誤信息如下:

    這是為什么呢,原來我們沒有為service配置事務(wù)。打開applicationContext.xml,添加如下內(nèi)容:

    <aop:config>
    <aop:advisor
    pointcut="execution(* com.struts.sample.service.*.*(..))"
    advice-ref="txAdvice" />
    </aop:config>
    <tx:advice id="txAdvice">
    <tx:attributes>
    <tx:method name="insert*" />
    <tx:method name="update*" />
    <tx:method name="*" propagation="REQUIRED"/>
    </tx:attributes>
    </tx:advice>

    運行試試,應(yīng)該沒有問題了吧!運行界面如下:

     

     們添加一條記錄看看,我隨便填了一條,點submit:

    這里,我們的第一個示例就宣告完成了,如果有什么錯誤,還請大家指正。

    源碼下載:struts-sample.rar

    本文為原創(chuàng),同時在easyjf官方博客發(fā)表:http://www.easyjf.com/blog/html/20080402/1474562.html。歡迎轉(zhuǎn)載,轉(zhuǎn)載請保留出處。

    posted on 2008-04-02 10:44 天 一 閱讀(3142) 評論(6)  編輯  收藏

    評論:
    # re: 基于Struts2+Spring+JPA的添刪改查示例[未登錄] 2008-04-02 12:31 | allenny
    沒有DAO嗎?  回復(fù)  更多評論
      
    # re: 基于Struts2+Spring+JPA的添刪改查示例 2008-04-02 13:12 | 天 一
    簡單的應(yīng)用,就省了。  回復(fù)  更多評論
      
    # re: 基于Struts2+Spring+JPA的添刪改查示例 2008-04-02 14:28 | super2
    一般就是這樣用的  回復(fù)  更多評論
      
    # re: 基于Struts2+Spring+JPA的添刪改查示例 2008-04-05 10:01 | 王能
    http://www.bt285.cn
    BT285.cn 我這個BT網(wǎng)站也是用這個技術(shù)的說.  回復(fù)  更多評論
      
    # re: 基于Struts2+Spring+JPA的添刪改查示例 2008-04-08 14:35 | dna
    我部署了一下,連續(xù)刪除會出現(xiàn)錯誤,
    增加留言時第一次是增加,后面幾次就成了編輯,
    不知道是什么原因  回復(fù)  更多評論
      
    # re: 基于Struts2+Spring+JPA的添刪改查示例[未登錄] 2008-04-08 14:40 | 天一
    可能是會有問題,我沒有做很多測試,畢竟只是一個簡單的示例,呵呵!  回復(fù)  更多評論
      

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
    博客園   IT新聞   Chat2DB   C++博客   博問  
     
    主站蜘蛛池模板: 无码永久免费AV网站| 亚洲日本va在线视频观看| 亚洲精品456播放| 亚洲Av无码专区国产乱码DVD| 免费播放美女一级毛片| 久久国产精品免费专区| 免费国产高清视频| 国产精品手机在线亚洲| 日韩亚洲国产综合久久久| 91亚洲视频在线观看| 成人影片一区免费观看| 国产一级淫片免费播放| 456亚洲人成在线播放网站| 国内精品免费在线观看| 久久国产精品亚洲综合| 30岁的女人韩剧免费观看| 亚洲色WWW成人永久网址| 国产真人无码作爱免费视频| 国产公开免费人成视频| 全部一级一级毛片免费看| 午夜成年女人毛片免费观看| 亚洲精品少妇30p| 日韩精品人妻系列无码专区免费| 亚洲伊人久久大香线蕉影院| 四色在线精品免费观看| 一级毛片免费在线播放| 香蕉视频在线观看亚洲| 免费观看成人毛片a片2008| 国产精品亚洲专区无码唯爱网| 无码人妻久久一区二区三区免费丨| 亚洲一区精彩视频| 免费大黄网站在线观看| 黄网站色视频免费在线观看的a站最新 | 亚洲av无码专区在线观看素人| 国产大片免费天天看| 亚洲第一二三四区| 亚洲成人免费在线观看| 亚洲AV无码一区二区三区鸳鸯影院| 国产a v无码专区亚洲av| 亚洲网站免费观看| 黄页网址大全免费观看12网站|