Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Java программирование > Java для Web (EE, Servlet, JSP, Tomcat, Spring MVC)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Результаты опроса: Интересна ли вам эта тема
Да, интересно 14 100.00%
Нет, не интересно 0 0%
Голосовавшие: 14. Вы ещё не голосовали в этом опросе

Закрытая тема
Ваша тема закрыта, почему это могло произойти? Возможно,
Нет наработок или кода, если нужно готовое решение - создайте тему в разделе Фриланс и оплатите работу.
Название темы включает слова - "Помогите", "Нужна помощь", "Срочно", "Пожалуйста".
Название темы слишком короткое или не отражает сути вашего вопроса.
Тема исчерпала себя, помните, один вопрос - одна тема
Прочитайте правила и заново правильно создайте тему.
 
Опции темы Поиск в этой теме
Старый 16.12.2007, 22:05   #31
Luka
 
Регистрация: 14.12.2007
Сообщений: 5
По умолчанию

Если у тебя нету времени тогда может выложишь архив готового портала.А
статью допишешь потом.
Luka вне форума
Старый 17.12.2007, 11:52   #32
Umen
Форумчанин
 
Аватар для Umen
 
Регистрация: 10.11.2006
Сообщений: 189
По умолчанию Урок 5. Создание веб-портала с помощью Hibernate + Spring + Spring MVC

Всем привет. Сегодня я наконец-то завершаю цикл статей посвящённый созданию веб-приложения
с помошью Spring и Hibernate

Сегодня мы наконец-то запустим наш портал!

Давайте начнём. Прежде всего создадим проект comedyclub, он будет у нас такой структуры:


Код:
\comedyclub
|-----\bin - тут будут храниться скомпилированные классы
|-----\src - тут лежат наши исходники
|	|----------\com - корень иерархии пакетов
|	|----------\comedyClub
|	|		|-----\dao - тут хранятся классы для слоя DAO
|	|		|-----\domain - тут хряняться доменные объекты и файлы маппингов для Hibernate
|	|		|-----\dto - тут хранятся классы DTO объектов
|	|		|-----\service - тут наша бизнес логика
|	|		|-----\web - контроллеры и валидаторы для Spring MVC
|
|-----\war - папка веб-приложения, именно эту папку мы будем помещать (не обязательно так называть)
|	|-----\css (не обязательна)
|	|	|-----style.css - цсс для наших страничек
|	|
|	|-----\WEB-INF - эта папка обязательно должна лежать в любом веб приложении
|	|	|-----\classes - тут находяться скомпилированные исходники нашего портала 
|	|	|			(папка должна обязательно так называться, если присутствует)
|	|	|-----\jsp - тут лежат наши jsp-старинцы
|	|	|-----\lib - тут лежат наши библиотеки (папка должна обязательно так называться, если присутствует)
|	|	|-----comedyclub-service.xml - один из файлов спрингового контекста, 
|	|	|						тут мы настроим доступ к базе данных
|	|	|-----comedyclub-servlet.xml - один из файлов спрингового контекста, 
|	|	|						тут мы опишем контроллеры и маппинги Spring MVC
|	|	|-----jdbc.properties - тут пропишем логин, пароль, имя бызы данных и др.
|	|	|-----log4j.properties - файл настроек логгера.
|	|	|-----web.xml - (обязательно) это контекст нашего веб приложения, тут описываются сервлеты,
|	|	|			листенеры, фильтры, и др
|	|	|-----index.htm - стартовая старница
Опишу процесс процесс разработки.
Все наши исходные java классы будут храниться в папке src.
Cкомпилированные классы мы будем помешать в папку classes и далнейшая работа будет проходить в папке war.
После создания всех jsp страниц, настройки всех конфигурационных файлов (*.xml, *.properties) в папке
web мы получим готовое веб-приложение. Для того чтобы запустить его нам достаточно скопировать
нашу папку war в папку webapps контейнера tomcat, переименовать например в comedyclub и стартовать сам томкат.

Структура папки war должна соответствовать спецификации веб приложения. Mинимально она может выглядеть так:

Код:
\webtest
|-----\WEB-INF
|	|-----\web.xml
|
|-----index.htm
web.xml может выглядеть например так:

Код:
<?xml version="1.0" encoding="UTF-8" ?>
<web-app 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">

  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
</web-app>
index.html может выглядеть например так:

Код:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>Test</title>
</head>
<body>
	<h1>Hello from Web application!</h1>
</body>
</html>
Скопируйте папку webtest в папку webapps веб-контейнера tomcat, выполните команду catalina start
(для этого у вас папка bin веб-контейнера должна находиться в переменной PATH).

После того как томкат стартует (в консоли появится строка "INFO: Server startup in xxxx ms"),
запустите любой браузер и перейдите на адрес: http://localhost:8080/webtest
(по умолчанию томкат стартует на порту 8080)

Если всё прошло удачно, то в окне браузера откроется наша старничка index.html !



Давайте вернёмся к нашему проекту.
Наша первая задача - это создать доменные объекты. Их написание я описывал в одной из первых статей,
поэтому тут не буду повторяться.

http://ifolder.ru/4589986 - по этому адресу вы можете скачать готовый проект,
так что качайте и смотрите как оно работает перед тем как я начну углубляться в детали.

все доменные объекты находятся в папке
ComedyClub\src\com\comedyClub\domai n\

У нас их 3:

Код:
User.java
Story.java
Rating.java
Теперь позаботимся о маппинге для них - в той же папке вы найдёте маппинги для доменных объектов:

Код:
Rating.hbm.xml
Story.hbm.xml
User.hbm.xml
Мы разбирали маппинги так, что на этом я также не буду останавливаться.

Далее разберёмся с DAO слоем.
Создадим интерфейсы для наших dao-методов:

ComedyClub\src\com\comedyClub\dao\I UserDao.java:
Umen вне форума
Старый 17.12.2007, 11:52   #33
Umen
Форумчанин
 
Аватар для Umen
 
Регистрация: 10.11.2006
Сообщений: 189
По умолчанию Урок 5. Создание веб-портала с помощью Hibernate + Spring + Spring MVC

Код:
package com.comedyClub.dao;
import com.comedyClub.domain.User;
import java.util.List;

public interface IUserDao {
	void save(User user);
	void update(User user);
	User getById(Long userId);
	User getByNameAndPassword(String name, String password);	
	void delete(User user);
	void deleteById(Long userId);
	
	List<User> getAllUsers();
    List<User> getUsersByName(String name);
}

ComedyClub\src\com\comedyClub\dao\I StoryDao.java:

Код:
package com.comedyClub.dao;
import com.comedyClub.domain.Story;
import java.util.List;

public interface IStoryDao {
	void update(Story story);
	Story getById(Long storyId);
	Story getByUserAndTitle(Long userId, String title);
	void delete(Story story);
	void deleteById(Long storyId);	
	
	List<Story> getByTitle(String title);
	List<Story> getByUser(Long userId);
	List<Story> getAllStories();
}
ComedyClub\src\com\comedyClub\dao\I RatingDao.java:


Код:
package com.comedyClub.dao;
import com.comedyClub.domain.Rating;
import java.util.List;

public interface IRatingDao {
	void update(Rating rating);
	Rating getById(Long ratingId);
	Rating getByStoryAndUser(Long storyId, Long userId);	
	void delete(Rating rating);
	void deleteById(Long ratingId);
	
	List<Rating> getByStory(Long storyId);
	List<Rating> getAllRatings();
}

Как вы помните, интерфейсы создаються для того, чтобы реализовать модель IoC, то есть,
чтобы уменьшить зависимость между компонентами нашего приложения

Реализации наших dao-методов будут заниматься сохранением, доставанием, удалением наших доменных объектов
из базы. Для того чтобы облегчить себе жизнь создадим класс-шаблон, в котором пропишем основные
операции сохранения, поиска, удаления безотносительно к конкретному доменному объекту:

ComedyClub\src\com\comedyClub\dao\i mpl\BaseAbstractDao.java:


Код:
package com.comedyClub.dao.impl;

import java.io.Serializable;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Expression;
import org.hibernate.criterion.Order;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class BaseAbstractDao extends HibernateDaoSupport {

	protected Object getEntityById(Class clazz, Serializable id) {
		return getHibernateTemplate().get(clazz, id);
	}
	
	protected void saveEntity(Object entity) {
		getHibernateTemplate().persist(entity);
	}
	
	protected void saveOrUpdateEntity(Object entity) {
		getHibernateTemplate().saveOrUpdate(entity);
	}	

	protected void updateEntity(Object entity) {
		getHibernateTemplate().update(entity);
	}

	protected void deleteEntity(Object entity) {
		getHibernateTemplate().delete(entity);		
	}
	
	protected void deleteEntityById(Class clazz, Serializable id) {
		Object entity = getEntityById(clazz, id);
		if (entity != null) {
		    deleteEntity(entity);	
		}				
	}	
	
    protected List findAll(Class clazz) {
    	return getHibernateTemplate().loadAll(clazz);        
    }
    
    protected List findAll(Class clazz, String orderBy) {  
    	return getHibernateTemplate().findByCriteria(
				DetachedCriteria.forClass(clazz).addOrder(Order.asc(orderBy)));	        
    }   
    
	protected List findFiltered(Class clazz, String property, Object filter) {
		return getHibernateTemplate().findByCriteria(
				DetachedCriteria.forClass(clazz).add(
						Expression.eq(property, filter)));		
	}    
	
	protected List findFiltered(Class clazz, String property, Object filter, String orderBy) {
		return getHibernateTemplate().findByCriteria(
				DetachedCriteria.forClass(clazz).add(
						Expression.eq(property, filter)).addOrder(
						Order.asc(orderBy)));		
	}  	
	
	protected Object findUniqueFiltered(Class clazz, String property, Object filter) {
		return DataAccessUtils.requiredUniqueResult(getHibernateTemplate()
				.findByCriteria(
						DetachedCriteria.forClass(clazz).add(
								Expression.eq(property, filter))));		
	}    
	
	protected Object findUniqueFiltered(Class clazz, String property, Object filter, String orderBy) {
		return DataAccessUtils.requiredUniqueResult(getHibernateTemplate()
				.findByCriteria(
						DetachedCriteria.forClass(clazz).add(
								Expression.eq(property, filter)).addOrder(
								Order.asc(orderBy))));
	} 	

}
Как видите все методы принимают параметры типа Object и Class, что означает что они не привязаны
к конкретному доменному объекту. Это универсальный класс и его можно использовать и в других приложениях
где используется связка Hibernate+Spring

Далее создадим реализации наших интерфейсов, которые будут наследовать BaseAbstractDao:

ComedyClub\src\com\comedyClub\dao\i mpl\UserDaoImpl.java:
Umen вне форума
Старый 17.12.2007, 11:53   #34
Umen
Форумчанин
 
Аватар для Umen
 
Регистрация: 10.11.2006
Сообщений: 189
По умолчанию Урок 5. Создание веб-портала с помощью Hibernate + Spring + Spring MVC

Код:
package com.comedyClub.dao.impl;

import com.comedyClub.dao.IUserDao;
import com.comedyClub.domain.User;

import java.util.List;

public class UserDaoImpl extends BaseAbstractDao implements IUserDao {

    public UserDaoImpl() {
    }

    public void delete(User user) {
        super.deleteEntity(user);
    }

    public void deleteById(Long userId) {
        super.deleteEntityById(User.class, userId);
    }

    @SuppressWarnings("unchecked")
    public List<User> getAllUsers() {
        return super.findAll(User.class);
    }

    public User getById(Long userId) {
        return (User) super.getEntityById(User.class, userId);
    }

    public User getByNameAndPassword(String name, String password) {
        String queryString = "from User u where u.name = :name and u.password = :password";

        List users = getHibernateTemplate()
                .findByNamedParam(queryString,
                        new String[]{"name", "password"},
                        new Object[]{name, password});

        return (User) users.get(0);
    }

    @SuppressWarnings("unchecked")
    public List<User> getUsersByName(String name) {

        String queryString = "from User u where u.name = :name";
        List usersList = getHibernateTemplate().findByNamedParam(queryString,
                new String[]{"name"},
                new Object[]{name});

        return usersList;
    }


    public void save(User user) {
        super.saveEntity(user);
    }

    public void update(User user) {
        super.updateEntity(user);
    }

}
обратите внимание - в большинстве методов мы просто вызываем методы родительского класса BaseAbstractDao.
Замечу, что реализация не совсем гладкая - необходимо обеспечить
обработку исключительных ситуаций, однако сдесь мы её для простоты опустим.
Заметьте - в методах с queryString используется HQL - Hibernate Query Language это замена для обычного SQL

Другие реализации - StoryDaoImpl, RatingDaoImpl реализованы аналогично (см. исходники)
@SuppressWarnings("unchecked") нужно всего лишь чтобы обмануть IDE, чтобы она не выдавала предупреждения.

С DAO слоем покончено, переходим к слою бизнес-логики. Его будут составлять 3 интерфейса и их реализации:

ComedyClub\src\com\comedyClub\servi ce\IUserManagerService.java:

Код:
package com.comedyClub.service;
import com.comedyClub.dto.UserDto;
import java.util.List;

public interface IUserManagerService {
	UserDto registerNewUser(UserDto userDto);
	void updateUser(UserDto userDto);
	void deleteUser(Long userId);
	UserDto getUserByNameAndPassword(String name, String password);
	UserDto getUserById(Long userId);
	void addFriend(Long userId, Long friendId);
	void deleteFriend(Long userId, Long friendId);
	
	List<UserDto> getAllUsers();
	List<UserDto> getUsersByName(String name);    
    List<UserDto> getAllFriends(Long userId);
}
и аналогичные ему IStoryManagerService и IRatingManagerService

Как видите, тут у нас описаны методы регистрации нового юзера, его обновление, удаление,
получение списка всех юзеров, всех юзеров по имени и др.

А вот и реализация:

ComedyClub\src\com\comedyClub\servi ce\impl\UserManagerServiceImpl.java :
Umen вне форума
Старый 17.12.2007, 11:53   #35
Umen
Форумчанин
 
Аватар для Umen
 
Регистрация: 10.11.2006
Сообщений: 189
По умолчанию Урок 5. Создание веб-портала с помощью Hibernate + Spring + Spring MVC

Код:
package com.comedyClub.service.impl;

import com.comedyClub.dao.IUserDao;
import com.comedyClub.domain.User;
import com.comedyClub.dto.UserDto;
import com.comedyClub.service.IUserManagerService;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class UserManagerServiceImpl implements IUserManagerService {
	
	IUserDao userDao;
	
	public UserManagerServiceImpl() {
	}

	public void setUserDao(IUserDao userDao) {
		this.userDao = userDao;
	}

	private UserDto makeUserDto(User user) {
		UserDto userDto = new UserDto();
		
		userDto.setId(user.getId());
		userDto.setName(user.getName());
        userDto.setPassword(user.getPassword());

        return userDto;
	}

	private List<UserDto> makeUserDtoSet(List<User> users) {
		List<UserDto> usersDto = new ArrayList<UserDto>();

        for (Object user1 : users) {
            User user = (User) user1;

            usersDto.add(makeUserDto(user));
        }
		
		return usersDto;
	}

	public UserDto registerNewUser(UserDto userDto) {
		User user = new User();
		
		user.setName(userDto.getName());
		user.setPassword(userDto.getPassword());        
        userDao.save(user);
		return makeUserDto(user);
	}

	public void updateUser(UserDto userDto) {
		User user = userDao.getById(userDto.getId());
		
		user.setName(userDto.getName());
		userDao.update(user);	
	}

	public void deleteUser(Long userId) {
		userDao.deleteById(userId);
	}

	public UserDto getUserByNameAndPassword(String name, String password) {
		User user = userDao.getByNameAndPassword(name, password);
		
		return makeUserDto(user);
	}

	public UserDto getUserById(Long userId) {
		User user = userDao.getById(userId);
		
		return makeUserDto(user);
	}

	public void addFriend(Long userId, Long friendId) {
		User user = userDao.getById(userId);
		User friend = userDao.getById(friendId);
		
		user.addFriend(friend);
		userDao.update(user);
	}

	public void deleteFriend(Long userId, Long friendId) {
		User user = userDao.getById(userId);
		User friend = userDao.getById(friendId);
		
		user.getFriends().remove(friend);
		
		userDao.update(user);
	}
	
	public List<UserDto> getAllUsers() {
		return makeUserDtoSet(userDao.getAllUsers());
	}

    public List<UserDto> getUsersByName(String name) {
        return makeUserDtoSet(userDao.getUsersByName(name));
    }

    public List<UserDto> getAllFriends(Long userId) {
		User user = userDao.getById(userId);
        List<User> friends = new ArrayList<User>();
        friends.addAll(user.getFriends());
        return makeUserDtoSet(friends);
	}

}
как видите у нас тут есть строки

Код:
	IUserDao userDao;
	
	public void setUserDao(IUserDao userDao) {
		this.userDao = userDao;
	}
их мы будем использовать для Dependency Injection - иньекции зависимости, которую
мы опишем в контексте нашего приложения. Остальные классы выглядят аналогично.
В бизнес методах происходит конвертация dto-объектов в доменные и наоборот.
В принципе есть фреймворки которые позволяют динамически
стрить dto объекты из доменных (например dynadto), но мы сделаем их руками.

итак переходим к dto объектам:

ComedyClub\src\com\comedyClub\dto\U serDto.java:

Код:
package com.comedyClub.dto;

import java.io.Serializable;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

public class UserDto implements Serializable {
	
	private static final long serialVersionUID = 3165487412362978214L;
	
	private Long id;
	private String name;
    private String password;

    public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String toString() {
		return new ToStringBuilder(this)
					.append(this.getName())
					.toString();
	}
	
	public boolean equals(Object obj) {
		if (null == obj) {
			return false;
		}
		
		if (obj == this) {
			return true;
		}
		
		if  (!(obj instanceof UserDto)) {
			return false;
		}
		
		UserDto userDto =  (UserDto) obj;
		
		return new EqualsBuilder()
					.append(this.getName(), userDto.getName())
					.isEquals();
	}

	public int hashCode() {
		return new HashCodeBuilder(13, 37)
					.append(this.getName())
					.toHashCode();
	}

}
Umen вне форума
Старый 17.12.2007, 11:53   #36
Umen
Форумчанин
 
Аватар для Umen
 
Регистрация: 10.11.2006
Сообщений: 189
По умолчанию Урок 5. Создание веб-портала с помощью Hibernate + Spring + Spring MVC

Наш dto-объект отличается от соответствующего ему доменного только отсутствием полей типа Set.
Аналогично делаем StoryDto, RatingDto. В нашем приложении других дто-объектов нам не понадобиться.

На самом деле dto объект не обязательно должен внешне быть похожим на доменный объект, всё зависит от того,
какие данные мы хотим передавать

Ну вот - с бек-ендом покончено. Переходим к UI. У нас в качестве UI используется Spring MVC.
Что такое MVC? Это шаблон проектирования Model View Controller. В чём его смысл? Давайте рассмотрим
следующёю схему:

Пользователь производит какие-то действия, например нажимает на ссылку, это действие передаётся
оперделённому классу, который его обработает, он достанет из бекенда необходимые данные (либо сохранит их) и
покажет пользователю результат его действий. Тут как раз и описана схема работы MVC:

Наш класс, который обрабатывает запросы от пользователя - это контроллер.
Бизнес методы в месте с доменной моделью - это модель
Результат, который отображается пользователю - это view (представление)

Модель у нас уже есть. Осталось разобраться с view и controllers

Возьмём к примеру страничку логина.
Создадим в папке war\web-inf\jsp файл userLogin.jsp:

Код:
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
    <title><fmt:message key="title"/></title>
    <link rel="stylesheet" type="text/css" href="css/style.css"/>
</head>

<body>
<h1>Welcome to Comedy Club!</h1>

<form method="post" action="userLogin.html">
    <table bgcolor="f8f8ff" cellspacing="0" cellpadding="5">
        <spring:bind path="userToLogin.name">
            <tr>
                <td align="right">name:</td>
                <td>
                    <input type="text" name="name" value="${status.value}">
                </td>
                <td>
                    <font color="red">${status.errorMessage}</font>
                </td>
            </tr>
        </spring:bind>
        <spring:bind path="userToLogin.password">
            <tr>
                <td align="right">password:</td>
                <td>
                    <input type="password" name="password" value="${status.value}">
                </td>
                <td>
                    <font color="red">${status.errorMessage}</font>
                </td>
            </tr>
        </spring:bind>
        <tr>
            <td/>
            <td>
                <input type="submit" align="right" value="login">
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <spring:hasBindErrors name="userToLoign">
                    <b>Enter correct name, or register if you are visit for the first time</b>
                </spring:hasBindErrors>
            </td>
        </tr>
    </table>
    <br/>
    <a href="registerUser.html">register</a>
</form>
</body>
</html>
как видите это почти обычный html с некоторыми дополнениями:

Код:
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
тут мы подключаем дополнительные
теги к нашей страничке, и потом используем их, например так:
Код:
        <spring:bind path="userToLogin.name">
			.....
	   </spring:bind>
далее мы видим непонятное выражение ${status.value} в строке
<input type="text" name="name" value="${status.value}">

посредством ${} мы можем вставлять в наш код выражения. В данном случае мы вставляем значение переменной.
Откуда тут взялась переменная?
В данном случае она относится к строке
Код:
        <spring:bind path="userToLogin.name">
Что значит
Код:
<spring:bind path="userToLogin.name">
?

Внутри этого тега появляется возможность заполнить в поле формы для переменной userToLogin поле name.
Откуда взялась переменная userToLogin? Её передал на нашу страничку контроллер.

Давайте перейдём к его рассмотрению. Создадим класс UserLoginFormController.java в

ComedyClub\src\com\comedyClub\web:
Umen вне форума
Старый 17.12.2007, 12:01   #37
Umen
Форумчанин
 
Аватар для Umen
 
Регистрация: 10.11.2006
Сообщений: 189
По умолчанию Урок 5. Создание веб-портала с помощью Hibernate + Spring + Spring MVC

Код:
package com.comedyClub.web;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.servlet.view.RedirectView;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.comedyClub.dto.UserDto;
import com.comedyClub.service.IUserManagerService;

public class UserLoginFormController extends SimpleFormController {
    /** Logger for this class and subclasses */
    final Log logger = LogFactory.getLog(getClass());    

    public ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command, BindException e) throws ServletException {

    	String name = ((UserDto)command).getName();
    	String password = ((UserDto)command).getPassword();

        UserDto user = userManagerService.getUserByNameAndPassword(name, password);
		logger.info("user="+user+" successfully logged");

        request.getSession().setAttribute("user", user);
		return new ModelAndView(new RedirectView(getSuccessView()));
        
    }

    protected Object formBackingObject(HttpServletRequest request) throws ServletException {
        UserDto user = new UserDto();
        return user;
    }

    private IUserManagerService userManagerService;    
    public void setUserManagerService(IUserManagerService userManagerService) {
    	this.userManagerService = userManagerService;
    }
}
тут onSubmit вызовется когда мы нажмём на кнопку login на страничке логина

formBackingObject подготавливает для нашей странички новый объект типа UserDto. Именно в его
поля мы будем на страничке записывать логин и пароль.

Код:
private IUserManagerService userManagerService;
    public void setUserManagerService(IUserManagerService userManagerService) {
    	this.userManagerService = userManagerService;
    }
эти строки используются для получения userManagerService.

Как же связывактся между собой котроллер и представление (view)? Все связи прописываются в контексте.

Перед тем как описать их, рассмотрим более общие файлы в конфигурации:

web.xml:
Код:
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/comedyclub-service.xml
        /WEB-INF/comedyclub-servlet.xml
    </param-value>
  </context-param>
тут мы указываем где будет настраиваться контекст спринга
Код:
  <context-param>
    <param-name>log4jConfigLocation</param-name>
    <param-value>/WEB-INF/log4j.properties</param-value>
  </context-param>
тут мы указываем спрингу откуда брать настройки для логгера

Код:
  <listener>        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
  </listener>
это листенер для логгера, т.е. тут мы связываем спринг и логгер (log4j)

Код:
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
тут мы подгружаем спринговый контекст

Код:
<servlet>
    <servlet-name>comedyclub</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
это сервлет, он и будет разгребать наши странички

Код:
  <servlet-mapping>
    <servlet-name>comedyclub</servlet-name>
    <url-pattern>*.html</url-pattern>
  </servlet-mapping>
тут указываем, что наш сервлет будет обрабатывать всё что заканчивается на .html
(даже если такой старинчки в принципе нету). Соответсвие между html страничкой
и одним из наших контроллеров будет определяться в comedyclub-servlet.xml

Код:
  <welcome-file-list>
    <welcome-file>index.htm</welcome-file>
  </welcome-file-list>
тут указываем страничку по умолчанию
(у неё расширение .htm а не .html потому, что противном случае она обрабатывалась бы нашим сервлетом
см. выше, а это обычная страничка)

Код:
  <session-config>
      <session-timeout>30</session-timeout>
  </session-config>
тут мы указываем скольхо будет храниться сессия в целях безопастности.

Теперь рассмотрим comedyclub-servlet.xml:
Код:
<bean id="readMyStoryController"
        class="com.comedyClub.web.ReadMyStoryController">
        <property name="storyManagerService"><ref bean="storyManagerService"/></property>
    </bean>
таким образом мы описываем простые контроллеры, на страничках которых не будет форм.

Код:
<bean id="userLoginFormValidator" class="com.comedyClub.web.validator.UserLoginFormValidator">
        <property name="userManagerService"><ref bean="userManagerService"/></property>
    </bean>
Это валидатор - класс который используется для проверки данных форм.
Umen вне форума
Старый 17.12.2007, 12:18   #38
Umen
Форумчанин
 
Аватар для Umen
 
Регистрация: 10.11.2006
Сообщений: 189
По умолчанию Урок 5. Создание веб-портала с помощью Hibernate + Spring + Spring MVC

Код:
<bean id="userLoginFormController" class="com.comedyClub.web.UserLoginFormController">
        <property name="sessionForm"><value>true</value></property>
        <property name="commandName"><value>userToLogin</value></property>
        <property name="commandClass"><value>com.comedyClub.dto.UserDto</value></property>
        <property name="validator"><ref bean="userLoginFormValidator"/></property>
        <property name="formView"><value>userLogin</value></property>
        <property name="successView"><value>userStartPage.html</value></property>
        <property name="userManagerService"><ref bean="userManagerService"/></property>
    </bean>
Это и есть описание нашего контроллера. Тут мы описываем, что он имеет период жизни такой же как и сессия,
имя объекта, который мы будем передавать в представление (мы его инициализировали методом formBackingObject),
тип, этого объекта, валидатор, который будет проверать данные формы, имя представления, с которым
связан наш котроллер, имя представления. на которое мы перейдём в случае успешного воода данных,
а также тут мы просечиваем конкретную реализацию IUserManagerService.


Код:
    <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="/userLogin.html">userLoginFormController</prop>
                <prop key="/registerUser.html">registerUserFormController</prop>
                <prop key="/userStartPage.html">userStartPageController</prop>
                <prop key="/listUsers.html">listUsersController</prop>
                <prop key="/listUserStories.html">listUserStoriesController</prop>
                <prop key="/userSummary.html">userSummaryController</prop>
                <prop key="/addFriend.html">addFriendController</prop>
                <prop key="/deleteFriend.html">deleteFriendController</prop>
                <prop key="/readUserStory.html">readUserStoryController</prop>
                <prop key="/rateUserStory.html">rateUserStoryFormController</prop>
		<prop key="/listMyStories.html">listMyStoriesController</prop>
		<prop key="/addStory.html">addStoryFormController</prop>
		<prop key="/editStory.html">editStoryFormController</prop>
		<prop key="/deleteStory.html">deleteStoryController</prop>
		<prop key="/readMyStory.html">readMyStoryController</prop>
            </props>
        </property>
        <property name="interceptors">
            <list>
                <bean class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
                    <property name="sessionFactory" ref="sessionFactory"/>
                    <property name="flushModeName" value="FLUSH_AUTO" />
                </bean>
            </list>
        </property>  
    </bean>
Это маппинг между html страничкми и контроллерами

Код:
<property name="interceptors">
- тут мы описываем перехатчики
(мы не будем руками работать с сессиями hibernate, Спринг сделает это за нас)


Код:
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass"><value>org.springframework.web.servlet.view.JstlView</value></property>
        <property name="prefix"><value>/WEB-INF/jsp/</value></property>
        <property name="suffix"><value>.jsp</value></property>
    </bean>
тут мы указываем, что в качестве представления будут использоваться jsp странички которій находяться в
/WEB-INF/jsp/




<bean id="messageSource" class="org.springframework.context. support.ResourceBundleMessageSource ">
<property name="basename"><value>messages</value></property>
</bean>

тут мы подключаем файл сообщений.




Рассмотрим UserLoginFormValidator - валидатор значений формы введённых на страничке логина:
Umen вне форума
Старый 17.12.2007, 12:20   #39
Umen
Форумчанин
 
Аватар для Umen
 
Регистрация: 10.11.2006
Сообщений: 189
По умолчанию Урок 5. Создание веб-портала с помощью Hibernate + Spring + Spring MVC

Код:
package com.comedyClub.web.validator;

import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import org.springframework.validation.Errors;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.comedyClub.dto.UserDto;
import com.comedyClub.service.IUserManagerService;

public class UserLoginFormValidator implements Validator {

    /** Logger for this class and subclasses */
    protected final Log logger = LogFactory.getLog(getClass());
    
    private IUserManagerService userManagerService;
    
    public void setUserManagerService(IUserManagerService userManagerService) {
    	this.userManagerService = userManagerService;
    }

    public boolean supports(Class clazz) {
        return clazz.equals(UserDto.class);
    }

    public void validate(Object obj, Errors errors) {
    	ValidationUtils.rejectIfEmpty(errors, "name", "user.empty");
    	ValidationUtils.rejectIfEmpty(errors, "password", "password.empty");

        UserDto user = (UserDto) obj;
        
        try {
        	/*UserDto userDto = */
        	userManagerService.getUserByNameAndPassword(user.getName(), user.getPassword()); 
        } catch (Exception e) {
        	logger.error("user with name: " + user.getName() + " and password: " + user.getPassword() + " not found");
//        	errors.rejectValue("name", "user.not-found", null, "Value required.");
        	errors.rejectValue("name", "user.not-found");
        }
       
    }
}
supports - указывает какой класс мы будем валидировать, в данном случае UserDto -
тот который мы заполняли на страничке логина под именем userToLogin.

validate - собственно процедура валидации данных:

ValidationUtils.rejectIfEmpty(error s, "name", "user.empty"); - если поле имя было пустое - вернуть ошибку

далее пытаемся получить из базы юзера по логину и паролю, и если вылетает ексепшен, предполагаем, что
такого юзера нету и возвращаем ошибку (не лучший вариант).

Рассмотрим ещё, например, котроллер AddFriendController:

Код:
package com.comedyClub.web;

import com.comedyClub.dto.UserDto;
import com.comedyClub.service.IUserManagerService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

public class AddFriendController  extends AbstractController {

	protected ModelAndView handleRequestInternal(HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		/** Logger for this class and subclasses */
	    final Log logger = LogFactory.getLog(getClass());

        if (!CheckUserInSession.isUserInSession(request)) {
            logger.error("Unauthorized access!");
            return new ModelAndView("userLogin", "userToLogin", new UserDto());
        }
        
        long friendId = Long.parseLong(request.getParameter("user"));
	    
	    UserDto user = (UserDto)request.getSession().getAttribute("user");
	    List<UserDto> friends = userManagerService.getAllFriends(user.getId());
		UserDto targetUser = userManagerService.getUserById(friendId);
		String message;
		
		if (!friends.contains(targetUser)) {
			userManagerService.addFriend(user.getId(), friendId);
			logger.info("user with " + user + " add to his friends list user " + targetUser);
			message = targetUser.getName() + " was successfully added to your friends list";
		} else {
			message = targetUser.getName() + " is already in your friends list";			
			logger.info("user " + user + " already have in his friends list user " + targetUser);			
		}
		
		ModelAndView addFriend = new ModelAndView("addRemoveFriend");
		addFriend.addObject("user", targetUser);
		addFriend.addObject("message", message);			
		return addFriend;
		
	}

	private IUserManagerService userManagerService;		

	public void setUserManagerService(IUserManagerService userManagerService) {
		this.userManagerService = userManagerService;
	}
}
тут у нас метод handleRequestInternal вызывается до того как мы попадаем на страничку добавления друга
(в предыдущем примере метод onSubmit вызывался уже после того как мы нажимали кнопку на нашей страничке)

Обратите внимание на строки

Код:
        if (!CheckUserInSession.isUserInSession(request)) {
            logger.error("Unauthorized access!");
            return new ModelAndView("userLogin", "userToLogin", new UserDto());
        }
тут у нас происходит проверка - зарегестрирован ли юзер (ведь он мог спокойно, не вводя логин и пароль,
просто ввести в строке адреса http://localhost:8080/comedyclub/addFriend.html)
тут мы проверяем - если юзера нету в сессии, то выкидываем но страницу логина
Umen вне форума
Старый 17.12.2007, 12:21   #40
Umen
Форумчанин
 
Аватар для Umen
 
Регистрация: 10.11.2006
Сообщений: 189
По умолчанию Урок 5. Создание веб-портала с помощью Hibernate + Spring + Spring MVC

файл comedyclub-service.xml я подробно описывать не буду - он служит для соединения с базой.

Вот и всё. Все остальные файлы написаны подобно тем что мы уже рассмотрели.

теперь осталось запустить наш портал. Для этого нужно:

1. В mysql (с помощью heidisql) создать базу comedyclub и юзера user c паролем user,
который имеет все права на данную базу
2. Проверить, что у нас установлены и настроены ant, tomcat
(томкат должен находится в с:\tomcat иначе нужно править файлы конфиеурации)

3. в папке CpmedyClub выполнить команду ant deploy
4. выполнить команду catalina start
5. перейти по адресу http://localhost:8080/comedyclub


Я на самом деле пропускал некоторыt моменты, но это потому что я просто не в состоянии все их описть.
Если вы хотите углубить свои познания в Spring и Hibernate советую прочитать книги
1. Spring in action
2. Java persistence with Hibernate

Вот и всё. Будут вопросы - не стесняётесь - задавайте.

Ещё раз привожу адрес, откуда можно скачать исходные коды портала: http://ifolder.ru/4589986




Если у меня будет время и желание, я покажу как можно проще и удобнее сделать UI с помошью JSF - Java Server Faces
Umen вне форума
Закрытая тема


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ассемблер - Быстрый старт Ev3658 Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 12 17.01.2023 22:16
Старт в ВЕБе AVer Свободное общение 5 29.03.2015 20:55
Старт в Java Artem Vitalievich Общие вопросы по Java, Java SE, Kotlin 1 03.07.2014 13:15
Ищу веб-програмиста для старт-апа Валентин Андреевич Фриланс 2 19.10.2011 10:25
Старт в Java for Mobile: Уроки [Smarik] Общие вопросы по Java, Java SE, Kotlin 6 14.07.2010 15:17