一步一步使用 IntelliJ IDEA 创建简单的 Web 应用

IntelliJ IDEA 来自于 JetBrains ,相信很多人都不会感到陌生,其 IED 整体界面风格还是让人很舒服的。下面将演示如何一步一步创建一个简单的 Web 应用的过程。该项目中有简单应用到
Hibernate 和 Servlet 、Tomcat、JSP 等相关内容,如果你还不是特别熟悉这些概念也没关系,这篇文章只是为了方便初学者能够快速了解整体流程。

文中示例项目代码:WebApplicationDemo-Github

本片文章中,你将可以看到如何构建一个拥有简单注册和登录流程的应用。应用大致流程是:用户在 JSP 页面输入并提交表单数据,应用通过 Servlet 获取到请求参数后,使用 Hibernate 进行一些基本的数据库增删改查,处理简单业务逻辑后返回结果内容展示到 JSP 页面。

文章背景大致介绍清楚了,相信你也明白大概要做个什么样的东西。为了更直观地了解,开始之前,我们先来看一眼项目文件结构和实际运行的效果图:

项目结构

下面是实际运行效果截图,文章最后也有演示内容截图:

实际效果

1. 下载 IDE

关于开发工具 IDE 的选择因人而异,主要看团队开发环境和个人使用习惯,这里我们就直接选择 JetBrains 的 IntelliJ IDEA 下载了。

IntelliJ IDEA

2. 搭建运行环境

  • 确认系统已有 JDK 环境:关于安装过程这里就不展开了

  • 搭建 Tomcat 环境:这里推荐之前写的一篇文章:Mac 系统 Tomcat 配置

  • 数据库环境:挑合适的就行了,我这里选熟悉的 MySQL,有需要的直接去 MySQL 官网下载安装就行了,安装完成后记得去系统偏好设置中开启 MySQL 服务。

MySQL

MySQL 服务使用前建议先改密码,不然会有使用时会有 Access denied for user 'root'@'localhost' (using password: YES) 提示。

# 1.初始化状态无密码,直接按回车进入
mysql -u root -p
# 2.为 root 用户设置密码
SET PASSWORD FOR root = PASSWORD('xxxxxx');
# 3.刷新权限
flush privileges;
# 4.退出
\q
# 5.重新启动
sudo mysql.server restart

这推荐一个数据库可视化操作工具:Sequel Pro,非常简单好用。

你可能还需要一个 MySQL 连接库用于 IDE 中连接数据库,关于这个可以参考我之前的另一篇文章:处理 com.mysql.jdbc.Driver Not Found

3. 创建项目数据库表

登录数据库,查看目前已有数据库

# 登录 mysql
mysql -u root -p
# 查看已有数据库
show databases;

创建新的数据库:

# 创建新的数据库
create database demo_web_app

创建新的数据表:

# 选择数据库
use demo_web_app;
# 创建数据表
CREATE TABLE `user` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `userName` char(30) CHARACTER SET latin1 NOT NULL DEFAULT '',
  `password` char(30) CHARACTER SET latin1 NOT NULL DEFAULT '',
  `nickName` char(30) CHARACTER SET latin1 DEFAULT '',
  `email` char(30) CHARACTER SET latin1 DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

可视化工具查看

Sequel Pro

4. 新建项目

这里为了展示创建一个简单的 web 应用,这里直接选 Web Application 和 Hibernate 即可:

Web Application

勾选 Hibernate 支持

Hibernate

输入项目名称和主 Module 名称

Project

项目创建完成后,我们先简单看看项目文件结构

项目结构
  • lib 包中是 Hibernate 的相关支持库
  • src 包是存放项目源码和 Hibernate 配置文件
  • web 包是存放 web 页面相关的资源

5. 项目配置

选中 module 后点击右键打开 Open Module Settings, 配置 module 的依赖,项目比较简单我们选择 Hibernate 和 tomcat 依赖即可。

Dependencies

**注意 tomcat 的依赖配置路径,建议选其安装目录下的整个 lib **

tomcat

配置 Artifacts

下面我们为 module 配置 Artifacts ,这是为了告诉 IDE 选中的 module 要如何进行打包,例如可以是 war exploded、war、jar、ear 等等这种打包形式。某个 module 有了 Artifacts 就可以部署到应用服务器中了。

  • jar (Java Archive):通常用于聚合大量的Java类文件、相关的元数据和资源(文本、图片等)文件到一个文件,以便分发Java平台应用软件或库;

  • war (Web application Archive):一种JAR文件,其中包含用来分发的JSP、Java Servlet、Java类、XML文件、标签库、静态网页(HTML和相关文件),以及构成Web应用程序的其他资源;

  • exploded:在这里你可以理解为展开,不压缩的意思。也就是war、jar等产出物没压缩前的目录结构。建议在开发的时候使用这种模式,便于修改了文件的效果立刻显现出来。

默认情况下,IDEA的 Modules 和 Artifacts 的 output 目录已经设置好了,不需要更改,打成 war 包的时候会自动在 WEB-INF 目录下生成 classes,然后把编译后的文件放进去。

修改 Artifacts 配置

对于项目其他一些配置和作用,大家可以参考这篇文章:理解 IntelliJ IDEA 的项目配置和Web部署

连接 Database,这里我们选择 MySQL 作为项目 Data Source:

Database

我们先前搭建项目基础环境时,已经创建了一个叫 demo_web_app 的数据库,这里直接进行连接即可:

Database connect

数据库连接成功后,我们我们可以可以在 IDE 中看到直观的看到数据库表内容,里面有我们之前创建的 user 表:

database viewer

下面将创建项目时自动生成的 hibernate.cfg.xml 进行修改,按照实际数据库连接参数进行配置

hibernate.cfg.xml

hibernate.cfg.xml 修改完成后,我们在 Persistence 选项卡中选中 hibernate.cfg.xml 点击右键,打开 Gennerate Persistence Mapping 进行数据库产生持久化数据映射。

Persistence

此时 IDE 会自动加载数据库 Database Schema,我们选择一个用于存放映射出来实体类的 Package 路径。

Gennerate Persistence Mapping

然后 IDE 就会自动生成实体类和对应的 .hbm.xml 文件

UserEntity
UserEntity.hbm.xml

项目中 hibernate.cfg.xml 也会自动更新,添加 mapping 语句关联
UserEntity.hbm.xml 文件

hibernate.cfg.xml

这里牵涉到 ORM 的概念,如果你还不熟悉这里,建议可以先结合
Hibernate 的使用过程了解一下。

下面修改运行配置,可以设置运行时启动的浏览器和地址,这里使用默认的即可,注意下图蓝色选中标识的内容,选中之前配置的 Build Artifacts 选项,如果没有出现可以点击提示出现的 fix 按钮自动导入

Run Configurations

6. 编码实现

尽可能结合注释内容理解吧,各个知识点就不单独展开说明了

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="connection.url">jdbc:mysql://localhost:3306/demo_web_app</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="current_session_context_class">thread</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
        
        <!-- DB schema will be updated if needed-->
        <property name="hbm2ddl.auto">update</property>
        <property name="show_sql">true</property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        <mapping resource="gdut/bai/entity/UserEntity.hbm.xml"/>

    </session-factory>
</hibernate-configuration>
package gdut.bai.util;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

/**
 * Hibernate 工具类
 *
 * Session 是由SessionFactory负责创建的,而SessionFactory的实现是线程安全的,
 * 多个并发的线程可以同时访问一个 SessionFactory 并从中获取 Session 实例,而Session不是线程安全的。
 * Session 中包含了数据库操作相关的状态信息,那么说如果多个线程同时使用一个 Session 实例进行 CRUD,就很有可能导致数据存取的混乱
 */
public class HibernateUtil {

    /**
     *
     */
    private static SessionFactory sessionFactory;

    /**
     * 使用 ThreadLocal 保存当前业务线程中的 Hibernate Session
     *
     * ThreadLocal 并不是一个Thread,而是 thread local variable (线程局部变量)。
     * ThreadLocal 非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。
     * 从线程的角度看,就好像每一个线程都完全拥有一个该变量 (Map 类型 key-value 保存)。
     * ThreadLocal 这个类本身不是代表线程要访问的变量,这个类的成员变量才是。
     * 线程通过 ThreadLocal 的 get 和 set 方法去访问这个变量。
     *
     */
    private static ThreadLocal<Session> threadLocalSession = new ThreadLocal<>();

    /**
     *  Hibernate 配置
     */
    private static Configuration configuration = new Configuration();

    /**
     * 静态代码块
     */
    static {
        buildSessionFactory();
    }

    private HibernateUtil() {
    }

    /**
     * 获取 Session
     * @return
     * @throws HibernateException
     */
    public static Session getSession() throws HibernateException {

        System.out.println("getSession");

        Session session = threadLocalSession.get();

        if (session == null || !session.isOpen()) {
            if (sessionFactory == null) {
                buildSessionFactory();
            }

            session = (sessionFactory != null) ? sessionFactory.openSession() : null;
            threadLocalSession.set(session);
        }

        return session;
    }


    /**
     * 关闭 Session
     * @throws HibernateException
     */
    public static void closeSession() throws HibernateException {
        Session session = threadLocalSession.get();
        threadLocalSession.set(null);

        if (session != null) {
            session.close();
        }
    }

    /**
     * 获取 SessionFactory
     * @return SessionFactory
     *
     * @deprecated
     */
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    /**
     * 获取 Configuration
     * @return Configuration
     *
     * @deprecated
     */
    public static Configuration getConfiguration() {
        return configuration;
    }

    /**
     * 构建 SessionFactory
     */
    private static void buildSessionFactory() {
        System.out.println("start buildSessionFactory.");

        try {
            // 读取 Hibernate 的配置文件(默认 hibernate.cfg.xml)
            if (configuration == null){
                configuration = new Configuration();
            }
            configuration.configure("/hibernate.cfg.xml");

            // 创建 ServiceRegistry,通过 StandardServiceRegistryBuilder 构建并设置 Configuration 信息
            ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
                    .configure() // 可以指定配置文件(默认hibernate.cfg.xml)
                    .build();

            try {
                // 创建 SessionFactory
                sessionFactory = new MetadataSources(serviceRegistry)
                        .buildMetadata()
                        .buildSessionFactory();
            }catch (Exception e){
                StandardServiceRegistryBuilder.destroy(serviceRegistry);
                e.printStackTrace();
            }
        }catch (Exception e){
            System.err.println("Creating SessionFactory Error.");
            e.printStackTrace();
        }
    }

}
package gdut.bai.dao;

import org.hibernate.Session;

/**
 * DAO 工厂类
 * 单例模式
 *
 * @author baishixian
 */
public class DAOFactory {

    private static volatile DAOFactory mInstance;

    private DAOFactory() {
    }

    public static DAOFactory getInstance(){

        if (mInstance == null){

            synchronized (DAOFactory.class){

                if (mInstance == null){
                    mInstance = new DAOFactory();
                }
            }
        }

        return mInstance;
    }

    /**
     * 获取 UserDao
     * @return UserDao
     */
    public UserDao getUserDAO(Session session) {
        return new UserDaoImpl(session);
    }

}

package gdut.bai.dao;

import gdut.bai.entity.UserEntity;

import java.util.List;

/**
 * 数据访问对象 DAO
 * 作为用户数据的访问接口
 *
 * @author baishixian
 */
public interface UserDao {

    String insertUser(UserEntity user);

    String updateUser(UserEntity user);

    List<UserEntity> queryInfo(String type, Object value);

}
package gdut.bai.dao;

import gdut.bai.entity.UserEntity;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.query.Query;

import javax.swing.*;
import java.util.List;

/**
 * 数据访问对象 DAO
 * 作为用户数据的访问接口
 *
 * @author baishixian
 */
public class UserDaoImpl implements UserDao {

    private final Session session;

    // 提交数据的事务
    private Transaction transaction;

    public UserDaoImpl(Session session) {
        this.session = session;
    }

    @Override
    public String insertUser(UserEntity user) {
        String result;

        try {
            transaction = session.beginTransaction();
            session.save(user);
            transaction.commit();
            result = "用户:" + user.getUserName() + "注册成功!";
        } catch (Exception e) {
          //  showMessage("RegisterInfo error:" + e);
            e.printStackTrace();
            result = "注册失败:" + e;
        }

        return result;
    }

    @Override
    public String updateUser(UserEntity user) {
        String result;

        try {
            transaction = session.beginTransaction();
            session.update(user);
            transaction.commit();
            result = "用户:" + user.getUserName() + "信息更新成功!";
        } catch (Exception e) {
          //  showMessage("updateUser error:" + e);
            e.printStackTrace();
            result = "用户信息失败:" + e;
        }

        return result;
    }

    @Override
    public List<UserEntity> queryInfo(String type, Object value) {
        String sql = "from gdut.bai.entity.UserEntity as user where user." + type + "=?";

        System.out.println("queryInfo sql " + sql + " value = " + value);

        try {
            transaction = session.beginTransaction();
            Query query = session.createQuery(sql);
            query.setParameter(0, value);
            List list = query.list();
            transaction.commit();
            return list;
        } catch (Exception e) {
            showMessage("queryInfo error:" + e);
            e.printStackTrace();
            return null;
        }
    }

    private void showMessage(String mess) {
        int type = JOptionPane.YES_NO_OPTION;
        String title = "提示信息";
        JOptionPane.showMessageDialog(null, mess, title, type);
    }
}

package gdut.bai.entity;

public class UserEntity {
    private int id;
    private String userName;
    private String password;
    private String nickName;
    private String email;

    public int getId() {
        return id;
    }

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

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

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

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        UserEntity that = (UserEntity) o;

        if (id != that.id) return false;
        if (userName != null ? !userName.equals(that.userName) : that.userName != null) return false;
        if (password != null ? !password.equals(that.password) : that.password != null) return false;
        if (nickName != null ? !nickName.equals(that.nickName) : that.nickName != null) return false;
        if (email != null ? !email.equals(that.email) : that.email != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = id;
        result = 31 * result + (userName != null ? userName.hashCode() : 0);
        result = 31 * result + (password != null ? password.hashCode() : 0);
        result = 31 * result + (nickName != null ? nickName.hashCode() : 0);
        result = 31 * result + (email != null ? email.hashCode() : 0);
        return result;
    }
}
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>

    <class name="gdut.bai.entity.UserEntity" table="user" schema="demo_web_app">
        <id name="id">
            <column name="id" sql-type="int(11) unsigned"/>
        </id>
        <property name="userName">
            <column name="userName" sql-type="char(30)" length="30" not-null="true"/>
        </property>
        <property name="password">
            <column name="password" sql-type="char(30)" length="30" not-null="true"/>
        </property>
        <property name="nickName">
            <column name="nickName" sql-type="char(30)" length="30"/>
        </property>
        <property name="email">
            <column name="email" sql-type="char(30)" length="30" />
        </property>
    </class>
</hibernate-mapping>
package gdut.bai.servlet;

import gdut.bai.comment.Constance;
import gdut.bai.dao.DAOFactory;
import gdut.bai.dao.UserDao;
import gdut.bai.entity.UserEntity;
import gdut.bai.util.HibernateUtil;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 交由 post 方法统一处理
        doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 设置内容类型
        response.setContentType("text/html;charset=utf-8");

        // 文本输出流
        PrintWriter printWriter = response.getWriter();

        // 获取请求提交的内容
        String username = request.getParameter(Constance.USER_NAME);
        String password = request.getParameter(Constance.PASSWORD);

        // 获取 UseDAO
        UserDao userDao = DAOFactory.getInstance().getUserDAO(HibernateUtil.getSession());

        if (username == null || username.length() == 0) {
            printWriter.print(getErrorAlertMsg("用户名不能为空"));
        } else {
            List<UserEntity> userList = userDao.queryInfo(Constance.USER_NAME, username);

            if (userList != null && !userList.isEmpty()){
                for (UserEntity user : userList) {
                    if (user.getUserName().equals(username)) {
                        if (user.getPassword().equals(password)) {
                            printWriter.print("登录成功!");
                            return;
                        } else {
                            printWriter.print(getErrorAlertMsg("密码错误!"));
                        }
                    }
                }
            }

            HibernateUtil.closeSession();

            printWriter.print(getErrorAlertMsg("用户名错误!"));
        }
    }

    private String getErrorAlertMsg(String msg){
        return "<script language='javascript'>alert('" + msg + "'); window.location.href='JSP/login.jsp';</script>";
    }
}

package gdut.bai.servlet;

import gdut.bai.comment.Constance;
import gdut.bai.dao.DAOFactory;
import gdut.bai.dao.UserDao;
import gdut.bai.entity.UserEntity;
import gdut.bai.util.HibernateUtil;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

@WebServlet("/RegisterServlet")
public class RegisterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");

        PrintWriter printWriter = response.getWriter();
        String username = request.getParameter(Constance.USER_NAME);
        String password = request.getParameter(Constance.PASSWORD);
        String confirmPassword = request.getParameter(Constance.CONFIRM_PASSWORD);

        UserDao userDao = DAOFactory.getInstance().getUserDAO(HibernateUtil.getSession());

        if (username == null || username.length() == 0) {
            printWriter.print(getErrorAlertMsg("用户名不能为空!"));
        } else {
            List<UserEntity> userList = userDao.queryInfo(Constance.USER_NAME, username);

            if (userList != null && !userList.isEmpty()){
                for (UserEntity user : userList) {
                    if (user.getUserName().equals(username)) {
                        printWriter.print(getErrorAlertMsg("用户名已存在"));
                    }
                }
            }
        }
        if (password == null || password.length() == 0) {
            printWriter.print(getErrorAlertMsg("密码不能为空!"));
        } else if (!password.equals(confirmPassword)) {
            printWriter.print(getErrorAlertMsg("两次输入的密码不一致!"));
        }

        // 创建 User 对象
        UserEntity user = new UserEntity();
        user.setUserName(username);
        user.setPassword(password);

        // 往数据库插入新用户信息
        String result = userDao.insertUser(user);
        printWriter.print(result);

        HibernateUtil.closeSession();

    }

    private String getErrorAlertMsg(String msg){
        return "<script language='javascript'>alert('" + msg + "'); window.location.href='JSP/register.jsp';</script>";
    }
}

package gdut.bai.comment;

/**
 * 存放常量
 * @author baishixian
 */
public interface Constance {

    String USER_NAME = "userName";
    String PASSWORD = "password";
    String CONFIRM_PASSWORD = "confirmPassword";
}

web/JSP/index.jsp

<%--
  Created by IntelliJ IDEA.
  User: baishixian
  Date: 2017/10/26
  Time: 下午3:32
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8"%>
<html>
  <head>
    <meta charset="utf-8">
    <title>Web Application Demo</title>
  </head>

  <body>
  <h1>Welcome Web Application</h1>
  <hr/>
  Hello World!<br/>

  <br/>

  <tr>
    <td colspan="2">
      <input class="button" type="button" onclick="goRegister()" value="开始注册"/>
      <input class="button" type="button" onclick="goLogin()" value="开始登录" />
    </td>
  </tr>

  </body>

  <script type="text/javascript">
      function goLogin(){
          window.location = "JSP/login.jsp";
      }

      function goRegister(){
          window.location = "JSP/register.jsp";
      }
  </script>
</html>

web/JSP/login.jsp

<%--
  Created by IntelliJ IDEA.
  User: baishixian
  Date: 2017/10/25
  Time: 下午10:31
  To change this template use File | Settings | File Templates.
--%>
<%--
  Created by IntelliJ IDEA.
  User: baishixian
  Date: 2017/10/25
  Time: 下午10:31
  To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
            + path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <base href="<%=basePath%>">

    <title>My JSP 'index.jsp' starting page</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
</head>

<body>
<h1>登            录</h1>
<hr>
<form action="LoginServlet" method="post">
    <table class="centertable">
        <tr>
            <td class="td1">用 户 名:</td>
            <td class="td2"><input class="text1" type="text"
                                   name="userName"/></td>
        </tr>
        <tr>
            <td class="td1">密    码:</td>
            <td class="td2"><input class="text1" type="password"
                                   name="password" /></td>
        </tr>
        <tr>
            <td colspan="2">
                <input class="button" type="submit" value="登录"  onchange="checkpwd()"/>
                <input class="button" type="button" onclick="javascript:history.back(-1);" value="返回"/>
            </td>
        </tr>
    </table>
</form>
</body>
</html>

web/JSP/register.jsp

<%--
  Created by IntelliJ IDEA.
  User: baishixian
  Date: 2017/10/25
  Time: 下午10:31
  To change this template use File | Settings | File Templates.
--%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
            + path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <base href="<%=basePath%>">

    <title>My JSP 'index.jsp' starting page</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
</head>

<body>
<h1>注            册</h1>
<hr>
<form action="RegisterServlet" method="post">
    <table class="centertable">
        <tr>
            <td class="td1">用 户 名:</td>
            <td class="td2"><input class="text1" type="text"
                                   name="userName" /></td>
        </tr>
        <tr>
            <td class="td1">密    码:</td>
            <td class="td2"><input class="text1" type="password"
                                   name="password" /></td>
        </tr>
        <tr>
            <td class="td1">确认密码:</td>
            <td class="td2"><input class="text1" type="password"
                                   name="confirmPassword" /></td>
        </tr>
        <tr>
            <td colspan="2"><input class="button" type="submit" value="注册"
                                   onchange="checkpwd()" /> <input class="button" type="button"
                                                                   onclick="javascript:history.back(-1);" value="返回" /></td>
        </tr>
    </table>
</form>
</body>
</html>

7. 运行应用

上面运行参数配置后,点击 run 按钮,启动 Tomcat:

run

Tomcat 运行起来后,会自动打开 localhost:8080 页面

欢迎页

跳转到注册页面,输入用户信息:

注册页面

点击注册,检测数据库是否已有该用户,没有则新增一条。

注册成功

注册成功以后的数据库表成功新增一条记录:

数据表中新增内容

进入登录页面,试试刚刚注册的账号能否做登录验证:

登录页面

登录数据验证成功后,提示登录成功:

登录成功

测试密码输出的情况,提示一切正常:

密码输出的情况

Github Project

文中示例项目代码:WebApplicationDemo-Github

参考文章:

理解 IntelliJ IDEA 的项目配置和Web部署
处理 com.mysql.jdbc.Driver Not Found
Mac 系统 Tomcat 配置
Hibernate实现登录注册小例子

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容

  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,367评论 6 343
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,296评论 18 399
  • 一. Java基础部分.................................................
    wy_sure阅读 3,731评论 0 11
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • 文/一个苞谷 1 我是一个爱周期性买书的人。何为周期性?就是空虚放纵了一段时间后,一次性将排行榜前几名的书全买回来...
    一个苞谷阅读 1,858评论 27 7