Spring 3 і Hibernate 3. Частина 2

квітня
13
2012
Мітки: hibernate java spring

Зміст

У цій частині статті розглянемо безпосереднє створення класів і веб-сторінок для взаємодії з користувачем. У першій частині статті згадувався файл настройок Hibernate під назвою hibernate.cfg.xml, в якому знаходиться маппінг класів, пов'язаних з базою даних. В нашому випадку, це класи Country і User. Файл hibernate.cfg.xml представлений нижче


<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <mapping class="com.seostella.spring.domain.user.User" />
        <mapping class="com.seostella.spring.domain.Country" />
    </session-factory>
</hibernate-configuration>

Почнемо розгляд з більш простого класу Country. Нижче лістинг:

Country.java

package com.seostella.spring.domain;

import javax.persistence.*;

/**
 *
 * @author seostella.com
 */
@Entity
public class Country {
    @Id
    @GeneratedValue
    private long id;
    
    @Column(name = "name", unique = true, nullable=false)
    private String name;
    
    public Country() {
    }

    public Country(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    public long getId() {
        return id;
    }

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

Докладно зупинятися на цьому класі не будемо - основні моменти описані в статті Основи Hibernate 3 на прикладі роботи з MySQL

Далі створимо DAO для роботи з цим класом. Почнемо з інтерфейсу CountryDAO:

CountryDAO.java

package com.seostella.spring.dao;

import com.seostella.spring.domain.Country;
import java.util.List;

/**
 * 
 * @author seostella.com
 */
public interface CountryDAO {

    public void saveCountry(Country user);

    public List<Country> countryList();

    public void removeCountry(Long id);

    public Country retriveCountry(Long id);
}

За допомогою CountryDAO будемо виконувати найпростіші операції: збереження країни, отримання списку країн, видалення країни і отримання об'єкта за ідентифікатором.

Реалізація інтерфейсу CountryDAO представлена ​​нижче:

CountryDAOImpl.java

package com.seostella.spring.dao;

import com.seostella.spring.domain.Country;
import java.util.List;
import org.hibernate.Query;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

/**
 * 
 * @author seostella.com
 */
@Repository
public class CountryDAOImpl implements CountryDAO {

    @Autowired
    private SessionFactory sessionFactory;

    public void saveCountry(Country user) {
        sessionFactory.getCurrentSession().saveOrUpdate(user);
    }

    @SuppressWarnings("unchecked")
	public List<Country> countryList() {
        return sessionFactory.getCurrentSession().createQuery("from Country").list();
    }

    public void removeCountry(Long id) {
    	Country country = (Country) sessionFactory.getCurrentSession().load(
    			Country.class, id);
        if (null != country) {
            sessionFactory.getCurrentSession().delete(country);
        }
    }
    
    public Country retriveCountry(Long id){
        Query q = sessionFactory.getCurrentSession().createQuery("from Country where id = :id");
        q.setLong("id", id);
        return (Country) q.uniqueResult();
    }
}

Розглянемо детально цей клас:


    @Autowired
    private SessionFactory sessionFactory;

- bean з конфігураційного файлу db-config.xml:


    <bean id="sessionFactory"
          class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation">
            <value>/WEB-INF/db/hibernate.cfg.xml</value>
        </property>
        <property name="configurationClass">
            <value>org.hibernate.cfg.AnnotationConfiguration</value>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${jdbc.dialect}</prop>
                <prop key="hibernate.show_sql">${jdbc.show_sql}</prop>
            </props>
        </property>
    </bean>

- він є по суті "коннектором" до бази даних. За допомогою його виконуються всі звернення до бази.


    public void saveCountry(Country user) {
        sessionFactory.getCurrentSession().saveOrUpdate(user);
    }

- метод для збереження і оновлення об'єкта Country в базі даних. Для визначення наявності об'єкта в базі використовується первинний ключ (в нашому випадку id). Тому, якщо методу передається об'єкт Country, в якому не встановлено значення властивості id, то об'єкт буде додано в базу, а не оновлено. Тобто, при виконанні цього методу виконується два запити до бази. Перший - "select * from country where id =: countryId", другий - або "insert into country ...", або "update country ..." в залежності від того, повернув перший запит якийсь запис в таблиці чи ні.


    @SuppressWarnings("unchecked")
	public List<Country> countryList() {
        return sessionFactory.getCurrentSession().createQuery("from Country").list();
    }

- метод для отримання списку країн. sessionFactory.getCurrentSession().createQuery("from Country") - створення об'єкта Query, який повертає записи з бази даних. "from Country" - формат "внутрішнього SQL для Hibernate", названого HQL. В цій статті розглянуто 3 типи створення запитів: за допомогою @NamedQueries, @NamedNativeQueries і без їх використання.

У методах removeCountry() і retriveCountry() немає нічого специфічного, тому вони розглядатися не будуть.

Класи сервісу CountryService і CountryServiceImpl повторюють логіку CountryDAO так як в цьому прикладі немає необхідності в додатковій обробці даних, отриманих від CountryDAO.

CountryService.java

package com.seostella.spring.service;

import java.util.List;

import com.seostella.spring.domain.Country;

/**
 * 
 * @author seostella.com
 */
public interface CountryService {

    public void saveCountry(Country user);

    public List<Country> countryList();

    public void removeCountry(Long id);

    public Country retriveCountry(Long id);
}

CountryServiceImpl.java

package com.seostella.spring.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.seostella.spring.dao.CountryDAO;
import com.seostella.spring.domain.Country;

/**
 * 
 * @author seostella.com
 */
@Service
public class CountryServiceImpl implements CountryService {

    @Autowired
    private CountryDAO countryDAO;

    @Transactional
    public void saveCountry(Country country) {
        countryDAO.saveCountry(country);
    }

    @Transactional
    public List<Country> countryList() {
        return countryDAO.countryList();
    }

    @Transactional
    public void removeCountry(Long id) {
        countryDAO.removeCountry(id);
    }
    
    @Transactional
	public Country retriveCountry(Long id) {
		return countryDAO.retriveCountry(id);
	}
}

Контролер, який обробляє дані від користувача представлений нижче:

CountryController.java

package com.seostella.spring.controller;

import com.seostella.spring.domain.Country;
import com.seostella.spring.service.CountryService;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * 
 * @author seostella.com
 */
@Controller
public class CountryController {

    @Autowired
    private CountryService countryService;

    @RequestMapping("/country/index")
    public String listContacts(Map<String, Object> map) {

        map.put("country", new Country());
        map.put("countryList", countryService.countryList());

        return "country_list";
    }

    @RequestMapping(value = "/country/add", method = RequestMethod.POST)
    public String addContact(@ModelAttribute("country") Country country, BindingResult result) {

        countryService.saveCountry(country);

        return "redirect:/country/index";
    }

    @RequestMapping("/country/delete/{countryId}")
    public String deleteContact(@PathVariable("countryId") Long countryId) {

        countryService.removeCountry(countryId);

        return "redirect:/country/index";
    }
    
    @RequestMapping("/country/save")
    public String saveContact(@ModelAttribute("country") Country country, BindingResult result) {

        countryService.saveCountry(country);

        return "redirect:/country/edit/" + country.getId();
    }
    
    @RequestMapping("/country/edit/{countryId}")
    public String editContact(@PathVariable("countryId") Long countryId, Map<String, Object> map) {

        Country country = countryService.retriveCountry(countryId);
        map.put("country", country); 

        return "country_edit";
    }
    
}

Контролери та jsp-відображення виходять за рамки цієї статті і тому розглядатися не будуть. Нижче наведені jsp-файли, відповідальні за відображення об'єктів Country:

country_edit.jsp

<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>Spring Hibernate Example</title>
</head>
<body>
	<jsp:include flush="false" page="menu.jsp" />

	<h2>Edit '${country.name}'</h2>
	
	<form:form method="post"
		action="${pageContext.request.contextPath}/country/save"
		commandName="country">
		<form:hidden path="id" />
		<jsp:include flush="true" page="country_form.jsp" />
	</form:form>

	<a href="${pageContext.request.contextPath}/country/index"
		title="Country List">Country List</a>
</body>
</html>

country_form.jsp

<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
    <table>
        <tr>
            <td><form:label path="name"><spring:message code="label.name"/></form:label></td>
        	<td><form:input path="name" /></td>
        </tr>
        <tr>
            <td colspan="2">
                <input type="submit" value="<spring:message code="label.savecountry"/>"/>
            </td>
        </tr>
    </table>

country_list.jsp

<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>Spring Hibernate Example</title>
</head>
<body>
	<jsp:include flush="false" page="menu.jsp" />

	<h2>Country List</h2>

	<form:form method="post"
		action="${pageContext.request.contextPath}/country/add"
		commandName="country">
		<jsp:include flush="true" page="country_form.jsp">
			<jsp:param name="adduser" value="true" />
		</jsp:include>
	</form:form>

	<h3>
		<spring:message code="label.countries" />
	</h3>
	<c:if test="${!empty countryList}">
		<table class="data">
			<tr>
				<th><spring:message code="label.name" /></th>
				<th> </th>
			</tr>
			<c:forEach items="${countryList}" var="country">
				<tr>
					<td>${country.name}</td>
					<td><a
						href="${pageContext.request.contextPath}/country/edit/${country.id}"><spring:message
								code="label.edit" /></a></td>
					<td><a
						href="${pageContext.request.contextPath}/country/delete/${country.id}"><spring:message
								code="label.delete" /></a></td>
				</tr>
			</c:forEach>
		</table>
	</c:if>

</body>
</html>

Перейдемо до класу User:

User.java

package com.seostella.spring.domain.user;

import javax.persistence.*;

import com.seostella.spring.domain.Country;

/**
 * 
 * @author seostella.com
 */
@NamedQueries({
		@NamedQuery(name = User.NamedQuery.USER_FIND_ALL, query = "from User"),
		@NamedQuery(name = User.NamedQuery.USER_FIND_BY_ID, query = "from User where id = :id") })
@NamedNativeQueries({ 
	@NamedNativeQuery(name = User.NamedQuery.USER_FIND_BY_NAME, query = "select * from hb_user where name like :name", resultClass = User.class) })
@Entity
@Table(name = "hb_user")
public class User {
	@Id
	@GeneratedValue
	private long id;

	@Column(name = "name", unique = true, nullable = false)
	private String name;

	@Column(nullable = false)
	private String password;

	@Column(columnDefinition = "enum('male','female')")
	@Enumerated(EnumType.STRING)
	private Gender gender = Gender.male;

	@ManyToOne
	@JoinColumn(name = "country_id")
	private Country country;
	private Boolean subscribed;

	public User() {
	}

	public User(String name, String password) {
		this.name = name;
		this.password = password;
	}

	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 long getId() {
		return id;
	}

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

	public Country getCountry() {
		return country;
	}

	public Gender getGender() {
		return gender;
	}

	public void setCountry(Country country) {
		this.country = country;
	}

	public void setGender(Gender gender) {
		this.gender = gender;
	}

	public Boolean getSubscribed() {
		return subscribed;
	}

	public void setSubscribed(Boolean subscribed) {
		this.subscribed = subscribed;
	}

	public static class NamedQuery {
		public static final String USER_FIND_ALL = "User.findAll";
		public static final String USER_FIND_BY_ID = "User.findById";
		public static final String USER_FIND_BY_NAME = "User.findByName";
	}
}


@NamedQueries({
		@NamedQuery(name = User.NamedQuery.USER_FIND_ALL, query = "from User"),
		@NamedQuery(name = User.NamedQuery.USER_FIND_BY_ID, query = "from User where id = :id") })
@NamedNativeQueries({ 
	@NamedNativeQuery(name = User.NamedQuery.USER_FIND_BY_NAME, query = "select * from hb_user where name like :name", resultClass = User.class) })

- іменовані запити, один з яких, USER_FIND_BY_NAME, є "сирим" запитом. Об'єкти Query для подібних запитів формуються наступним способом:


Query q = sessionFactory.getCurrentSession().getNamedQuery( User.NamedQuery.USER_FIND_BY_ID );

Інші елементи цього класу розглядалися у статті Основи Hibernate 3 на прикладі роботи з MySQL.

Класи UserDAO і UserDAOImpl:

UserDAO.java

package com.seostella.spring.dao;

import com.seostella.spring.domain.user.User;
import java.util.List;

/**
 * 
 * @author seostella.com
 */
public interface UserDAO {

    public void saveUser(User user);

    public List<User> userList();

    public void removeUser(Long id);

    public User retriveUser(Long id);
    
    public List<User> findUsersByName(String name);
}

UserDAOImpl.java

package com.seostella.spring.dao;

import com.seostella.spring.domain.Country;
import com.seostella.spring.domain.user.User;
import com.seostella.spring.service.CountryService;

import java.util.List;
import org.hibernate.Query;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

/**
 * 
 * @author seostella.com
 */
@Repository
public class UserDAOImpl implements UserDAO {
	@Autowired
	CountryService countryService;

    @Autowired
    private SessionFactory sessionFactory;

    public void saveUser(User user) {
    	Country country = countryService.retriveCountry( user.getCountry().getId() );
    	user.setCountry(country);
    	
        sessionFactory.getCurrentSession().saveOrUpdate(user);
    }

    @SuppressWarnings("unchecked")
	public List<User> userList() {
        return sessionFactory.getCurrentSession().getNamedQuery( User.NamedQuery.USER_FIND_ALL ).list();
    }

    public void removeUser(Long id) {
        User user = (User) sessionFactory.getCurrentSession().load(
                User.class, id);
        if (null != user) {
            sessionFactory.getCurrentSession().delete(user);
        }
    }
    
    public User retriveUser(Long id){
        Query q = sessionFactory.getCurrentSession().getNamedQuery( User.NamedQuery.USER_FIND_BY_ID );
        q.setLong("id", id);
        return (User) q.uniqueResult();
    }

    @SuppressWarnings("unchecked")
	public List<User> findUsersByName(String name){
        Query q = sessionFactory.getCurrentSession().getNamedQuery( User.NamedQuery.USER_FIND_BY_NAME );
        q.setString("name", "%" + name + "%");
        return (List<User>) q.list();
    }
}

Класи UserService і UserServiceImpl:

UserService.java

package com.seostella.spring.service;

import com.seostella.spring.domain.user.User;
import java.util.List;

/**
 * 
 * @author seostella.com
 */
public interface UserService {

	public void saveUser(User user);

	public List<User> userList();

	public void removeUser(Long id);

	public User retriveUser(Long id);

	public List<User> findUsersByName(String name);
}

UserServiceImpl.java

package com.seostella.spring.service;

import com.seostella.spring.dao.UserDAO;
import com.seostella.spring.domain.user.User;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 
 * @author seostella.com
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDAO userDAO;

    @Transactional
    public void saveUser(User user) {
        userDAO.saveUser(user);
    }

    @Transactional
    public List<User> userList() {
        return userDAO.userList();
    }

    @Transactional
    public void removeUser(Long id) {
        userDAO.removeUser(id);
    }
    
    @Transactional
    public User retriveUser(Long id){
        return userDAO.retriveUser(id);
    }
    
    @Transactional
    public List<User> findUsersByName(String name){
    	return userDAO.findUsersByName( name );
    }
}

UserController і jsp-файли:

UserController.java

package com.seostella.spring.controller;

import com.seostella.spring.domain.user.User;
import com.seostella.spring.service.CountryService;
import com.seostella.spring.service.UserService;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * 
 * @author seostella.com
 */
@Controller
public class UserController {

    @Autowired
    private UserService userService;
    @Autowired
    private CountryService countryService;

    @RequestMapping("/user/index")
    public String listUsers(Map<String, Object> map) {

        map.put("user", new User());
        map.put("findUser", new User());
        map.put("userList", userService.userList());
        map.put("countryList", countryService.countryList());

        return "user_list";
    }

    @RequestMapping(value = "/user/add", method = RequestMethod.POST)
    public String addUser(@ModelAttribute("user") User user, BindingResult result) {

        userService.saveUser(user);

        return "redirect:/user/index";
    }

    @RequestMapping("/user/delete/{userId}")
    public String deleteUser(@PathVariable("userId") Long userId) {

        userService.removeUser(userId);

        return "redirect:/user/index";
    }
    
    @RequestMapping("/user/save")
    public String saveUser(@ModelAttribute("user") User user, BindingResult result) {

        userService.saveUser(user);

        return "redirect:/user/edit/" + user.getId();
    }
    
    @RequestMapping("/user/edit/{userId}")
    public String editUser(@PathVariable("userId") Long userId, Map<String, Object> map) {

        User user = userService.retriveUser(userId);
        map.put("user", user); 
        map.put("countryList", countryService.countryList());

        return "user_edit";
    }
    
    @RequestMapping("/user/find")
    public String findUsers(@ModelAttribute("findUser") User user, BindingResult result, Map<String, Object> map) {

    	map.put("userList", userService.findUsersByName( user.getName() ) );
        map.put("user", new User());

        return "user_list";
    }
}

user_edit.jsp

<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>Spring Hibernate Example</title>
</head>
<body>
	<jsp:include flush="false" page="menu.jsp" />

	<h2>Edit '${user.name}' from ${user.country.name}</h2>

	<form:form method="post"
		action="${pageContext.request.contextPath}/user/save"
		commandName="user">
		<form:hidden path="id" />
		<jsp:include flush="true" page="user_form.jsp" />
	</form:form>

	<a href="${pageContext.request.contextPath}/user/index"
		title="User List">User List</a>
</body>
</html>

user_form.jsp

<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
    <table>
        <tr>
            <td><form:label path="name"><spring:message code="label.name"/></form:label></td>
        <td><form:input path="name" /></td>
        </tr>
        <tr>
            <td><form:label path="password"><spring:message code="label.password"/></form:label></td>
        <td><form:input path="password" /></td>
        </tr>
        <tr>
            <td><form:label path="gender"><spring:message code="label.gender"/></form:label></td>
        <td>
        <form:radiobutton path="gender" value="male" /><spring:message code="label.male"/>
        <form:radiobutton path="gender" value="female" /><spring:message code="label.female"/>
        </td>
        </tr>
        <tr>
            <td><form:label path="country"><spring:message code="label.country"/></form:label></td>
        <td>
            <form:select path="country.id">
            	<form:option value="0" label="Select" />
            	<form:options items="${countryList}" itemValue="id" itemLabel="name" />
            </form:select>
        </td>
        </tr>
        <tr>
            <td><form:label path="subscribed"><spring:message code="label.subscribed"/></form:label></td>
        <td><form:checkbox path="subscribed" label="Would you like to join our mailinglist?" /></td>
        </tr>
        <tr>
            <td colspan="2">
                <input type="submit" value="<spring:message code="label.saveuser"/>"/>
            </td>
        </tr>
    </table>

user_list.jsp

<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>Spring Hibernate Example</title>
</head>
<body>
	<jsp:include flush="false" page="menu.jsp" />

	<h2>User List</h2>


	<form:form method="post"
		action="${pageContext.request.contextPath}/user/add"
		commandName="user">
		<jsp:include flush="true" page="user_form.jsp">
			<jsp:param name="adduser" value="true" />
		</jsp:include>
	</form:form>

	<h3>Find user: </h3>
	<form:form method="post"
		action="${pageContext.request.contextPath}/user/find"
		commandName="findUser">
        <form:label path="name"><spring:message code="label.name"/></form:label>
        <form:input path="name" />
        <input type="submit" value="<spring:message code="label.go"/>"/>
	</form:form>

	<h3>
		<spring:message code="label.users" />
	</h3>
	<c:if test="${!empty userList}">
		<table class="data">
			<tr>
				<th><spring:message code="label.name" /></th>
				<th><spring:message code="label.password" /></th>
				<th><spring:message code="label.gender" /></th>
				<th><spring:message code="label.country" /></th>
				<th><spring:message code="label.subscribed" /></th>
				<th> </th>
			</tr>
			<c:forEach items="${userList}" var="user">
				<tr>
					<td>${user.name}</td>
					<td>${user.password}</td>
					<td>${user.gender}</td>
					<td>${user.country.name}</td>
					<td>${user.subscribed}</td>
					<td><a
						href="${pageContext.request.contextPath}/user/edit/${user.id}"><spring:message
								code="label.edit" /></a></td>
					<td><a
						href="${pageContext.request.contextPath}/user/delete/${user.id}"><spring:message
								code="label.delete" /></a></td>
				</tr>
			</c:forEach>
		</table>
	</c:if>

</body>
</html>

Також представимо допоміжний клас HomeController і jsp-файли: home.jsp і menu.jsp:

HomeController.java

package com.seostella.spring.controller;

import java.util.Locale;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * 
 * @author seostella.com
 */
@Controller
public class HomeController {

    @RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		return "home";
	}
	
}

home.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ page session="false"%>
<html>
<head>
<title>Home</title>
</head>
<body>
	<jsp:include flush="false" page="menu.jsp" />
	<h2>Home page ${user.name}</h2>
</body>
</html>

menu.jsp

<a href="${pageContext.request.contextPath}/" title="Home">Home</a>
<a href="${pageContext.request.contextPath}/user/index" title="User List">User List</a>
<a href="${pageContext.request.contextPath}/country/index" title="Country List">Country List</a>
<hr>

Завантажити код програми можна за наступним посиланням - Завантажити spring-hibernate.zip

< Spring 3 і Hibernate 3. Частина 1

Коментарі (1)

andydoroga1989
29 листопада 2012 р. 02:38
Добавлять надо либы какие ещё? Не запускается ни в 6 томкате, ни в 7. Также в родном STS. 100500 ошибок. 10 часов жизни убил на этот пример.
Ви повинні увійти під своїм аккаунтом щоб залишати коментарі