上一篇已经搭建好了开发环境,现在用一个简单的注册登录来体验一下S2SH。

1、建立一个实体类:user.java,在cn.dy.bean包新建class

 1 package cn.dy.bean;
 2 
 3 public class User {
 4     private Integer userId;
 5     private String userName;
 6     private String userPassword;
 7     private String trueName;
 8     private String peopleId;

 9     get()...set()...
10 }

2、建立hibernate配置文件,在cn.dy.bean包新建文件,命名为:User.hbm.xml,内容如下

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 4 <hibernate-mapping>
 5     <class name="cn.dy.bean.User" table="tb_user" catalog="learn">
 6         <id name="userId" type="integer">
 7             <column name="userId" />
 8             <generator class="identity" />
 9         </id>
10         <property name="userName" type="string">
11             <column name="userName" length="16" not-null="true">
12                 <comment>帐号</comment>
13             </column>
14         </property>
15         <property name="userPassword" type="string">
16             <column name="userPassword" length="50" not-null="true">
17                 <comment>密码</comment>
18             </column>
19         </property>
20         <property name="trueName" type="string">
21             <column name="trueName" length="20" not-null="true">
22                 <comment>真实姓名</comment>
23             </column>
24         </property>
25         <property name="peopleId" type="string">
26             <column name="peopleId" length="20" not-null="true">
27                 <comment>身份证号码</comment>
28             </column>
29         </property>
30     </class>
31 </hibernate-mapping>

注意第五行,class是映射的类,table是数据库对应的表名,如果不填的话,默认是和类名一致,catalog为数据库名称,下面的几行都比较简单,看看就明白,这里就不解释了。
注:使用hibernate注解可以省略这个User.hbm.xml文件,具体见另一篇文章:【待填】

3、检查一下配置是否成功,新建一个单元测试类,new>other>java>JUnit>JUnit Test Case,选择New JUnit 4 test把它放到刚才我们建立的cn.dy.test包里。命名为UserTest,然后选择setUpBeforeClass(),finish,然后加入相关的jar包(选择最后一项)。这里需要说的是为什么选择setUpBeforeClass(),因为我们想要测试,所以在测试类构建完成后,就想获取一个上下文,方便使用。至此,测试类代码如下,运行不报错,说明已经配置成功,然后打开数据库找到learns,发现里面已经建立了tb_user表。

 1 package cn.dy.test;
 2 
 3 import org.junit.BeforeClass;
 4 import org.junit.Test;
 5 import org.springframework.context.ApplicationContext;
 6 import org.springframework.context.support.ClassPathXmlApplicationContext;
 7 
 8 public class UserTest {
 9 
10     @BeforeClass
11     public static void setUpBeforeClass() throws Exception {    
12     }
13     
14     @Test
15     public void test() {
16         ApplicationContext act = new ClassPathXmlApplicationContext(
17         "file:WebRoot/WEB-INF/spring.xml");
18     }
19 }

注:spring文件的路径一定要注意,有人问了,为什么以前见的路径和这个不一样呢,这里我强调一下,如果你的spring配置文件放在WEB-INF文件夹下,就是用我的这个表现方式,如果你的spring配置文件在src下,直接使用spring.xml就好了。我建议还是放在WEB-INF文件夹下比较好,毕竟里面有数据库的配置代码,安全至上。


4、测试成功继续进行我们的小项目,首先把功能整理清楚,要实现的功能有:用户的注册、修改、删除、查找。也就是基本的操作。好,修改index.jsp文件,代码如下

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 <%@ taglib uri="/struts-tags" prefix="s"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 4 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 5     <head>
 6         <title>简单的注册页面</title>
 7     </head>
 8     <body>
 9         <s:form action="" namespace="" method="post">
10             <table>
11                 <tr>
12                     <td><label for="name">*帐号:</label></td>
13                     <td><s:textfield id="name" name="user.userName" value="" /></td>
14                 </tr>
15                 <tr>
16                     <td><label for="password">*密码:</label></td>
17                     <td><s:password id="password" name="user.userPassword" value="" /></td>
18                 </tr>
19                 <tr>
20                     <td><label for="repassword">*确认密码:</label></td>
21                     <td><s:password id="repassword" value="" name="repassword" /></td>
22                 </tr>
23                 <tr>
24                     <td><label for="true">*真实姓名:</label></td>
25                     <td><s:textfield id="true" name="user.trueName" value="" /></td>
26                 </tr>
27                 <tr>
28                     <td><label for="peopleId">*身份证号:</label></td>
29                     <td><s:textfield id="peopleId" name="user.peopleId" value="" /></td>
30                 </tr>
31                 <tr>
32                     <td>&nbsp;</td>
33                     <td><s:submit value="添加" /><s:reset value="重置" /></td>
34                 </tr>
35             </table>
36         </s:form>
37     </body>
38 </html>

注意:<s:textfield />标签里面的name属性值的格式,这样才能被action辨认,方便反射。index.jsp页面里面去掉了对于编码来说不必要的部分,比如说head不分的meta块,实际的web前端开发中,这一部分是及其重要的,涉及到SEO知识,大家了解这个关联就好,这里不做阐述。具体请见【待填】

5、在cn.dy.dao新建UserDao.java接口

 1 package cn.dy.dao;
 2 
 3 import java.util.List;
 4 import cn.dy.bean.User;
 5 
 6 public interface UserDao {
 7 
 8     public void insert(User user);
 9 
10     public User search(Integer userId);
11 
12     public void delete(Integer userIds);
13 
14     public List<User> list();
15 }

cn.dy.dao.impl新建UserDaoBean.java类,@Transactional声明这是事务方法,这就是基于注解方式配置事务;@Repository("userDao")注意这样写以后,后面调用的userDao,就是UserDaoBean.java,而不是UserDao.java。@Transactional(propagation = Propagation.NOT_SUPPORTED)很明显,查找是不需要事务处理的。只有需要提交的方法才需要事务处理,比如说:添加,删除,修改。

 1 package cn.dy.dao.impl;
 2 
 3 import java.util.List;
 4 import cn.dy.bean.User;
 5 import cn.dy.dao.UserDao;
 6 import javax.annotation.Resource;
 7 
 8 import org.hibernate.SessionFactory;
 9 import org.springframework.stereotype.Repository;
10 import org.springframework.transaction.annotation.Propagation;
11 import org.springframework.transaction.annotation.Transactional;
12 
13 @Repository("userDao")
14 @Transactional
15 public class UserDaoBean implements UserDao {
16 
17     @Resource
18     SessionFactory factory;
19 
20     @Override
21     public void delete(Integer userIds) {
22         // 不要使用get方法查找.效率很低,这里使用load方法
23         for (Integer userId : userIds) {
24             factory.getCurrentSession().delete(
25                     factory.getCurrentSession().load(User.class, userId));
26         }
27     }
28 
29     @Override
30     @Transactional(propagation = Propagation.NOT_SUPPORTED)
31     public User search(Integer userId) {
32         return (User) factory.getCurrentSession().get(User.class, userId);
33     }
34 
35     @SuppressWarnings("unchecked")
36     @Override
37     @Transactional(propagation = Propagation.NOT_SUPPORTED)
38     public List<User> list() {
39         return factory.getCurrentSession().createQuery("from User").list();
40     }
41 
42     @Override
43     public void insert(User user) {
44         // persist相当于save.而merge相当于saveOrUpdate
45         factory.getCurrentSession().persist(user);
46     }
47 }
48 

cn.dy.service新建UserService.java接口,这里大家都注意到了,和UserDao.java几乎完全相同,那为什么还需要多此一举呢?事实上,这是很有必要的,具体见:【待填】

 1 package cn.dy.service;
 2 
 3 import java.util.List;
 4 import cn.dy.bean.User;
 5 
 6 public interface UserService {
 7 
 8     public void insert(User user);
 9 
10     public User search(Integer userId);
11 
12     public void delete(Integer userIds);
13 
14     public List<User> list();
15 }

cn.dy.service.impl新建UserServiceBean.java类,注意这里的@Service("userService"),在测试类中反射时候,userService就是代表UserServiceBean.java类。

 1 package cn.dy.service.impl;
 2 
 3 import java.util.List;
 4 import javax.annotation.Resource;
 5 import org.springframework.stereotype.Service;
 6 import cn.dy.bean.User;
 7 import cn.dy.dao.UserDao;
 8 import cn.dy.service.UserService;
 9 
10 @Service("userService")
11 public class UserServiceBean implements UserService {
12 
13     @Resource
14     private UserDao userDao;
15 
16     public void setUserDao(UserDao userDao) {
17         this.userDao = userDao;
18     }
19 
20     @Override
21     public void delete(Integer userIds) {
22         userDao.delete(userIds);
23     }
24 
25     @Override
26     public User search(Integer userId) {
27         return userDao.search(userId);
28     }
29 
30     @Override
31     public List<User> list() {
32         return userDao.list();
33     }
34 
35     @Override
36     public void insert(User user) {
37         userDao.insert(user);
38     }
39 }
40 

6、数据层和业务层都已经建好了,最后建立action,在cn.dy.action新建UserAction.java类,@Controller注解这是个控制类,@Scope("prototype")设置这个类为非单例模式,什么时候设为非单例呢,当action中存放针对某个用户的信息时,如用户注册,就要用@Scope("prototype")避免默认的单例模式。如果想知道不设置这个会有什么后果,也很简单,去掉这一行代码,然后连续注册两个用户,你的答案就会出现。这里纠正一下网上某些文章的解决办法,有些文章说可以修改UserDaoBean.java类中的insert方法,修改persist(user)为merge(user);确实解决了不能连续注册的问题,但是..merge不等于persist,这样会有什么样的后果,留给大家自己先思考下。(我提示下,会有非常严重的资料同步问题,怎么发生的,自己思考吧),千万不要把persist换成merge!切记。

 1 package cn.dy.action;
 2 
 3 import javax.annotation.Resource;
 4 
 5 import org.springframework.context.annotation.Scope;
 6 import org.springframework.stereotype.Controller;
 7 import com.opensymphony.xwork2.ActionSupport;
 8 import cn.dy.bean.User;
 9 import cn.dy.service.UserService;
10 
11 @Controller
12 @Scope("prototype")
13 public class UserAction extends ActionSupport {
14     @Resource
15     UserService userService;
16     private User user;
17 
18     public User getUser() {
19         return user;
20     }
21 
22     public void setUser(User user) {
23         this.user = user;
24     }
25 
26     public String insert() {
27         return null;
28     }
29 }
30 

7、在struts配置文件里面配置action,好让表单提交的时候能找到相对应的路径。

1 <package name="user" namespace="/user" extends="struts-default">
2         <action name="op_*" class="userAction" method="{1}">
3             <result>/success.jsp</result>
4         </action>
5     </package>

op_*说明以op_开头的跳转都会到userAction,而那个星号所代表的单词就是userAction里面的方法名称,由method={1}映射,另外一个注意点就是result的跳转类型,这里因为是简单的项目,不会太详细解释,详情请移步【待填】

8、好了,现在开始扫尾,在和index.jsp同一级目录新建success.jsp文件,里面就写一句代码:注册成功,欢迎某某(如何获取action传过来的值?请移步【待填】)

 1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
 2 
 3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 4 <html>
 5   <head>
 6     <title>结果页面</title>
 7   </head>
 8   <body>
 9     注册成功,欢迎${requestScope.user.userName}
10   </body>
11 </html>
12 

index.jsp页面里面改变<s:form>的提交代码<s:form action="op_insert" namespace="/user" method="post">

UserAction里面的insert方法代码(SUCCESS是默认值,action必须继承com.opensymphony.xwork2.ActionSupport才能使用,其他默认值详见【待填】)

1     public String insert() {
2         userService.insert(user);
3         return SUCCESS;
4     }

9、测试,把项目部署到tomcat中,然后地址栏输入http://localhost:8080/DyEngima/,返回正确页面。

下面将要讨论的是注册页面的ajax验证,我这里是通过jQuery实现的。


      此文部分内容来源网络。如有侵犯您的版权问题,请来消息至电子邮件DyEngima&163.com(&换成@),经核实后会在文章内部标明来源。
转载请注明来源http://www.blogjava.net/DyEnigma/
签名:有能力、有担当、有情义的人才能称之为男人,而不是由性别决定。