Статьи

Разработка приложения для персональной мини-фотогалереи с использованием Struts2, Hibernate и MySQL BLOB — часть 1

Обзор:

На этом семинаре мы разработаем веб-приложение, которое можно использовать для создания красивой фотогалереи. Это вы можете разместить на веб-сервере или использовать на своем ПК для поддержки и управления вашей коллекцией фотографий. Используя это руководство, вы сможете изучить следующие важные моменты, связанные со Struts2 и Hibernate:

  • Как интегрировать инфраструктуру Struts2 с Hibernate
  • Как загрузить фото или файл в Struts2
  • Как динамически загружать / скачивать фотографии в поле MySQL BLOB и из него
  • Как динамически передавать параметры из одного действия в другое в Struts2

В первой части этого руководства мы разработаем панель администратора. Панель администратора будет использоваться для создания фотоальбома и загрузки фотографий в альбом. Во второй части мы создадим главное веб-приложение внешнего интерфейса, которое будет отображать фотографии по альбомам, добавленным в панель администратора.

Используемые инструменты:

  1. Eclipse Indigo Java EE IDE для веб-разработчиков
  2. Struts 2
  3. Hibernate 3
  4. Hibernate Tools Eclipse Plugin Версия 3.5.1
  5. jar-файл JDBC для mysql (mysql-connector-java-5.1.23)
  6. Tomcat 7

Шаг 1: Подготовка базы данных MySQL для приложения Фотогалерея

Мы будем использовать базу данных MySQL. Belw — это скрипт для создания таблиц базы данных. Используемое имя базы данных — «tctalk_apps_photoalbum». Однако вы можете создать любое имя базы данных. Просто помните, что вам нужно изменить имя базы данных в файле конфигурации Hibernate. Ниже приведены SQL-коды для двух таблиц album и phototbl.

1
2
3
4
5
6
7
CREATE TABLE IF NOT EXISTS `album` (
  `albumid` INT(4) NOT NULL AUTO_INCREMENT,
  `albumname` VARCHAR(55) NOT NULL,
  `albumdesc` text NOT NULL,
  `albumcreatedate` DATE NOT NULL,
  PRIMARY KEY (`albumid`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;
01
02
03
04
05
06
07
08
09
10
CREATE TABLE IF NOT EXISTS `phototbl` (
  `photoid` INT(4) NOT NULL AUTO_INCREMENT,
  `albumid` INT(4) NOT NULL,
  `phototitle` VARCHAR(255) NOT NULL,
  `photoname` VARCHAR(255) NOT NULL,
  `imgcontenttype` VARCHAR(255) NOT NULL,
  `photocreatedate` datetime NOT NULL,
  `photodata` longblob NOT NULL,
  PRIMARY KEY (`photoid`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

Шаг 2: Создайте пакеты в исходном коде Java

Создайте пакеты на стороне java src после создания динамического веб-проекта в Eclipse. Помните, что пакеты com.tctalk.apps.album.db.xxx содержат все java и другие файлы для работы на стороне базы данных / гибернации, тогда как com.tctalk.apps.album.web.xxx будет иметь все java-файлы для уровня представления с использованием struts2 фреймворк.

image001

Бизнес-объекты будут иметь все классы BO, сопоставленные с таблицами. У Дао будут классы DAO для вызова базы данных с использованием Hibernate. Hbm будет иметь файлы * .hbm.xml, в которых есть отображение полей таблицы и таблицы java. У Utils будут все виды классов Utility. Действия будут иметь все классы действий инфраструктуры Struts2. Делегаты будут иметь классы делегатов в качестве моста между уровнем пользовательского интерфейса и уровнем базы данных. Формы будут иметь POJO (простые старые объекты Java), соответствующие полям пользовательского интерфейса. Hibernate.cfg.xml содержит файл конфигурации hibernate, в котором содержится информация о подключении к базе данных для подключения к базе данных. Struts.xml содержит данные конфигурации Struts.

Шаг 3: Скопируйте файлы JAR в папку lib

image003

Вам потребуется файл servlet-api.jar, который вы получите из установочного каталога Tomcat. Мой Tomcat находится в папке C: \ Java \ Tomcat \ tomcat7.

Шаг 4. Добавьте поддержку Struts 2 в наше приложение

У нас уже есть необходимые jar-файлы для поддержки Struts2 в нашем приложении. Теперь пришло время включить Struts2.xml и поместить ссылку в web.xml, чтобы сообщить об этом Tomcat.

web.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<display-name>PersonalPhotoAlbumApp</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
 <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>*.action</url-pattern>
</filter-mapping>
</web-app>

Struts.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
 
<struts>
 
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    <constant name="struts.devMode" value="false" />
 
    <package name="default" extends="struts-default" namespace="/">
 
    <result-types>
        <result-type name="imageResult" class="com.tctalk.apps.album.web.actions.CustomPhotoResult" />
    </result-types>
 
    <default-action-ref name="index" />
 
    <action name="index">
        <result>index.jsp</result>
    </action>
 
    <action name="admin">
        <result name="success" type="redirectAction">listAlbumAdmn</result>
    </action>
 
    <action name="listAlbumAdmn"
        class="com.tctalk.apps.album.web.actions.PhotoAlbumAdminAction" method="getAllAlbumList" >
        <result name="success">/WEB-INF/admin/jsp/showalbums.jsp</result>
    </action>
 
    <action name="addAlbumAdmn"
        class ="com.tctalk.apps.album.web.actions.PhotoAlbumAdminAction" method="addAlbumToCollection" >
        <result name="input">listAlbumAdmn</result>
        <result name="success" type="redirectAction">listAlbumAdmn</result>
    </action>
 
    <action name="delAlbumAdmn"
        class ="com.tctalk.apps.album.web.actions.PhotoAlbumAdminAction" method="delAlbumFromCollection" >
        <result name="success" type="redirectAction">listAlbumAdmn</result>
    </action>
 
    <action name="listPhotosByAlbumAdmn"
        class="com.tctalk.apps.album.web.actions.PhotoAlbumAdminAction" method="listAllPhotos" >
        <result name="success">/WEB-INF/admin/jsp/showphotos.jsp</result>
    </action>
 
    <action name="addPhotoAcion"
        class ="com.tctalk.apps.album.web.actions.PhotoAlbumAdminAction" method="uploadPhotoToAlbum" >
            <interceptor-ref name="exception"/>
            <interceptor-ref name="i18n"/>
            <interceptor-ref name="fileUpload">
                <param name="allowedTypes">image/x-png,image/png,image/gif,image/jpeg,image/pjpeg</param>
            </interceptor-ref>
            <interceptor-ref name="params">
                <param name="excludeParams">dojo\..*,^struts\..*</param>
            </interceptor-ref>
            <interceptor-ref name="validation">
                <param name="excludeMethods">input,back,cancel,browse</param>
            </interceptor-ref>
            <interceptor-ref name="workflow">
                <param name="excludeMethods">input,back,cancel,browse</param>
            </interceptor-ref>
 
        <result name="success" type="redirectAction">
            <param name="actionName">listPhotosByAlbumAdmn</param>
            <param name="albumid">${albumid}</param>
        </result>
 
        <result name="input">/WEB-INF/admin/jsp/showphotos.jsp</result>
    </action>
 
    <action name="delPhotoFrmAlbumAdmn"
        class ="com.tctalk.apps.album.web.actions.PhotoAlbumAdminAction" method="delPhoto" >
        <result name="success" type="redirectAction">
            <param name="actionName">listPhotosByAlbumAdmn</param>
            <param name="albumid">${albumid}</param>
        </result>
    </action>
 
    <action name="showPhotoAction" 
        class="com.tctalk.apps.album.web.actions.PhotoAlbumAdminAction" method="showPhoto">
        <result name="success" type="imageResult"/>
    </action>
 
 </package>
 
</struts>

Шаг 5. Добавьте поддержку Hibernate в наше приложение для фотоальбома.

Для работы с hibernate у нас уже есть хорошее пошаговое руководство, которое показывает, как вы можете использовать плагин Hibernate в Eclipse для автоматической генерации coresponds файлов hbm и java для таблиц в вашей базе данных. Проверьте учебник — http://www.techcubetalk.com/2013/04/step-by-step-auto-code-generation-for-pojo-domain-java-classes-and-hbm-files-using-elipse- зимуют-плагин /

  1. Создайте файл hibernate.cfg.xml с информацией о подключении к базе данных для подключения к базе данных.
  2. Создайте классы POJO, используя плагин, и сохраните в пакете, соответствующем таблицам. В нашем приложении мы будем использовать две таблицы album и phototbl, поэтому для этого у нас есть два класса POJO.
  3. Затем добавьте файлы hbm, соответствующие двум классам POJO, созданным на предыдущих этапах.
  4. Далее мы добавим HibernateUtils.java для простой обработки сеанса гибернации в нашем приложении. Также в том же пакете мы храним один постоянный файл, чтобы сохранить любые константы, которые есть в нашем проекте.
  5. Теперь мы добавим классы DAO, которые будут иметь все методы для взаимодействия с базой данных.
    1. ListgetAllPhotoAlbums () — возвращает список всех альбомов из базы данных.
    2. boolean addAlbum (альбом AlbumBO) — это добавляет альбом в базу данных
    3. boolean delAlbum (int albumId) — удалить альбом и все фотографии в этом альбоме
    4. ListgetAllPhotosFromAlbum (int albumid) — Возвращает все фотографии из альбома на основе идентификатора альбома.
    5. boolean addPhotoToAlbum (PhototblBO photo) — добавить объект фото в альбом
    6. boolean delPhotoFromAlbum (int photoid) — удалить фото из альбома
    7. ListgetPhoto (int photoid) — возвращает объект фото для отображения на странице

hibernate.cfg.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/tctalk_apps_photoalbum</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password"></property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="show_sql">true</property>
 
    <mapping resource="com/tctalk/apps/album/db/hbm/Album.hbm.xml" />
    <mapping resource="com/tctalk/apps/album/db/hbm/Phototbl.hbm.xml" />
 
    </session-factory>   
</hibernate-configuration>

AlbumBO.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package com.tctalk.apps.album.db.businessobjects;
// Generated Apr 22, 2013 1:26:39 PM by Hibernate Tools 3.4.0.CR1
 
import java.util.Date;
 
/**
 * Album generated by hbm2java
 */
public class AlbumBO implements java.io.Serializable {
 
    private Integer albumid;
    private String albumname;
    private String albumdesc;
    private Date albumcreatedate;
 
    public AlbumBO() {
    }
 
    public AlbumBO(String albumname, String albumdesc, Date albumcreatedate) {
        this.albumname = albumname;
        this.albumdesc = albumdesc;
        this.albumcreatedate = albumcreatedate;
    }
 
    public Integer getAlbumid() {
        return this.albumid;
    }
 
    public void setAlbumid(Integer albumid) {
        this.albumid = albumid;
    }
 
    public String getAlbumname() {
        return this.albumname;
    }
 
    public void setAlbumname(String albumname) {
        this.albumname = albumname;
    }
 
    public String getAlbumdesc() {
        return this.albumdesc;
    }
 
    public void setAlbumdesc(String albumdesc) {
        this.albumdesc = albumdesc;
    }
 
    public Date getAlbumcreatedate() {
        return this.albumcreatedate;
    }
 
    public void setAlbumcreatedate(Date albumcreatedate) {
        this.albumcreatedate = albumcreatedate;
    }
 
}

PhototblBO.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package com.tctalk.apps.album.db.businessobjects;
// Generated Apr 22, 2013 1:26:39 PM by Hibernate Tools 3.4.0.CR1
 
import java.util.Date;
 
/**
 * Phototbl generated by hbm2java
 */
public class PhototblBO implements java.io.Serializable {
 
    private int photoid;
    private int albumid;
    private String phototitle;
    private String photoname;
    private String imgcontenttype;
    private Date photocreatedate;
    private byte[] photodata;
 
    public PhototblBO() {
    }
 
    public PhototblBO(int photoid, int albumid, String phototitle,
            String photoname, String imgcontenttype, Date photocreatedate,
            byte[] photodata) {
        this.photoid = photoid;
        this.albumid = albumid;
        this.phototitle = phototitle;
        this.photoname = photoname;
        this.imgcontenttype = imgcontenttype;
        this.photocreatedate = photocreatedate;
        this.photodata = photodata;
    }
 
    public int getPhotoid() {
        return this.photoid;
    }
 
    public void setPhotoid(int photoid) {
        this.photoid = photoid;
    }
 
    public int getAlbumid() {
        return this.albumid;
    }
 
    public void setAlbumid(int albumid) {
        this.albumid = albumid;
    }
 
    public String getPhototitle() {
        return this.phototitle;
    }
 
    public void setPhototitle(String phototitle) {
        this.phototitle = phototitle;
    }
 
    public String getPhotoname() {
        return this.photoname;
    }
 
    public void setPhotoname(String photoname) {
        this.photoname = photoname;
    }
 
    public String getImgcontenttype() {
        return this.imgcontenttype;
    }
 
    public void setImgcontenttype(String imgcontenttype) {
        this.imgcontenttype = imgcontenttype;
    }
 
    public Date getPhotocreatedate() {
        return this.photocreatedate;
    }
 
    public void setPhotocreatedate(Date photocreatedate) {
        this.photocreatedate = photocreatedate;
    }
 
    public byte[] getPhotodata() {
        return this.photodata;
    }
 
    public void setPhotodata(byte[] photodata) {
        this.photodata = photodata;
    }
 
}

Album.hbm.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
<!-- Generated Apr 22, 2013 1:26:40 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.tctalk.apps.album.db.businessobjects.AlbumBO" table="album" catalog="tctalk_apps_photoalbum">
        <id name="albumid" type="java.lang.Integer">
            <column name="albumid" />
            <generator class="identity" />
        </id>
        <property name="albumname" type="string">
            <column name="albumname" length="55" not-null="true" />
        </property>
        <property name="albumdesc" type="string">
            <column name="albumdesc" length="65535" not-null="true" />
        </property>
        <property name="albumcreatedate" type="date">
            <column name="albumcreatedate" length="10" not-null="true" />
        </property>
    </class>
</hibernate-mapping>

Phototbl.hbm.xml

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
<!-- Generated Apr 22, 2013 1:26:40 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.tctalk.apps.album.db.businessobjects.PhototblBO" table="phototbl" catalog="tctalk_apps_photoalbum">
        <id name="photoid" type="int">
            <column name="photoid" />
            <generator class="assigned" />
        </id>
        <property name="albumid" type="int">
            <column name="albumid" not-null="true" />
        </property>
        <property name="phototitle" type="string">
            <column name="phototitle" not-null="true" />
        </property>
        <property name="photoname" type="string">
            <column name="photoname" not-null="true" />
        </property>
        <property name="imgcontenttype" type="string">
            <column name="imgcontenttype" not-null="true" />
        </property>
        <property name="photocreatedate" type="timestamp">
            <column name="photocreatedate" length="19" not-null="true" />
        </property>
        <property name="photodata" type="binary">
            <column name="photodata" not-null="true" />
        </property>
    </class>
</hibernate-mapping>

HibernateUtils.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.tctalk.apps.album.utils;
 
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
 
public class HibernateUtils {
    private static SessionFactory hbmSessionFactory;
 
    static {
        try {
            Configuration cfg = new Configuration()
                    .configure(PhotoAlbumConstant._HIBERNATE_CONFIG_LOCATION);
            hbmSessionFactory = cfg.buildSessionFactory();
        } catch (RuntimeException ex) {
            System.out.println("********* Error occurred while reading config file *********");
            ex.printStackTrace();
        }
    }
 
    /**
     * getSession creates hibernate Session & returns it
     */
    public static Session getSession() {
        return hbmSessionFactory.openSession();
    }
 
    /**
     * closeSession closes the session, if it exists
     */
    public static void closeSession(Session inSession) {
        if (inSession != null) {
            inSession.close();
        }
    }
}

PhotoAlbumConstant.java

1
2
3
4
5
6
7
package com.tctalk.apps.album.utils;
 
public interface PhotoAlbumConstant {
 
    String _HIBERNATE_CONFIG_LOCATION = "hibernate.cfg.xml";
    String _HQL_DEL_PHOTOS_ALBUM = "DELETE FROM PhototblBO WHERE albumid= :albumid";   
}

PhotoAlbumAdminDao.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
package com.tctalk.apps.album.db.dao;
 
import java.util.List;
 
import com.tctalk.apps.album.db.businessobjects.AlbumBO;
import com.tctalk.apps.album.db.businessobjects.PhototblBO;
 
public interface PhotoAlbumAdminDao {
    // Photo Album related operations
    public List<AlbumBO> getAllPhotoAlbums();
    public boolean addAlbum(AlbumBO album);
    public boolean delAlbum(int albumId);
 
    //Photo related operations
    public List<PhototblBO> getAllPhotosFromAlbum(int albumid);
    public boolean addPhotoToAlbum(PhototblBO photo);
    public boolean delPhotoFromAlbum(int photoid);
    public List<PhototblBO> getPhoto(int photoid);
}

PhotoAlbumAdminDaoImpl.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
package com.tctalk.apps.album.db.dao;
 
import java.util.Date;
import java.util.List;
 
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
 
import com.tctalk.apps.album.db.businessobjects.AlbumBO;
import com.tctalk.apps.album.db.businessobjects.PhototblBO;
import com.tctalk.apps.album.utils.HibernateUtils;
import com.tctalk.apps.album.utils.PhotoAlbumConstant;
 
public class PhotoAlbumAdminDaoImpl implements PhotoAlbumAdminDao, PhotoAlbumConstant {
 
    /**
     * The below methods will be used for handling the Photo album related
     * operations
     *
     */
 
    /**
     * This function retrieves all the photo albums and send the list to the
     * front end
     */
    public List<AlbumBO> getAllPhotoAlbums() {
        List<AlbumBO> albumList = null;
        Session hbmSession = null;
        try {
            hbmSession = HibernateUtils.getSession();
            Criteria criteria = hbmSession.createCriteria(AlbumBO.class);
            albumList = criteria.list();
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            HibernateUtils.closeSession(hbmSession);
        }
 
        return albumList;
    }
 
    /**
     * This function adds one photo album to the database
     */
    public boolean addAlbum(AlbumBO album) {
        Session hbmSession = null;
        boolean STATUS_FLAG = true;
        try {
            hbmSession = HibernateUtils.getSession();
            hbmSession.beginTransaction();
 
            // change the creation date to today's date in the album object
            album.setAlbumcreatedate(new Date());
            // add the album to the hibernate session to save
            hbmSession.save(album);
            hbmSession.getTransaction().commit();
        } catch (Exception ex) {
            hbmSession.getTransaction().rollback();
            ex.printStackTrace();
            STATUS_FLAG = false;
        } finally {
            HibernateUtils.closeSession(hbmSession);
        }
        return STATUS_FLAG;
    }
 
    /**
     * This function deletes the photoalbum based on the album id. It first
     * check if the album has any photos or not. If the album is not emptry then
     * it deletes the photos first and then delete the album itself
     */
    public boolean delAlbum(int albumId) {
        Session hbmSession = null;
        boolean STATUS_FLAG = true;
        try {
            // get the hibernate session to perform delete operation
            hbmSession = HibernateUtils.getSession();
            hbmSession.beginTransaction();
 
            //delete all photos from the Photo table correspond to the album id
            Query query = hbmSession.createQuery(_HQL_DEL_PHOTOS_ALBUM);
            query.setInteger("albumid", new Integer(albumId));
            int rowCount = query.executeUpdate();
            System.out.println("Rows affected: " + rowCount);
 
            //now load the album object from Album table and delete it correspond to the album id
            AlbumBO albumObj = (AlbumBO) hbmSession.load(AlbumBO.class, albumId);
            hbmSession.delete(albumObj);
 
            hbmSession.getTransaction().commit();
        } catch (Exception ex) {
            hbmSession.getTransaction().rollback();
            ex.printStackTrace();
            STATUS_FLAG = false;
        } finally {
            HibernateUtils.closeSession(hbmSession);
        }
        return STATUS_FLAG;
    }
 
    /**
     * The below functions will be helpful to work on the Photos in the photo
     * album
     */
 
    /**
     * This function retrieves all the photos and send the list to the front end
     */
    public List<PhototblBO> getAllPhotosFromAlbum(int albumid) {
        List<PhototblBO> photoList = null;
        Session hbmSession = null;
        Criteria criteria = null;
 
        try {
            hbmSession = HibernateUtils.getSession();
            hbmSession.beginTransaction();
 
            // retrieve all photos from photo table correspond to the album Id
            criteria = hbmSession.createCriteria(PhototblBO.class).add(
                    Restrictions.eq("albumid", albumid));
            photoList = criteria.list();
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            HibernateUtils.closeSession(hbmSession);
        }
        return photoList;
    }
 
    /**
     * This function adds photo to the album
     */
    public boolean addPhotoToAlbum(PhototblBO photoobj) {
        Session hbmSession = null;
        boolean STATUS_FLAG = true;
        try {
            hbmSession = HibernateUtils.getSession();
            hbmSession.beginTransaction();
            hbmSession.save(photoobj);
            hbmSession.getTransaction().commit();
        } catch (Exception ex) {
            hbmSession.getTransaction().rollback();
            ex.printStackTrace();
            STATUS_FLAG = false;
        } finally {
            HibernateUtils.closeSession(hbmSession);
        }
        return STATUS_FLAG;
    }
 
    /**
     * This function deletes the photo from the album itself
     */
    public boolean delPhotoFromAlbum(int photoid) {
        Session hbmSession = null;
        boolean STATUS_FLAG = true;
 
        try {
            // get the hibernate session to perform delete operation
            hbmSession = HibernateUtils.getSession();
            hbmSession.beginTransaction();
            PhototblBO photoobj = (PhototblBO) hbmSession.load(
                    PhototblBO.class, photoid);
            hbmSession.delete(photoobj);
            hbmSession.getTransaction().commit();
        } catch (Exception ex) {
            hbmSession.getTransaction().rollback();
            ex.printStackTrace();
            STATUS_FLAG = false;
        } finally {
            HibernateUtils.closeSession(hbmSession);
        }
        return STATUS_FLAG;
    }
 
    /**
     * This function returns the photo object itself
     */
    public List<PhototblBO> getPhoto(int photoid) {
        List<PhototblBO> photoList = null;
        Session hbmSession = null;
        Criteria criteria = null;
 
        try {
            hbmSession = HibernateUtils.getSession();
            hbmSession.beginTransaction();
 
            // retrieve all photos from photo table correspond to the album Id
            criteria = hbmSession.createCriteria(PhototblBO.class).add(
                    Restrictions.eq("photoid", photoid));
            photoList = criteria.list();
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            HibernateUtils.closeSession(hbmSession);
        }
        return photoList;
    }
 
}

Шаг 6: Разработка пользовательского интерфейса

Создайте папку «admin», чтобы сохранить все файлы, связанные с интерфейсом администратора. Хотя в нашем приложении не будет файла CSS или JavaScript, мы будем создавать папки в качестве заполнителя. Мы добавим два файла jsp — showalbums.jsp — это будет использоваться для отображения существующих альбомов, а также полей для добавления одного альбома в базу данных.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ 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=ISO-8859-1">
<title>TechcubeTalk.com - Let's build apps from scratch series - Personal Photo Album App</title>
</head>
<body>
<h2>:: TechcubeTalk.com - Personal Photo Album Admin Panel ::</h2>
<div style="margin-bottom: 25px;">
<s:form action="addAlbumAdmn" method="POST">
        <s:textfield label="Photo Album Name/Title" name="album.albumname"/>
        <s:textfield label="Optional Brief Description" name="album.albumdesc"/>
        <br/>
        <s:submit value="Create Photo Album" align="center"/>
</s:form>
<hr/>
</div>
<div>
    <table style="border: 1px dotted black;">
    <tr>
        <th style="background-color:#ABDCFF;" align="center"> Album Id </th>
        <th style="background-color:#ABDCFF;" align="center"> Photo Album Title </th>
        <th style="background-color:#ABDCFF;" align="center"> Brief Description </th>
        <th style="background-color:#ABDCFF;" align="center"> Created On </th>
        <th style="background-color:#ABDCFF;" align="center"> Delete? </th>
        <th style="background-color:#ABDCFF;" align="center"> View Photos in Album </th>
    </tr>
    <s:iterator value="albumList" var="album">
        <tr>
            <td align="center"><s:property value="albumid"/></td>
            <td align="center"><s:property value="albumname"/></td>
            <td align="center"><s:property value="albumdesc"/></td>
            <td align="center"><s:property value="albumcreatedate"/></td>
            <td align="center"> <a href="delAlbumAdmn.action?albumid=<s:property value="albumid"/>">Delete</a> </td>
            <td align="center"> <a href="listPhotosByAlbumAdmn.action?albumid=<s:property value="albumid"/>">Click to View</a> </td>
        </tr>
    </s:iterator>
    </table>
</div>
</body>
</html>

showphotos.jsp — этот jsp покажет все фотографии в альбоме, которые пользователь нажмет. Также он покажет поля для загрузки фотографий в этом каталоге.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ 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=ISO-8859-1">
<title>TechcubeTalk.com - Let's build apps from scratch series - Personal Music Manager Application</title>
</head>
<body>
<h2>:: TechcubeTalk.com - Personal Photo Album Admin Panel ::</h2>
<div style="margin-bottom: 25px;">
<s:form action="addPhotoAcion" namespace="/" method="POST" enctype="multipart/form-data">
<s:textfield label="Photo Title" name="photoTitle"/>
<s:file name="fileUpload" label="Select a File to upload" size="40" />
<s:hidden name="albumid" value="%{albumid}" />
 
<s:submit value="Upload Photo to Album" name="submit" />
</s:form>
 
</div>
<div> <a href="listAlbumAdmn.action"><< Back to Albums</a></div>
<div>
    <table style="border: 1px dotted black;">
    <tr>
        <th style="background-color:#ABDCFF;">Photo Id</th>
        <th style="background-color:#ABDCFF;">Photo Title</th>
        <th style="background-color:#ABDCFF;">Upload Date</th>
        <th style="background-color:#ABDCFF;">View Photo</th>
        <th style="background-color:#ABDCFF;">Delete Photo</th>
    </tr>
    <s:iterator value="photoList" var="photo">
        <tr>
            <td><s:property value="photoid"/></td>
            <td><s:property value="phototitle"/></td>
            <td><s:property value="photocreatedate"/></td>
            <td><a href="showPhotoAction.action?photoid=<s:property value="photoid"/>" target="_blank">View</a></td>
            <td><a href="delPhotoFrmAlbumAdmn.action?albumid=<s:property value="albumid"/>&photoid=<s:property value="photoid"/>">Delete</a></td>
        </tr>
    </s:iterator>
    </table>
</div>
</body>
</html>

Шаг 7. Добавьте классы действий и пользовательский класс результатов.

PhotoAlbumAdminAction расширяет POJO PhotoAlbumForm.java для хранения отправленных полей формы и других значений для страницы пользовательского интерфейса. Мы используем один пользовательский результат отображения фотографии, извлекая ее в виде двоичного файла из базы данных BLOB-полей.

PhotoAlbumAdminAction.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package com.tctalk.apps.album.web.actions;
 
import java.io.IOException;
import java.util.Date;
import java.util.List;
 
import org.apache.commons.io.FileUtils;
 
import com.tctalk.apps.album.db.businessobjects.AlbumBO;
import com.tctalk.apps.album.db.businessobjects.PhototblBO;
import com.tctalk.apps.album.web.delegates.PhotoAlbumAdminDelegate;
import com.tctalk.apps.album.web.forms.PhotoAlbumForm;
 
public class PhotoAlbumAdminAction extends PhotoAlbumForm {
 
    private static final long serialVersionUID = 9168149105719285096L;
    private PhotoAlbumAdminDelegate delegate = new PhotoAlbumAdminDelegate();
 
    public String getAllAlbumList() {
        List<AlbumBO> albumList = delegate.getAllPhotoAlbums();
        String returnString = ERROR;
 
        if (albumList != null) {
            setAlbumList(albumList);
            returnString = SUCCESS;
        }
        return returnString;
    }
 
    public String addAlbumToCollection() {
        String returnString = ERROR;
        AlbumBO album = getAlbum();
 
        if (delegate.addAlbumToCollection(album)) {
            returnString = SUCCESS;
        }
 
        return returnString;
    }
 
    public String delAlbumFromCollection() {
        String returnString = ERROR;
 
        int albumId = getAlbumid();
        if (delegate.delAlbumFromCollection(albumId)) {
            returnString = SUCCESS;
        }
 
        return returnString;
    }
 
    public String listAllPhotos() {
        List<PhototblBO> photoList = delegate.getAllPhotos(this.getAlbumid());
        String returnString = ERROR;
 
        if (photoList != null) {
            this.setPhotoList(photoList);
            returnString = SUCCESS;
        }
        return returnString;
    }
 
    public String uploadPhotoToAlbum() {
        String returnString = ERROR;
        PhototblBO photoBO = new PhototblBO();
 
        // set the uploaded file meta data to the PhototblBO object before
        // saving to database
        photoBO.setAlbumid(getAlbumid());
        photoBO.setPhotocreatedate(new Date());
        photoBO.setImgcontenttype(getFileUploadContentType());
        photoBO.setPhotoname(getFileUploadFileName());
        photoBO.setPhototitle(getPhotoTitle());
        try {
            // the uploaded file is in File format so we need to convert to
            // byte[] array for storing in our database. For this apache
            //common file utility class is used below.
            photoBO.setPhotodata(FileUtils.readFileToByteArray(getFileUpload()));
        } catch (IOException e) {
            e.printStackTrace();
        }
 
        setPhotobo(photoBO);
        setAlbumid(photoBO.getAlbumid());
        if (delegate.addAPhoto(getPhotobo())) {
            returnString = SUCCESS;
        }
 
        return returnString;
    }
 
    public String delPhoto() {
        String returnString = ERROR;
 
        int photoId = getPhotoid();
        if (delegate.delPhoto(photoId)) {
            returnString = SUCCESS;
        }
 
        return returnString;
    }
 
    public String showPhoto() {
        String returnString = ERROR;
        List<PhototblBO> photoList = delegate.getPhoto(this.getPhotoid());
 
        if (photoList != null) {
            PhototblBO photoBO = (PhototblBO)photoList.get(0);
            if(photoBO != null){
                setPhotobo(photoBO);
                returnString = SUCCESS;
            }
        }
        return returnString;
    }
 
}

PhotoAlbumForm.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package com.tctalk.apps.album.web.forms;
 
import java.io.File;
import java.util.List;
 
import com.opensymphony.xwork2.ActionSupport;
import com.tctalk.apps.album.db.businessobjects.AlbumBO;
import com.tctalk.apps.album.db.businessobjects.PhototblBO;
 
public class PhotoAlbumForm extends ActionSupport{
 
    private static final long   serialVersionUID         = 706337856877546963L;
 
    private List<AlbumBO>         albumList                = null;
    private List<PhototblBO>  photoList                = null;
 
    private AlbumBO             album                    = null;
    private PhototblBO          photobo                  = null;
 
    private File                fileUpload;
    private String              fileUploadContentType;
    private String              fileUploadFileName;
    private String              photoTitle;
    private int                 photoid;
    private int                 albumid;
 
    public String getFileUploadContentType() {
        return fileUploadContentType;
    }
 
    public void setFileUploadContentType(String fileUploadContentType) {
        this.fileUploadContentType = fileUploadContentType;
    }
 
    public String getFileUploadFileName() {
        return fileUploadFileName;
    }
 
    public void setFileUploadFileName(String fileUploadFileName) {
        this.fileUploadFileName = fileUploadFileName;
    }
 
    public File getFileUpload() {
        return fileUpload;
    }
 
    public void setFileUpload(File fileUpload) {
        this.fileUpload = fileUpload;
    }
 
    public String getPhotoTitle() {
        return photoTitle;
    }
 
    public void setPhotoTitle(String photoTitle) {
        this.photoTitle = photoTitle;
    }
 
    public List<AlbumBO> getAlbumList() {
        return albumList;
    }
    public void setAlbumList(List<AlbumBO> albumList) {
        this.albumList = albumList;
    }
    public List<PhototblBO> getPhotoList() {
        return photoList;
    }
    public void setPhotoList(List<PhototblBO> photoList) {
        this.photoList = photoList;
    }
    public AlbumBO getAlbum() {
        return album;
    }
    public void setAlbum(AlbumBO album) {
        this.album = album;
    }
    public PhototblBO getPhotobo() {
        return photobo;
    }
    public void setPhotobo(PhototblBO photobo) {
        this.photobo = photobo;
    }
    public int getPhotoid() {
        return photoid;
    }
    public void setPhotoid(int photoid) {
        this.photoid = photoid;
    }
    public int getAlbumid() {
        return albumid;
    }
    public void setAlbumid(int albumid) {
        this.albumid = albumid;
    }
}

CustomPhotoResult.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.tctalk.apps.album.web.actions;
 
import javax.servlet.http.HttpServletResponse;
 
import org.apache.struts2.ServletActionContext;
 
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.Result;
 
public class CustomPhotoResult implements Result {
 
    private static final long serialVersionUID = 1L;
 
    public void execute(ActionInvocation invocation) throws Exception {
        PhotoAlbumAdminAction action = (PhotoAlbumAdminAction) invocation.getAction();
        HttpServletResponse response = ServletActionContext.getResponse();
 
        response.setContentType(action.getPhotobo().getImgcontenttype());
        response.setHeader("Content-Disposition", "inline; filename=\"" + action.getPhotobo().getPhotoname() + "\"");
        response.setHeader("cache-control", "no-cache");
        response.getOutputStream().write(action.getPhotobo().getPhotodata());
        response.getOutputStream().flush();
        response.getOutputStream().close();
    }
}

Шаг 8: Добавьте класс делегата

Класс Delegate работает как мост между уровнем представления Struts2 и бизнес-уровнем, разработанным с помощью Hibernate.

PhotoAlbumAdminDelegate.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package com.tctalk.apps.album.web.delegates;
 
import java.util.List;
 
import com.tctalk.apps.album.db.businessobjects.AlbumBO;
import com.tctalk.apps.album.db.businessobjects.PhototblBO;
import com.tctalk.apps.album.db.dao.PhotoAlbumAdminDao;
import com.tctalk.apps.album.db.dao.PhotoAlbumAdminDaoImpl;
 
public class PhotoAlbumAdminDelegate {
    PhotoAlbumAdminDao admindao = (PhotoAlbumAdminDao) new PhotoAlbumAdminDaoImpl();
 
    // Photo Album related functions
 
    public List<AlbumBO> getAllPhotoAlbums() {
        return admindao.getAllPhotoAlbums();
    }
 
    public boolean addAlbumToCollection(AlbumBO album) {
        return admindao.addAlbum(album);
    }
 
    public boolean delAlbumFromCollection(int albumId) {
        return admindao.delAlbum(albumId);
    }
 
    //Only Photo related functions
 
    public List<PhototblBO> getAllPhotos(int albumId) {
        return admindao.getAllPhotosFromAlbum(albumId);
    }
 
    public boolean addAPhoto(PhototblBO photo) {
        return admindao.addPhotoToAlbum(photo);
    }
 
    public boolean delPhoto(int photoid) {
        return admindao.delPhotoFromAlbum(photoid);
    }
 
    public List<PhototblBO> getPhoto(int photoid) {
        return admindao.getPhoto(photoid);
    }
}

Шаг 9: Окончательная интеграция

Вся структура проекта будет похожа на следующую:

image005

В файле struts.xml при перенаправлении с одного действия на другое нам нужно передать идентификатор альбома. Например, после того, как фотография загружена в базу данных, вам нужно перенаправить обратно в список всех фотографий в этом альбоме. Таким образом, мы должны отправить альбом обратно также после добавления фотографии. Для этого мы использовали $ {albumid} в struts.xml, чтобы передать albumid из формы POJO.

После завершения проекта сгенерируйте файл WAR из Eclipse. Для этого щелкните правой кнопкой мыши проект и выберите «Экспорт» -> «Файл WAR», чтобы создать файл WAR и развернуть его в Tomcat.

Если ваше развертывание прошло успешно и в консоли Tomcat нет сообщений об ошибках (игнорируйте все предупреждения, например LOG4J и т. Д.), Запустите браузер и введите URL-адрес — http: // localhost: 8080 / PersonalPhotoAlbumApp / admin.action

Это вызовет панель администратора и отобразится список категорий (в первый раз результат не будет отображаться, поэтому добавьте один альбом).

image007

Выберите «Click to View», чтобы перейти на страницу «Фотографии», и вы можете загрузить фотографии на этой странице или просмотреть загруженные фотографии.

image009

Это все на сегодня. Во второй части я разработаю интерфейсную панель, на которой будут отображаться альбомы и фотографии в этом альбоме с использованием jQuery, Struts2 и Hibernate.

Скачать исходные файлы:

Я уже дал все исходные коды в вышеуказанных шагах. Проект eclipse (с jars) и файлы WAR загружаются в GitHub repo.