乐者为王

Do one thing, and do it well.

实现用户注册功能

已经两个星期没有更新代码了,这次来给加上用户注册的功能。

先在User.java中添加confirmPassword字段。然后在UserDao.java中添加保存用户的代码:

1
2
3
4
5
6
7
8
9
10
11
public void addUser(User user) {
    Session session = sessionFactory.openSession();
    Transaction ts = null;
    try {
        ts = session.beginTransaction();
        session.save(user);
        ts.commit();
    } finally {
        session.close();
    }
}

在UserService.java中添加以下代码:

1
2
3
4
5
6
7
public void addUser(User user) throws UserAlreadyExistsException {
    User u = getUser(user.getUsername());
    if (u != null) {
        throw new UserAlreadyExistsException();
    }
    userDao.addUser(user);
}

其中UserAlreadyExistsException.java代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.codemany.account.service;

public class UserAlreadyExistsException extends Exception {
    private static final long serialVersionUID = -7518737598462419360L;

    public UserAlreadyExistsException() {
        super();
    }

    public UserAlreadyExistsException(String message) {
        super(message);
    }

    public UserAlreadyExistsException(String message, Throwable cause) {
        super(message, cause);
    }

    public UserAlreadyExistsException(Throwable cause) {
        super(cause);
    }
}

在applicationContext.xml中加上一个bean:

1
2
3
<bean id="registerAction" class="com.codemany.account.action.RegisterAction" scope="prototype">
    <property name="userService" ref="userService" />
</bean>

然后在account.xml中添加register动作,并修改login动作相应的页面:

1
2
3
4
5
6
7
8
9
<action name="login" class="loginAction">
    <result name="success">/index.jsp</result>
    <result name="input">/login.jsp</result>
</action>

<action name="register" class="registerAction">
    <result name="success">/index.jsp</result>
    <result name="input">/register.jsp</result>
</action>

建立RegisterAction.java类:

1
2
3
4
5
6
7
8
9
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.codemany.account.action;

import com.codemany.account.model.User;
import com.codemany.account.service.UserAlreadyExistsException;
import com.codemany.account.service.UserService;

import com.opensymphony.xwork2.ActionSupport;

public class RegisterAction extends ActionSupport {
    private static final long serialVersionUID = 7021982816578678150L;

    private User user;

    private UserService userService;

    public String execute() throws Exception {
        try {
            userService.addUser(user);
        } catch (UserAlreadyExistsException e) {
            return INPUT;
        }
        return SUCCESS;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public void setUserService(UserService userService) {
        this.userService = userService;
    }
}

新建校验配置文件。先是对应RegisterAction类的RegisterAction-validation.xml配置:

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE validators PUBLIC
    "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
    "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">

<validators>
    <field name="user">
        <field-validator type="visitor">
            <param name="appendPrefix">true</param>
            <message />
        </field-validator>
    </field>
</validators>

这里的校验使用了visitor类型,它是用于检测action里的复合属性的。这里的复合属性是User对象,所以要在User.java同一个目录下建立校验配置文件User-validation.xml,内容如下:

1
2
3
4
5
6
7
8
9
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
<!DOCTYPE validators PUBLIC
    "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
    "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">

<validators>
    <field name="username">
        <field-validator type="requiredstring">
            <message>Username is required</message>
        </field-validator>
        <field-validator type="stringlength">
            <param name="minLength">2</param>
            <param name="maxLength">20</param>
            <message>Username must be between ${minLength} and ${maxLength} characters</message>
        </field-validator>
    </field>

    <field name="password">
        <field-validator type="requiredstring">
            <message>Password is required</message>
        </field-validator>
        <field-validator type="stringlength">
            <param name="minLength">6</param>
            <param name="maxLength">50</param>
            <message>Password must be between ${minLength} and ${maxLength} characters</message>
        </field-validator>
    </field>

    <field name="confirmPassword">
        <field-validator type="fieldexpression">
            <param name="expression">confirmPassword.equals(password)</param>
            <message>Password does not match the confirm password</message>
        </field-validator>
    </field>
</validators>

修改index.jsp,将登录表单移到单独的login.jsp页面中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>

<%@ taglib uri="/struts-tags" prefix="s" %>

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>JBookShelf</title>
</head>

<body>
    <s:if test="#session.logined">
        Welcome, you have logined. <a href="<%= request.getContextPath() %>/logout.action">Logout</a>
    </s:if>
    <s:else>
        <a href="<%= request.getContextPath() %>/login!input.action">Login</a> |
        <a href="<%= request.getContextPath() %>/register!input.action">Register</a>
    </s:else>
</body>
</html>

这里是登录页面login.jsp,首页index.jsp中的登录表单就是被移到这个文件中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>

<%@ taglib uri="/struts-tags" prefix="s" %>

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Login</title>
</head>

<body>
    <p>User: test/test</p>
    <s:form action="login">
        <s:textfield key="username" label="Username" />
        <s:password key="password" label="Password" />
        <s:submit value="Login" />
    </s:form>
</body>
</html>

注册页面register.jsp,负责生成注册时的表单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>

<%@ taglib uri="/struts-tags" prefix="s" %>

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Registration</title>
</head>

<body>
    <s:form action="register">
        <s:textfield key="user.username" label="Username" />
        <s:password key="user.password" label="Password" />
        <s:password key="user.confirmPassword" label="Password Confirmation" />
        <s:submit value="Register" />
    </s:form>
</body>
</html>

代码下载:https://github.com/dohkoos/JBookShelf

Comments