- •«Разработка web-приложения»
- •Содержание
- •Введение
- •1. Структура и задачи предприятия
- •1.1 Разработка систем с использованием web-технологий
- •2. Краткое теоретическиое обоснование применяемых для решения поставленной задачи технологий
- •2.1.1 Архитектура Spring
- •3. Практическая реализация поставленной задачи
- •Заключение
- •Список использованной литературы
3. Практическая реализация поставленной задачи
Покажем практическую реализацию интеграции Spring+Struts+Hibernate на примере новостного портала. Данный web- проект будет включать в себя просмотр всех новостей, просмотр, редактирование и удаление выбранной новости, добавление новой новости и удаление выбранного количества новостей. Будет присутствовать интернационализация и локализация.
Стартовая страница будет иметь вид:
Рис. 2 – Список всех новостей
На Рис. 3 можно увидеть форму для добавления новой новости. После нажатия на кнопку СОХРАНИТЬ происходит валидация, и если есть ошибки, то они подсвечиваются и не корректная информация не сохраняется.
Рис.3 – Форма для добавления новости
На Рис. 4 можно увидеть форму для редактирования новости. Форма имеет такой же вид как и на Рис. 3, только с уже заполненной информацией.
Рис.4 - Форма для редактирования новости
На Рис. 5 демонстрируется возможность интернационализации надписей.
Рис. 5 – Пример интернационализации
Далее представим немного основных кусков кода с небольшими комментариями:
Листинг 1. Конфигурация Spring.
<?xml version="1.0" encoding="Utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="configProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:/resources/config.properties</value>
</property>
</bean>
<bean id="pool" class="com.epam.news.pool.ConnectionPool" scope="" destroy-method="dispose">
<constructor-arg value="${database.driver}"/>
<constructor-arg value="${database.url}"/>
<constructor-arg value="${connectionPool.poolSize}"/>
</bean>
<bean id="jdbcNewsDAO" class="com.epam.news.database.JdbcNewsDAO">
<property name="pool" ref="pool"/>
</bean>
<bean id="hibernateNewsDAO" class="com.epam.news.database.HibernateNewsDAO"/>
<bean id="jpaNewsDAO" class="com.epam.news.database.JpaNewsDAO"/>
<bean name="/setEnglishLocale /setRussianLocale" class="com.epam.news.presentation.action.LocaleAction"/>
<bean name="newsAction" class="com.epam.news.presentation.action.NewsAction">
<property name="newsDAO" ref="hibernateNewsDAO"/>
</bean>
<alias name="newsAction" alias="/saveNews"/>
<alias name="newsAction" alias="/newsList"/>
<alias name="newsAction" alias="/cancel"/>
<alias name="newsAction" alias="/viewNews"/>
<alias name="newsAction" alias="/addNews"/>
<alias name="newsAction" alias="/editNews"/>
<alias name="newsAction" alias="/deleteNews"/>
</beans>
Листинг 2. Класс, который обрабатывает запросы, пришедшие от пользователя.
public class NewsAction extends MappingDispatchAction {
private static final Logger log = Logger.getLogger(NewsAction.class);
private static final String SUCCESS = "success";
private INewsDAO newsDAO;
public void setNewsDAO(INewsDAO newsDAO) {
this.newsDAO = newsDAO;
}
public ActionForward list(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
log.info(NEWS_LIST);
NewsForm newsForm = (NewsForm) form;
newsForm.setNewsList(newsDAO.getList());
return mapping.findForward(SUCCESS);
}
public ActionForward view(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
NewsForm newsForm = (NewsForm) form;
int newsId = newsForm.getId();
log.info(NEWS_VIEW + newsId);
newsForm.setNewsMessage(newsDAO.fetchById(newsId));
return mapping.findForward(SUCCESS);
}
public ActionForward edit(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
NewsForm newsForm = (NewsForm) form;
int newsId = newsForm.getId();
log.info(NEWS_EDIT + newsId);
newsForm.setNewsMessage(newsDAO.fetchById(newsId));
return mapping.findForward(SUCCESS);
}
public ActionForward delete(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
NewsForm newsForm = (NewsForm) form;
String[] selected = newsForm.getSelected();
log.info(NEWS_DELETE + selected);
List<Integer> deletedList = new ArrayList<Integer>();
for (int index = 0; index < selected.length; index++) {
deletedList.add(Integer.parseInt(selected[index]));
}
newsDAO.remove(deletedList);
return mapping.findForward(SUCCESS);
}
public ActionForward cancel(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
TraceDeque traceDeque = (TraceDeque) request.getSession().getAttribute(TRACE_DEQUE);
String back;
if (traceDeque.peekLast().equals(ADD_NEWS_DO)) {
back = NEWS_LIST_DO;
} else {
back = traceDeque.peek();
}
log.info(NEWS_CANCEL + back);
ActionForward refererForward = new ActionForward(back, true);
return refererForward;
}
public ActionForward save(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
NewsForm newsForm = (NewsForm) form;
News news = newsForm.getNewsMessage();
newsDAO.save(news);
log.info(NEWS_SAVE + news);
String path = mapping.findForward(SUCCESS).getPath();
ActionForward modifiedForward = new ActionForward(path + "?" + ID +"="
+ news.getId(), true);
return modifiedForward;
}
public ActionForward add(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
log.info(NEWS_ADD);
NewsForm newsForm = (NewsForm) form;
newsForm.setNewsMessage(new News());
return mapping.findForward(SUCCESS);
}
}
Листинг 3. Пример пулла соединений:
public class ConnectionPool {
private static final Logger log = Logger.getLogger(ConnectionPool.class);
private static final String POOL_CREATED = "Connection pool created, pool size: ";
private static final String POOL_DESTROYED = "Connection pool destroyed";
private String driver;
private String url;
private int poolSize;
private BlockingQueue<Connection> queue;
private ConnectionPool(String driver, String url, int poolSize) {
this.driver = driver;
this.url = url;
this.poolSize = poolSize;
initialize();
}
private void initialize() {
try {
Class.forName(driver).newInstance();
queue = new ArrayBlockingQueue<Connection>(poolSize);
for (int i = 0; i < poolSize; i++) {
queue.offer(DriverManager.getConnection(url));
}
} catch (SQLException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
log.info(POOL_CREATED + poolSize);
}
public Connection getConnection() {
Connection connection = null;
try {
connection = queue.take();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return connection;
}
public void returnConnection(Connection connection) {
boolean closed = true;
try {
connection.setAutoCommit(true);
closed = connection.isClosed();
} catch (SQLException e) {
throw new RuntimeException(e);
}
if (!closed) {
queue.offer(connection);
}
}
public void dispose() {
Connection connection;
if (queue == null) {
return;
}
while ((connection = queue.poll()) != null) {
try {
if (!connection.getAutoCommit()) {
connection.commit();
}
connection.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
log.info(POOL_DESTROYED);
}
}
Листинг 4. Пример маппинга для Hibernate
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.epam.news.model.News" table="news">
<id column="newsId" name="id" type="integer">
<generator class="sequence">
<param name="sequence">NEWS_SEQ</param>
</generator>
</id>
<property column="title" name="title" type="string" />
<property column="c_date" name="date" type="date" />
<property column="brief" name="brief" type="string" />
<property column="content" name="content" type="string" />
</class>
<query name="findAllNews">
<![CDATA[FROM News ORDER BY date DESC]]>
</query>
<query name="deleteSelectedNews">
<![CDATA[DELETE FROM News WHERE id IN (:newsIdList)]]>
</query>
</hibernate-mapping>
