VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > PHP >
  • 登录注册

经过这段时间的努力,我们对Spring框架已经有了基本认识。是时候按下暂停键,学以致用,写个简单的小项目巩固一下我们至今所学的知识了。

这个小项目名为come-in,是个Web应用程序,实现了登录注册的功能。因此,整个网站总共包含三个页面:一个登录页面;一个注册页面;一个欢迎页面。如下:

登录页面:

注册页面:

欢迎页面:

实现这个网站用到的知识都是前文介绍过的。我们不会在这里讨论实现这个小项目所用的知识,而是把重心放在项目的实现上。为此,请打开IntelliJ IDEA,新建项目come-in,开始我们的网站实现之旅。

01.编写SQL脚本,运行SQL脚本,创建数据库。

复制代码
 1 CREATE DATABASE come_in DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
 2 
 3 USE come_in;
 4 
 5 CREATE TABLE person (
 6   person_id       INT         NOT NULL AUTO_INCREMENT, # 数据库表ID
 7   person_phone    CHAR(11)    NOT NULL,                # 手机号码
 8   person_password CHAR(68)    NOT NULL,                # 密码
 9   person_name     VARCHAR(12) NOT NULL,                # 名字
10   person_time     TIMESTAMP   NOT NULL,                # 注册时间
11   PRIMARY KEY (person_id)                              # 添加主键
12 ) ENGINE = INNODB;
复制代码

02.在com.dream包下定义ErrorCode枚举。

复制代码
 1 package com.dream;
 2 
 3 public enum ErrorCode {
 4     SUCCESS(0),
 5     ERROR_FATAL(1),
 6     ERROR_DUPLICATE(2),
 7     ERROR_CREDENTIAL(3);
 8 
 9     private final int value;
10 
11     ErrorCode(int value) {
12         this.value = value;
13     }
14 
15     public int value() {
16         return value;
17     }
18 }
复制代码

03.在com.dream包下定义Converter类。

复制代码
 1 package com.dream;
 2 
 3 import java.util.*;
 4 import java.text.*;
 5 
 6 public final class Converter {
 7     private Converter() {}
 8 
 9     public static Integer toInteger(String value) {
10         try {
11             return value != null && value.length() > 0 ? Integer.parseInt(value) : null;
12         } catch (NumberFormatException e) {
13             return null;
14         }
15     }
16 
17     public static Date toDate(String value) {
18         try {
19             return value != null ? new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(value) : null;
20         } catch (ParseException e) {
21             return null;
22         }
23     }
24 }
复制代码

04.在com.dream包下定义Validator类。

复制代码
 1 package com.dream;
 2 
 3 import java.util.regex.*;
 4 
 5 public final class Validator {
 6     private static final String PATTERN_PHONE = "^1[0-9]{10}$";
 7 
 8     private Validator() {}
 9 
10     public static boolean validatePersonName(String value) {
11         if (value == null) {
12             return false;
13         }
14         if (value.length() > 12) {
15             return false;
16         }
17         return true;
18     }
19 
20     public static boolean validatePersonPhone(String value) {
21         if (value == null) {
22             return false;
23         }
24         if (!Pattern.compile(PATTERN_PHONE).matcher(value).matches()) {
25             return false;
26         }
27         return true;
28     }
29 
30     public static boolean validatePersonPassword(String value) {
31         if (value == null) {
32             return false;
33         }
34         if (value.length() < 6) {
35             return false;
36         }
37         if (value.length() > 48) {
38             return false;
39         }
40         return true;
41     }
42 }
复制代码

05.在com.dream.repository包下定义AddPerson接口。

1 package com.dream.repository;
2 
3 public interface AddPerson {
4     void access(String name, String phone, String password);
5 }

06.在com.dream.repository包下定义实现了AddPerson接口的AddPersonImpl类。

复制代码
 1 package com.dream.repository;
 2 
 3 import javax.sql.*;
 4 import org.springframework.jdbc.core.*;
 5 import org.springframework.stereotype.*;
 6 import org.springframework.beans.factory.annotation.*;
 7 
 8 @Repository
 9 public class AddPersonImpl implements AddPerson {
10     private static final String STATEMENT;
11     private JdbcTemplate jdbcTemplate = null;
12 
13     @Autowired
14     public void setJdbcTemplate(DataSource dataSource) {
15         this.jdbcTemplate = new JdbcTemplate(dataSource);
16     }
17 
18     @Override
19     public void access(String name, String phone, String password) {
20         this.jdbcTemplate.update(STATEMENT, preparedStatement -> {
21             preparedStatement.setString(1, phone);
22             preparedStatement.setString(2, password);
23             preparedStatement.setString(3, name);
24         });
25     }
26 
27     static {
28         STATEMENT = ""
29         + " INSERT INTO person"
30         + "   (person_phone, person_password, person_name, person_time)"
31         + " VALUES"
32         + "   (?, ?, ?, NOW())";
33     }
34 }
复制代码

07.在com.dream.repository包下定义CountPersonByPhone接口。

1 package com.dream.repository;
2 
3 public interface CountPersonByPhone {
4     int access(String phone);
5 }

08.在com.dream.repository包下定义实现了CountPersonByPhone接口的CountPersonByPhoneImpl类。

复制代码
 1 package com.dream.repository;
 2 
 3 import javax.sql.DataSource;
 4 import org.springframework.jdbc.core.*;
 5 import org.springframework.stereotype.*;
 6 import org.springframework.beans.factory.annotation.*;
 7 
 8 @Repository
 9 public class CountPersonByPhoneImpl implements CountPersonByPhone {
10     private static final String STATEMENT;
11     private JdbcTemplate jdbcTemplate = null;
12 
13     @Autowired
14     public void setJdbcTemplate(DataSource dataSource) {
15         this.jdbcTemplate = new JdbcTemplate(dataSource);
16     }
17 
18     @Override
19     public int access(String phone) {
20         return this.jdbcTemplate.query(STATEMENT, preparedStatement -> {
21             preparedStatement.setString(1, phone);
22         }, resultSet -> resultSet.next() ? resultSet.getInt(1) : 0);
23     }
24 
25     static {
26         STATEMENT = "SELECT COUNT(*) FROM person WHERE person_phone=?";
27     }
28 }
复制代码

09.在com.dream.repository包下定义QueryPersonByIdOut数据模型。

复制代码
 1 package com.dream.repository;
 2 
 3 import java.util.*;
 4 
 5 public class QueryPersonByIdOut {
 6     private int personId = 0;
 7     private String personName = null;
 8     private Date personTime = null;
 9 
10     public int getPersonId() {
11         return this.personId;
12     }
13 
14     public void setPersonId(int personId) {
15         this.personId = personId;
16     }
17 
18     public String getPersonName() {
19         return this.personName;
20     }
21 
22     public void setPersonName(String personName) {
23         this.personName = personName;
24     }
25 
26     public Date getPersonTime() {
27         return this.personTime;
28     }
29 
30     public void setPersonTime(Date personTime) {
31         this.personTime = personTime;
32     }
33 }
复制代码

10.在com.dream.repository包下定义QueryPersonById接口。

1 package com.dream.repository;
2 
3 public interface QueryPersonById {
4     QueryPersonByIdOut access(int id);
5 }

11.在com.dream.repository包下定义实现了QueryPersonById接口的QueryPersonByIdImpl类。

复制代码
 1 package com.dream.repository;
 2 
 3 import javax.sql.*;
 4 import org.springframework.jdbc.core.*;
 5 import org.springframework.stereotype.*;
 6 import org.springframework.beans.factory.annotation.*;
 7 import com.dream.*;
 8 
 9 @Repository
10 public class QueryPersonByIdImpl implements QueryPersonById {
11     private static final String STATEMENT;
12     private JdbcTemplate jdbcTemplate = null;
13 
14     @Autowired
15     public void setJdbcTemplate(DataSource dataSource) {
16         this.jdbcTemplate = new JdbcTemplate(dataSource);
17     }
18 
19     @Override
20     public QueryPersonByIdOut access(int id) {
21         return this.jdbcTemplate.query(STATEMENT, preparedStatement -> {
22             preparedStatement.setInt(1, id);
23         }, resultSet -> {
24             if (resultSet.next()) {
25                 var out = new QueryPersonByIdOut();
26                 out.setPersonId(resultSet.getInt(1));
27                 out.setPersonName(resultSet.getString(2));
28                 out.setPersonTime(Converter.toDate(resultSet.getString(3)));
29                 return out;
30             } else {
31                 return null;
32             }
33         });
34     }
35 
36     static {
37         STATEMENT = ""
38         + " SELECT"
39         + "   person_id, person_name, person_time"
40         + " FROM"
41         + "   person"
42         + " WHERE"
43         + "   person_id=?";
44     }
45 }
复制代码

12.在com.dream.repository包下定义QueryPersonIdByCredential接口。

1 package com.dream.repository;
2 
3 public interface QueryPersonIdByCredential {
4     int access(String phone, String password);
5 }

13.在com.dream.repository包下定义实现了QueryPersonIdByCredential接口的QueryPersonIdByCredentialImpl类。

复制代码
 1 package com.dream.repository;
 2 
 3 import javax.sql.*;
 4 import org.springframework.jdbc.core.*;
 5 import org.springframework.stereotype.*;
 6 import org.springframework.beans.factory.annotation.*;
 7 
 8 @Repository
 9 public class QueryPersonIdByCredentialImpl implements QueryPersonIdByCredential {
10     private static final String STATEMENT;
11     private JdbcTemplate jdbcTemplate = null;
12 
13     @Autowired
14     public void setJdbcTemplate(DataSource dataSource) {
15         this.jdbcTemplate = new JdbcTemplate(dataSource);
16     }
17 
18     @Override
19     public int access(String phone, String password) {
20         return this.jdbcTemplate.query(STATEMENT, preparedStatement -> {
21             preparedStatement.setString(1, phone);
22             preparedStatement.setString(2, password);
23         }, resultSet -> resultSet.next() ? resultSet.getInt(1) : 0);
24     }
25 
26     static {
27         STATEMENT = ""
28         + " SELECT"
29         + "   person_id"
30         + " FROM"
31         + "   person"
32         + " WHERE"
33         + "   person_phone=? AND person_password=?";
34     }
35 }
复制代码

14.在com.dream.service包下定义BaseResult数据模型父类。

复制代码
 1 package com.dream.service;
 2 
 3 import com.dream.*;
 4 
 5 public class BaseResult {
 6     private ErrorCode errorCode = ErrorCode.SUCCESS;
 7 
 8     public ErrorCode getErrorCode() {
 9         return this.errorCode;
10     }
11 
12     public BaseResult(ErrorCode errorCode) {
13         this.errorCode = errorCode;
14     }
15 }
复制代码

15.在com.dream.service包下定义ServiceLogonResult数据模型。

复制代码
 1 package com.dream.service;
 2 
 3 import com.dream.*;
 4 
 5 public class ServiceLogonResult extends BaseResult {
 6     private int personId = 0;
 7 
 8     public int getPersonId() {
 9         return this.personId;
10     }
11 
12     public void setPersonId(int personId) {
13         this.personId = personId;
14     }
15 
16     public ServiceLogonResult(ErrorCode errorCode) {
17         super(errorCode);
18     }
19 }
复制代码

16.在com.dream.service包下定义ServiceLogon接口。

1 package com.dream.service;
2 
3 public interface ServiceLogon {
4     ServiceLogonResult process(String phone, String password);
5 }

17.在com.dream.service包下定义实现了ServiceLogon接口的ServiceLogonImpl类。

复制代码
 1 package com.dream.service;
 2 
 3 import org.springframework.beans.factory.annotation.*;
 4 import org.springframework.stereotype.*;
 5 import com.dream.repository.*;
 6 import com.dream.*;
 7 
 8 @Service
 9 public class ServiceLogonImpl implements ServiceLogon {
10     private QueryPersonIdByCredential queryPersonIdByCredential = null;
11 
12     @Autowired
13     public void setQueryPersonIdByCredential(QueryPersonIdByCredential queryPersonIdByCredential) {
14         this.queryPersonIdByCredential = queryPersonIdByCredential;
15     }
16 
17     @Override
18     public ServiceLogonResult process(String phone, String password) {
19         if (!Validator.validatePersonPhone(phone)) {
20             return new ServiceLogonResult(ErrorCode.ERROR_FATAL);
21         }
22         if (!Validator.validatePersonPassword(password)) {
23             return new ServiceLogonResult(ErrorCode.ERROR_FATAL);
24         }
25 
26         var personId = queryPersonIdByCredential.access(phone, password);
27         if (personId <= 0) {
28             return new ServiceLogonResult(ErrorCode.ERROR_CREDENTIAL);
29         }
30 
31         var serviceResult = new ServiceLogonResult(ErrorCode.SUCCESS);
32         serviceResult.setPersonId(personId);
33         return serviceResult;
34     }
35 }
复制代码

18.在com.dream.service包下定义ServiceRegistry接口。

1 package com.dream.service;
2 
3 public interface ServiceRegistry {
4     BaseResult process(String name, String phone, String password, String confirm);
5 }

19.在com.dream.service包下定义实现了ServiceRegistry接口的ServiceRegistryImpl类。

复制代码
 1 package com.dream.service;
 2 
 3 import org.springframework.beans.factory.annotation.*;
 4 import org.springframework.stereotype.*;
 5 import com.dream.repository.*;
 6 import com.dream.*;
 7 
 8 @Service
 9 public class ServiceRegistryImpl implements ServiceRegistry {
10     private CountPersonByPhone countPersonByPhone = null;
11     private AddPerson addPerson = null;
12 
13     @Autowired
14     public void setCountPersonByPhone(CountPersonByPhone countPersonByPhone) {
15         this.countPersonByPhone = countPersonByPhone;
16     }
17 
18     @Autowired
19     public void setAddPerson(AddPerson addPerson) {
20         this.addPerson = addPerson;
21     }
22 
23     @Override
24     public BaseResult process(String name, String phone, String password, String confirm) {
25         if(!Validator.validatePersonName(name)) {
26             return new BaseResult(ErrorCode.ERROR_FATAL);
27         }
28         if(!Validator.validatePersonPhone(phone)) {
29             return new BaseResult(ErrorCode.ERROR_FATAL);
30         }
31         if(!Validator.validatePersonPassword(password)) {
32             return new BaseResult(ErrorCode.ERROR_FATAL);
33         }
34         if(!password.equals(confirm)) {
35             return new BaseResult(ErrorCode.ERROR_FATAL);
36         }
37         if(this.countPersonByPhone.access(phone) > 0) {
38             return new BaseResult(ErrorCode.ERROR_DUPLICATE);
39         }
40 
41         this.addPerson.access(name, phone, password);
42         return new BaseResult(ErrorCode.SUCCESS);
43     }
44 }
复制代码

20.在com.dream.service包下定义ServicePersonInfoResult数据模型。

复制代码
 1 package com.dream.service;
 2 
 3 import java.util.*;
 4 import com.dream.*;
 5 
 6 public class ServicePersonInfoResult extends BaseResult {
 7     private int personId = 0;
 8     private String personName = null;
 9     private Date personTime = null;
10 
11     public int getPersonId() {
12         return this.personId;
13     }
14 
15     public void setPersonId(int personId) {
16         this.personId = personId;
17     }
18 
19     public String getPersonName() {
20         return this.personName;
21     }
22 
23     public void setPersonName(String personName) {
24         this.personName = personName;
25     }
26 
27     public Date getPersonTime() {
28         return this.personTime;
29     }
30 
31     public void setPersonTime(Date personTime) {
32         this.personTime = personTime;
33     }
34 
35     public ServicePersonInfoResult(ErrorCode errorCode) {
36         super(errorCode);
37     }
38 }
复制代码

21.在com.dream.service包下定义ServicePersonInfo接口。

1 package com.dream.service;
2 
3 public interface ServicePersonInfo {
4     ServicePersonInfoResult process(String personId);
5 }

22.在com.dream.service包下定义实现了ServicePersonInfo接口的ServicePersonInfoImpl类。

复制代码
 1 package com.dream.service;
 2 
 3 import org.springframework.beans.factory.annotation.*;
 4 import org.springframework.stereotype.*;
 5 import com.dream.repository.*;
 6 import com.dream.*;
 7 
 8 @Service
 9 public class ServicePersonInfoImpl implements ServicePersonInfo {
10     private QueryPersonById queryPersonById = null;
11 
12     @Autowired
13     public void setQueryPersonById(QueryPersonById queryPersonById) {
14         this.queryPersonById = queryPersonById;
15     }
16 
17     @Override
18     public ServicePersonInfoResult process(String personId) {
19         var id = Converter.toInteger(personId);
20         if (id == null) {
21             return new ServicePersonInfoResult(ErrorCode.ERROR_FATAL);
22         }
23 
24         var person = this.queryPersonById.access(id);
25         if (person == null) {
26             return new ServicePersonInfoResult(ErrorCode.ERROR_CREDENTIAL);
27         }
28 
29         var personInfoResult = new ServicePersonInfoResult(ErrorCode.SUCCESS);
30         personInfoResult.setPersonId(person.getPersonId());
31         personInfoResult.setPersonName(person.getPersonName());
32         personInfoResult.setPersonTime(person.getPersonTime());
33         return personInfoResult;
34     }
35 }
复制代码

23.在com.dream.controller包下定义ControlLogon类。

复制代码
 1 package com.dream.controller;
 2 
 3 import org.springframework.beans.factory.annotation.*;
 4 import org.springframework.web.bind.annotation.*;
 5 import org.springframework.web.context.request.*;
 6 import org.springframework.stereotype.*;
 7 import com.dream.service.*;
 8 
 9 @Controller
10 public class ControlLogon {
11     private ServiceLogon serviceLogon = null;
12 
13     @Autowired
14     public void setServiceLogon(ServiceLogon serviceLogon) {
15         this.serviceLogon = serviceLogon;
16     }
17 
18     @ResponseBody
19     @RequestMapping(value = "/logon", method = RequestMethod.POST)
20     public ServiceLogonResult visit(WebRequest request) {
21         var phone = request.getParameter("phone");;
22         var password = request.getParameter("password");
23         return this.serviceLogon.process(phone, password);
24     }
25 }
复制代码

24.在com.dream.controller包下定义ControlRegistry类。

复制代码
 1 package com.dream.controller;
 2 
 3 import org.springframework.beans.factory.annotation.*;
 4 import org.springframework.web.bind.annotation.*;
 5 import org.springframework.web.context.request.*;
 6 import org.springframework.stereotype.*;
 7 import com.dream.service.*;
 8 
 9 @Controller
10 public class ControlRegistry {
11     private ServiceRegistry serviceRegistry = null;
12 
13     @Autowired
14     public void setServiceRegistry(ServiceRegistry serviceRegistry) {
15         this.serviceRegistry = serviceRegistry;
16     }
17 
18     @ResponseBody
19     @RequestMapping(value = "/registry", method = RequestMethod.POST)
20     public BaseResult visit(WebRequest request) {
21         var name = request.getParameter("name");
22         var phone = request.getParameter("phone");
23         var password = request.getParameter("password");
24         var confirm = request.getParameter("confirm");
25         return this.serviceRegistry.process(name, phone, password, confirm);
26     }
27 }
复制代码

25.在com.dream.controller包下定义ControlPersonInfo类。

复制代码
 1 package com.dream.controller;
 2 
 3 import org.springframework.beans.factory.annotation.*;
 4 import org.springframework.web.bind.annotation.*;
 5 import org.springframework.web.context.request.*;
 6 import org.springframework.stereotype.*;
 7 import com.dream.service.*;
 8 
 9 @Controller
10 public class ControlPersonInfo {
11     private ServicePersonInfo servicePersonInfo = null;
12 
13     @Autowired
14     public void setServicePersonInfo(ServicePersonInfo servicePersonInfo) {
15         this.servicePersonInfo = servicePersonInfo;
16     }
17 
18     @ResponseBody
19     @RequestMapping(value = "/person_info", method = RequestMethod.POST)
20     public ServicePersonInfoResult visit(WebRequest request) {
21         var personId = request.getParameter("personId");
22         return this.servicePersonInfo.process(personId);
23     }
24 }
复制代码

26.在/come-in/web/WEB-INF/目录里添加web.xml文件。

复制代码
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="
 5          http://xmlns.jcp.org/xml/ns/javaee
 6          http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
 7          version="4.0">
 8 
 9     <context-param>
10         <param-name>contextConfigLocation</param-name>
11         <param-value>/WEB-INF/config/root-config.xml</param-value>
12     </context-param>
13     <listener>
14         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
15     </listener>
16 
17     <servlet>
18         <servlet-name>dispatcherServlet</servlet-name>
19         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
20         <init-param>
21             <param-name>contextConfigLocation</param-name>
22             <param-value>/WEB-INF/config/servlet-config.xml</param-value>
23         </init-param>
24         <load-on-startup>1</load-on-startup>
25     </servlet>
26     <servlet-mapping>
27         <servlet-name>dispatcherServlet</servlet-name>
28         <url-pattern>/</url-pattern>
29     </servlet-mapping>
30 </web-app>
复制代码

27.在/come-in/web/WEB-INF/config/目录里添加servlet-config.xml文件。

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.0.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <mvc:annotation-driven />
    <mvc:default-servlet-handler />
    <context:component-scan base-package="com.dream.controller" />

</beans>
复制代码

28.在/come-in/web/WEB-INF/config/目录里添加root-config.xml文件。

复制代码
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:context="http://www.springframework.org/schema/context"
 5        xsi:schemaLocation="
 6        http://www.springframework.org/schema/beans
 7        http://www.springframework.org/schema/beans/spring-beans.xsd
 8        http://www.springframework.org/schema/context
 9        http://www.springframework.org/schema/context/spring-context-4.0.xsd">
10 
11     <context:component-scan base-package="com.dream.repository,com.dream.service" />
12     <bean class="org.apache.commons.dbcp2.BasicDataSource">
13         <property name="username" value="root" />
14         <property name="password" value="123456" />
15         <property name="url" value="jdbc:mysql://localhost:3306/come_in" />
16         <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
17     </bean>
18 
19 </beans>
复制代码

29.在/come-in/web/目录里添加index.html文件。

复制代码
 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title>登录</title>
 5     <meta charset="UTF-8">
 6     <link rel="stylesheet" type="text/css" href="style/global.css">
 7     <link rel="stylesheet" type="text/css" href="style/index.css">
 8 </head>
 9 <body>
10     <div id="logon-box">
11         <div class="-title-box">
12             <h1>登陆</h1>
13         </div>
14         <div id="logon-body-box">
15             <div class="-input-item">
16                 <label id="logon-phone-hint" for="logon-phone-text">手机</label>
17                 <input id="logon-phone-text" type="text" maxlength="48">
18             </div>
19             <div class="-input-item">
20                 <label id="logon-password-hint" for="logon-password-text">密码</label>
21                 <input id="logon-password-text" type="password" maxlength="48">
22             </div>
23             <div class="-button-item">
24                 <input id="logon-button" class="-button" type="button" value="登陆">
25             </div>
26         </div>
27         <div id="logon-foot-box">
28             <label for="logon-registry-button">没有账号?</label>
29             <input id="logon-registry-button" type="button" value="马上注册">
30         </div>
31     </div>
32     <div id="registry-box">
33         <div class="-modal"></div>
34         <div id="registry-workbench-box" class="-modal-body">
35             <div class="-title-box">
36                 <h1>注册</h1>
37             </div>
38             <div id="registry-body-box">
39                 <div class="-input-item">
40                     <label id="registry-name-hint" for="registry-name-text">名字</label>
41                     <input id="registry-name-text" type="text" maxlength="48">
42                 </div>
43                 <div class="-input-item">
44                     <label id="registry-phone-hint" for="registry-phone-text">手机</label>
45                     <input id="registry-phone-text" type="text" maxlength="48">
46                 </div>
47                 <div class="-input-item">
48                     <label id="registry-password-hint" for="registry-password-text">密码</label>
49                     <input id="registry-password-text" type="password" maxlength="48">
50                 </div>
51                 <div class="-input-item">
52                     <label id="registry-confirm-hint" for="registry-confirm-text">密码确认</label>
53                     <input id="registry-confirm-text" type="password" maxlength="48">
54                 </div>
55                 <div class="-button-item">
56                     <input id="registry-ok-button" class="-button" type="button" value="注册">
57                     <input id="registry-cancel-button" class="-button" type="button" value="取消">
58                 </div>
59             </div>
60         </div>
61     </div>
62 
63     <script type="text/javascript" src="script/index.js"></script>
64 </body>
65 </html>
复制代码

30.在/come-in/web/style/目录里添加global.css文件。

复制代码
 1 @charset "UTF-8";
 2 * {
 3   margin:0;
 4   padding:0;
 5 }
 6 html {
 7   width:100%;
 8   height:100%;
 9   background-color:white;
10 }
11 body {
12   width:100%;
13   min-height:100%;
14   background-color:white;
15   background-repeat:no-repeat;
16   background-position:center;
17   font:14px/24px "Microsoft Yahei",微软雅黑,Arial,arial,SimSun,simsun;
18   font-weight:normal;
19   color:#333333;
20 }
21 a {
22   color:#3b5999;
23   text-decoration:none;
24   outline:none;
25 }
26 a:hover {
27   color:#699857;
28 }
29 img {
30   border-width:0;
31 }
32 input {
33   outline:none;
34 }
35 input[type=text]::-ms-clear {
36   display:none;
37 }
38 input[type=button] {
39   appearance:none;
40   -moz-appearance:none;
41   -webkit-appearance:none;
42   border-radius:0;
43 }
44 textarea {
45   resize:none;
46   outline:none;
47 }
48 strong {
49   font-style:normal;
50   font-weight:bold;
51 }
52 h1,h2,h3,h4,h5,h6 {
53   font-size:100%;
54   font-weight:bold;
55 }
56 input,button,textarea,select,optgroup,option {
57   font-family:inherit;
58   font-size:inherit;
59   font-style:inherit;
60   font-weight:inherit;
61 }
62 .-button {
63   height:40px;
64   border-width:0;
65   font-size:16px;
66   font-weight:bold;
67   line-height:40px;
68   background-color:#558543;
69   color:white;
70   cursor:pointer;
71 }
72 .-button:hover {
73   background-color:#699857;
74 }
75 .-clear:after {
76   content:"\200B";
77   display:block;
78   height:0;
79   clear:both;
80 }
81 .-clear {
82   *zoom:1;
83 }
84 .-modal {
85   position:fixed;
86   top:0;
87   left:0;
88   right:0;
89   bottom:0;
90   opacity:0.3;
91   filter:alpha(opacity=30);
92   background-color:#333333;
93   z-index:90000000;
94 }
95 .-modal-body {
96   position:fixed;
97   background-color:#e9ebee;
98   z-index:91000000;
99 }
复制代码

31.在/come-in/web/style/目录里添加index.css文件。

复制代码
  1 @charset "UTF-8";
  2 body {
  3     position:relative;
  4 }
  5 #logon-box {
  6     float:left;
  7     width:354px;
  8     height:399px;
  9     margin:60px;
 10     border-bottom:9px solid #3b5999;
 11     background-color:#e9ebee;
 12 }
 13 #logon-body-box {
 14     width:auto;
 15     height:258px;
 16     padding:18px 18px 0px;
 17 }
 18 #logon-button {
 19     width:100%;
 20 }
 21 #logon-foot-box {
 22     width:auto;
 23     height:20px;
 24     padding:16px 18px;
 25     font-size:14px;
 26     line-height:20px;
 27 }
 28 #logon-foot-box label {
 29     float:left;
 30     cursor:pointer;
 31 }
 32 #logon-foot-box input {
 33     width:auto;
 34     height:20px;
 35     border-width:0px;
 36     font-size:14px;
 37     line-height:20px;
 38     background-color:transparent;
 39     color:#3b5999;
 40     cursor:pointer;
 41 }
 42 #logon-foot-box input:hover {
 43     color:#699857;
 44 }
 45 #logon-registry-button {
 46     float:left;
 47 }
 48 #registry-box {
 49     display:none;
 50 }
 51 #registry-workbench-box {
 52     top:142px;
 53     left:50%;
 54     width:354px;
 55     height:380px;
 56     margin-left:-177px;
 57 }
 58 #registry-body-box {
 59     width:auto;
 60     height:290px;
 61     padding:18px 18px 0px;
 62 }
 63 #registry-ok-button {
 64     float:right;
 65     width:254px;
 66 }
 67 #registry-cancel-button {
 68     float:left;
 69     width:58px;
 70 }
 71 .-title-box {
 72     width:auto;
 73     height:72px;
 74     padding:0px 18px;
 75     font-size:36px;
 76     line-height:72px;
 77     background-color:#3b5999;
 78     color:white;
 79 }
 80 .-title-box h1 {
 81     font-weight:normal;
 82 }
 83 .-input-item {
 84     position:relative;
 85     width:auto;
 86     height:38px;
 87     margin-bottom:18px;
 88     border:1px solid #888888;
 89     background-color:white;
 90 }
 91 .-input-item label {
 92     position:absolute;
 93     top:0px;
 94     left:0px;
 95     width:auto;
 96     height:38px;
 97     padding:0px 9px;
 98     font-size:14px;
 99     line-height:38px;
100     color:#888888;
101     z-index:100;
102 }
103 .-input-item input {
104     position:absolute;
105     top:0px;
106     left:0px;
107     width:298px;
108     height:38px;
109     padding:0px 9px;
110     border-width:0px;
111     font-size:14px;
112     line-height:18px;
113     background-color:transparent;
114     color:#333333;
115     z-index:110;
116 }
117 .-button-item {
118     position:relative;
119     width:auto;
120     height:40px;
121 }
复制代码

32.在/come-in/web/script/目录里添加index.js文件。

复制代码
  1 window.onload = function() {
  2     let logonPhoneText = document.getElementById("logon-phone-text");
  3     let logonPasswordText = document.getElementById("logon-password-text");
  4     let logonButton = document.getElementById("logon-button");
  5     let logonRegistryButton = document.getElementById("logon-registry-button");
  6     let registryNameText = document.getElementById("registry-name-text");
  7     let registryPhoneText = document.getElementById("registry-phone-text");
  8     let registryPasswordText = document.getElementById("registry-password-text");
  9     let registryConfirmText = document.getElementById("registry-confirm-text");
 10     let registryOkButton = document.getElementById("registry-ok-button");
 11     let registryCancelButton = document.getElementById("registry-cancel-button");
 12 
 13     logonPhoneText.onfocus = onLogonPhoneTextFocus;
 14     logonPhoneText.onblur = onLogonPhoneTextBlur;
 15     logonPasswordText.onfocus = onLogonPasswordTextFocus;
 16     logonPasswordText.onblur = onLogonPasswordTextBlur;
 17     logonButton.onclick = onLogonButtonClick;
 18     logonRegistryButton.onclick = onLogonRegistryButtonClick;
 19     registryNameText.onfocus = onRegistryNameTextFocus;
 20     registryNameText.onblur = onRegistryNameTextBlur;
 21     registryPhoneText.onfocus = onRegistryPhoneTextFocus;
 22     registryPhoneText.onblur = onRegistryPhoneTextBlur;
 23     registryPasswordText.onfocus = onRegistryPasswordTextFocus;
 24     registryPasswordText.onblur = onRegistryPasswordTextBlur;
 25     registryConfirmText.onfocus = onRegistryConfirmTextFocus;
 26     registryConfirmText.onblur = onRegistryConfirmTextBlur;
 27     registryOkButton.onclick = onRegistryOkButtonClick;
 28     registryCancelButton.onclick = onRegistryCancelButtonClick;
 29 }
 30 
 31 function onLogonPhoneTextFocus() {
 32     let logonPhoneHint = document.getElementById("logon-phone-hint");
 33     logonPhoneHint.style.display = "none";
 34 }
 35 
 36 function onLogonPhoneTextBlur() {
 37     let logonPhoneText = document.getElementById("logon-phone-text");
 38     let logonPhoneHint = document.getElementById("logon-phone-hint");
 39     logonPhoneHint.style.display = (logonPhoneText.value.length === 0 ? "block" : "none");
 40 }
 41 
 42 function onLogonPasswordTextFocus() {
 43     let logonPasswordHint = document.getElementById("logon-password-hint");
 44     logonPasswordHint.style.display = "none";
 45 }
 46 
 47 function onLogonPasswordTextBlur() {
 48     let logonPasswordText = document.getElementById("logon-password-text");
 49     let logonPasswordHint = document.getElementById("logon-password-hint");
 50     logonPasswordHint.style.display = (logonPasswordText.value.length === 0 ? "block" : "none");
 51 }
 52 
 53 function onLogonButtonClick() {
 54     if(validateLogon()) {
 55         let phoneText = document.getElementById("logon-phone-text");
 56         let passwordText = document.getElementById("logon-password-text");
 57         let phone = eraseSpace(phoneText.value.trim());
 58         let password = passwordText.value;
 59         requestLogon(phone, password);
 60     }
 61 }
 62 
 63 function onLogonRegistryButtonClick() {
 64     let registryBox = document.getElementById("registry-box");
 65     registryBox.style.display = "block";
 66 }
 67 
 68 function onRegistryNameTextFocus() {
 69     let registryNameHint = document.getElementById("registry-name-hint");
 70     registryNameHint.style.display = "none";
 71 }
 72 
 73 function onRegistryNameTextBlur() {
 74     let registryNameText = document.getElementById("registry-name-text");
 75     let registryNameHint = document.getElementById("registry-name-hint");
 76     registryNameHint.style.display = (registryNameText.value.length === 0 ? "block" : "none");
 77 }
 78 
 79 function onRegistryPhoneTextFocus() {
 80     let registryPhoneHint = document.getElementById("registry-phone-hint");
 81     registryPhoneHint.style.display = "none";
 82 }
 83 
 84 function onRegistryPhoneTextBlur() {
 85     let registryPhoneText = document.getElementById("registry-phone-text");
 86     let registryPhoneHint = document.getElementById("registry-phone-hint");
 87     registryPhoneHint.style.display = (registryPhoneText.value.length === 0 ? "block" : "none");
 88 }
 89 
 90 function onRegistryPasswordTextFocus() {
 91     let registryPasswordHint = document.getElementById("registry-password-hint");
 92     registryPasswordHint.style.display = "none";
 93 }
 94 
 95 function onRegistryPasswordTextBlur() {
 96     let registryPasswordText = document.getElementById("registry-password-text");
 97     let registryPasswordHint = document.getElementById("registry-password-hint");
 98     registryPasswordHint.style.display = (registryPasswordText.value.length === 0 ? "block" : "none");
 99 }
100 
101 function onRegistryConfirmTextFocus() {
102     let registryConfirmHint = document.getElementById("registry-confirm-hint");
103     registryConfirmHint.style.display = "none";
104 }
105 
106 function onRegistryConfirmTextBlur() {
107     let registryConfirmText = document.getElementById("registry-confirm-text");
108     let registryConfirmHint = document.getElementById("registry-confirm-hint");
109     registryConfirmHint.style.display = (registryConfirmText.value.length === 0 ? "block" : "none");
110 }
111 
112 function onRegistryOkButtonClick() {
113     if(validateRegistry()) {
114         let nameText = document.getElementById("registry-name-text");
115         let phoneText = document.getElementById("registry-phone-text");
116         let passwordText = document.getElementById("registry-password-text");
117         let confirmText = document.getElementById("registry-confirm-text");
118         let name = nameText.value.trim();
119         let phone = eraseSpace(phoneText.value.trim());
120         let password = passwordText.value;
121         let confirm = confirmText.value;
122         requestRegistry(name, phone, password, confirm);
123     }
124 }
125 
126 function onRegistryCancelButtonClick() {
127     let registryBox = document.getElementById("registry-box");
128     registryBox.style.display = "none";
129 }
130 
131 function validateLogon() {
132     let phoneText = document.getElementById("logon-phone-text");
133     let phone = eraseSpace(phoneText.value.trim());
134     if (phone.length === 0) {
135         showMessage("请输入手机号码!", "知道了", null);
136         return false;
137     }
138     if (!isPhoneValid(phone)) {
139         showMessage("手机号码输错了!", "知道了", null);
140         return false;
141     }
142 
143     let passwordText = document.getElementById("logon-password-text");
144     let password = passwordText.value;
145     if (password.length === 0) {
146         showMessage("请输入密码!", "知道了", null);
147         return false;
148     }
149     if (password.length < 6) {
150         showMessage("密码输错了!", "知道了", null);
151         return false;
152     }
153     return true;
154 }
155 
156 function validateRegistry() {
157     let nameText = document.getElementById("registry-name-text");
158     let name = nameText.value.trim();
159     if (name.length === 0) {
160         showMessage("名字需要1-12个字符!", "知道了", null);
161         return false;
162     }
163     if (name.length > 12) {
164         showMessage("名字不能多于12个字符!", "知道了", null);
165         return false;
166     }
167 
168     let phoneText = document.getElementById("registry-phone-text");
169     let phone = eraseSpace(phoneText.value.trim());
170     if (phone.length === 0) {
171         showMessage("请输入您的手机号码!", "知道了", null);
172         return false;
173     }
174     if (!isPhoneValid(phone)) {
175         showMessage("请输入正确的手机号码!", "知道了", null);
176         return false;
177     }
178 
179     let passwordText = document.getElementById("registry-password-text");
180     let password = passwordText.value;
181     if (password.length === 0 || password.length < 6) {
182         showMessage("密码不能少于6个字符!", "知道了", null);
183         return false;
184     }
185 
186     let confirmText = document.getElementById("registry-confirm-text");
187     let confirm = confirmText.value;
188     if (confirm.length === 0) {
189         showMessage("请输入密码确认!", "知道了", null);
190         return false;
191     }
192     if (confirm !== password) {
193         showMessage("密码确认需与密码相同!", "知道了", null);
194         return false;
195     }
196 
197     return true;
198 }
199 
200 function requestLogon(phone, password) {
201     let requestData = "phone=" + encodeURIComponent(phone)
202                     + "&password=" + encodeURIComponent(password);
203     let request = new XMLHttpRequest();
204     request.onload = requestLogonHandler;
205     request.open("POST", "logon");
206     request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
207     request.send(requestData);
208 }
209 
210 function requestLogonHandler() {
211     if(this.status == 200 && this.responseText != null) {
212         let responseJson = JSON.parse(this.responseText);
213         if(responseJson && responseJson.errorCode === "SUCCESS") {
214             window.location.replace("welcome.html?personId=" + responseJson.personId);
215         } else if (responseJson && responseJson.errorCode === "ERROR_CREDENTIAL") {
216             showMessage("手机或密码输错了,请重新输入!", "知道了", null);
217         } else {
218             showMessage("登录失败。页面发生了严重错误,请重试!", "知道了", null);
219         }
220     }
221 }
222 
223 function requestRegistry(name, phone, password, confirm) {
224     let requestData = "name=" + encodeURIComponent(name)
225                     + "&phone=" + encodeURIComponent(phone)
226                     + "&password=" + encodeURIComponent(password)
227                     + "&confirm=" + encodeURIComponent(confirm);
228     let request = new XMLHttpRequest();
229     request.onload = requestRegistryHandler;
230     request.open("POST", "registry");
231     request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
232     request.send(requestData);
233 }
234 
235 function requestRegistryHandler() {
236     if(this.status == 200 && this.responseText != null) {
237         let responseJson = JSON.parse(this.responseText);
238         if(responseJson && responseJson.errorCode === "SUCCESS") {
239             let registryBox = document.getElementById("registry-box");
240             registryBox.style.display = "none";
241             showMessage("注册成功!", "知道了", null);
242         } else if (responseJson && responseJson.errorCode === "ERROR_DUPLICATE") {
243             showMessage("手机号码已被注册过,请用其它号码!", "知道了", null);
244         } else {
245             showMessage("注册失败。页面发生了严重错误,请重试!", "知道了", null);
246         }
247     }
248 }
249 
250 function isPhoneValid(value) {
251     return /^1[0-9]{10}$/.test(value);
252 }
253 
254 function eraseSpace(value) {
255     return value.replace(/ /gi, "");
256 }
257 
258 function showMessage(msg, okButtontext, okButtonAction) {
259     let messageBox = document.createElement("div");
260     messageBox.id = "message-box";
261     messageBox.innerHTML = ""
262         + "<div class='-modal' style='z-index:900000000'></div>"
263         + "<div class='-modal-body' style='top:50%;left:50%;width:492px;height:40px;padding:6px;margin:-58px 0px 0px -255px;border-left:6px solid #3b5999;border-radius:3px 0px 0px 3px;line-height:40px;z-index:910000000;'>"
264         + "    <span style='float:left;width:398px;height:40px;'>" + msg + "</span>"
265         + "    <input id='message-box-ok-button' type='button' value='" + okButtontext + "' style='float:right;width:88px;height:40px;border-width:0px;font-size:16px;font-weight:bold;line-height:40px;background-color:#558543;color:white;cursor:pointer;'>"
266         + "</div>";
267     document.body.appendChild(messageBox);
268 
269     let messageBoxOkButton = document.getElementById("message-box-ok-button");
270     messageBoxOkButton.onmouseenter = function() {
271         messageBoxOkButton.style.background = "#699857";
272     };
273     messageBoxOkButton.onmouseleave = function() {
274         messageBoxOkButton.style.background = "#558543";
275     };
276     messageBoxOkButton.onclick = function() {
277         document.body.removeChild(messageBox);
278         if(okButtonAction) {
279             okButtonAction();
280         }
281     };
282 }
复制代码

33.在/come-in/web/目录里添加welcome.html文件。

复制代码
 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <title>欢迎</title>
 5     <meta charset="UTF-8">
 6     <link rel="stylesheet" type="text/css" href="style/global.css">
 7     <link rel="stylesheet" type="text/css" href="style/welcome.css">
 8 </head>
 9 <body>
10     <div id="person-info-box"></div>
11 
12     <script type="text/javascript" src="script/welcome.js"></script>
13 </body>
14 </html>
复制代码

34.在/come-in/web/style/目录里添加welcome.css文件。

1 #person-info-box p {
2     margin:12px;
3     font-size: 24px;
4     font-weight: bold;
5 }

35.在/come-in/web/script/目录里添加welcome.js文件。

复制代码
 1 window.onload = function() {
 2     let requestData = "personId=" + encodeURIComponent(getParam("personId"));
 3     let request = new XMLHttpRequest();
 4     request.onload = requestPersonInfoHandler;
 5     request.open("POST", "person_info");
 6     request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
 7     request.send(requestData);
 8 }
 9 
10 function requestPersonInfoHandler() {
11     if(this.status == 200 && this.responseText != null) {
12         let responseJson = JSON.parse(this.responseText);
13         if(responseJson && responseJson.errorCode === "SUCCESS") {
14             let personInfoBox = document.getElementById("person-info-box");
15             personInfoBox.innerHTML = "<p>您好," + responseJson.personName + "!</p>";
16         } else {
17             let personInfoBox = document.getElementById("person-info-box");
18             personInfoBox.innerHTML = "<p>页面发生了严重错误,请重新登录!</p>";
19         }
20     }
21 }
22 
23 function getParam(paramName) {
24     let query = window.location.search.substring(1);
25     let paramArray = query.split("&");
26     for (let i = 0; i < paramArray.length; i++) {
27         let paramPair = paramArray[i].split("=");
28         if(paramPair[0] === paramName) {
29             return paramPair[1];
30         }
31     }
32     return null;
33 }
复制代码

完成!

当然,这个网站尚有很多缺陷。比如没有进行异常处理,导致我们的应用程序非常脆弱;比如没有进行编码处理,导致用户使用中文进行注册的话,显示的是一堆乱码。但是,所有这些缺陷并不影响我们整个网站基础功能的实现,也不影响我们希望通过这个小项目加深对Spring框架的理解的初衷。还有,随着学习的深入。大家自然而然的就知道怎么补上这些缺陷了。

返回目录    下载代码

 

https://github.com/Evan-I/Open-Spring

来源:https://www.cnblogs.com/evanlin/p/15552739.html


相关教程