一步一步使用 IntelliJ IDEA 創(chuàng)建簡單的 Web 應(yīng)用

IntelliJ IDEA 來自于 JetBrains ,相信很多人都不會感到陌生,其 IED 整體界面風(fēng)格還是讓人很舒服的。下面將演示如何一步一步創(chuàng)建一個簡單的 Web 應(yīng)用的過程。該項目中有簡單應(yīng)用到
Hibernate 和 Servlet 、Tomcat、JSP 等相關(guān)內(nèi)容,如果你還不是特別熟悉這些概念也沒關(guān)系,這篇文章只是為了方便初學(xué)者能夠快速了解整體流程。

文中示例項目代碼:WebApplicationDemo-Github

本片文章中,你將可以看到如何構(gòu)建一個擁有簡單注冊和登錄流程的應(yīng)用。應(yīng)用大致流程是:用戶在 JSP 頁面輸入并提交表單數(shù)據(jù),應(yīng)用通過 Servlet 獲取到請求參數(shù)后,使用 Hibernate 進(jìn)行一些基本的數(shù)據(jù)庫增刪改查,處理簡單業(yè)務(wù)邏輯后返回結(jié)果內(nèi)容展示到 JSP 頁面。

文章背景大致介紹清楚了,相信你也明白大概要做個什么樣的東西。為了更直觀地了解,開始之前,我們先來看一眼項目文件結(jié)構(gòu)和實際運行的效果圖:

項目結(jié)構(gòu)

下面是實際運行效果截圖,文章最后也有演示內(nèi)容截圖:

實際效果

1. 下載 IDE

關(guān)于開發(fā)工具 IDE 的選擇因人而異,主要看團(tuán)隊開發(fā)環(huán)境和個人使用習(xí)慣,這里我們就直接選擇 JetBrains 的 IntelliJ IDEA 下載了。

IntelliJ IDEA

2. 搭建運行環(huán)境

  • 確認(rèn)系統(tǒng)已有 JDK 環(huán)境:關(guān)于安裝過程這里就不展開了

  • 搭建 Tomcat 環(huán)境:這里推薦之前寫的一篇文章:Mac 系統(tǒng) Tomcat 配置

  • 數(shù)據(jù)庫環(huán)境:挑合適的就行了,我這里選熟悉的 MySQL,有需要的直接去 MySQL 官網(wǎng)下載安裝就行了,安裝完成后記得去系統(tǒng)偏好設(shè)置中開啟 MySQL 服務(wù)。

MySQL

MySQL 服務(wù)使用前建議先改密碼,不然會有使用時會有 Access denied for user 'root'@'localhost' (using password: YES) 提示。

# 1.初始化狀態(tài)無密碼,直接按回車進(jìn)入
mysql -u root -p
# 2.為 root 用戶設(shè)置密碼
SET PASSWORD FOR root = PASSWORD('xxxxxx');
# 3.刷新權(quán)限
flush privileges;
# 4.退出
\q
# 5.重新啟動
sudo mysql.server restart

這推薦一個數(shù)據(jù)庫可視化操作工具:Sequel Pro,非常簡單好用。

你可能還需要一個 MySQL 連接庫用于 IDE 中連接數(shù)據(jù)庫,關(guān)于這個可以參考我之前的另一篇文章:處理 com.mysql.jdbc.Driver Not Found

3. 創(chuàng)建項目數(shù)據(jù)庫表

登錄數(shù)據(jù)庫,查看目前已有數(shù)據(jù)庫

# 登錄 mysql
mysql -u root -p
# 查看已有數(shù)據(jù)庫
show databases;

創(chuàng)建新的數(shù)據(jù)庫:

# 創(chuàng)建新的數(shù)據(jù)庫
create database demo_web_app

創(chuàng)建新的數(shù)據(jù)表:

# 選擇數(shù)據(jù)庫
use demo_web_app;
# 創(chuàng)建數(shù)據(jù)表
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. 新建項目

這里為了展示創(chuàng)建一個簡單的 web 應(yīng)用,這里直接選 Web Application 和 Hibernate 即可:

Web Application

勾選 Hibernate 支持

Hibernate

輸入項目名稱和主 Module 名稱

Project

項目創(chuàng)建完成后,我們先簡單看看項目文件結(jié)構(gòu)

項目結(jié)構(gòu)
  • lib 包中是 Hibernate 的相關(guān)支持庫
  • src 包是存放項目源碼和 Hibernate 配置文件
  • web 包是存放 web 頁面相關(guān)的資源

5. 項目配置

選中 module 后點擊右鍵打開 Open Module Settings, 配置 module 的依賴,項目比較簡單我們選擇 Hibernate 和 tomcat 依賴即可。

Dependencies

**注意 tomcat 的依賴配置路徑,建議選其安裝目錄下的整個 lib **

tomcat

配置 Artifacts

下面我們?yōu)?module 配置 Artifacts ,這是為了告訴 IDE 選中的 module 要如何進(jìn)行打包,例如可以是 war exploded、war、jar、ear 等等這種打包形式。某個 module 有了 Artifacts 就可以部署到應(yīng)用服務(wù)器中了。

  • jar (Java Archive):通常用于聚合大量的Java類文件、相關(guān)的元數(shù)據(jù)和資源(文本、圖片等)文件到一個文件,以便分發(fā)Java平臺應(yīng)用軟件或庫;

  • war (Web application Archive):一種JAR文件,其中包含用來分發(fā)的JSP、Java Servlet、Java類、XML文件、標(biāo)簽庫、靜態(tài)網(wǎng)頁(HTML和相關(guān)文件),以及構(gòu)成Web應(yīng)用程序的其他資源;

  • exploded:在這里你可以理解為展開,不壓縮的意思。也就是war、jar等產(chǎn)出物沒壓縮前的目錄結(jié)構(gòu)。建議在開發(fā)的時候使用這種模式,便于修改了文件的效果立刻顯現(xiàn)出來。

默認(rèn)情況下,IDEA的 Modules 和 Artifacts 的 output 目錄已經(jīng)設(shè)置好了,不需要更改,打成 war 包的時候會自動在 WEB-INF 目錄下生成 classes,然后把編譯后的文件放進(jìn)去。

修改 Artifacts 配置

對于項目其他一些配置和作用,大家可以參考這篇文章:理解 IntelliJ IDEA 的項目配置和Web部署

連接 Database,這里我們選擇 MySQL 作為項目 Data Source:

Database

我們先前搭建項目基礎(chǔ)環(huán)境時,已經(jīng)創(chuàng)建了一個叫 demo_web_app 的數(shù)據(jù)庫,這里直接進(jìn)行連接即可:

Database connect

數(shù)據(jù)庫連接成功后,我們我們可以可以在 IDE 中看到直觀的看到數(shù)據(jù)庫表內(nèi)容,里面有我們之前創(chuàng)建的 user 表:

database viewer

下面將創(chuàng)建項目時自動生成的 hibernate.cfg.xml 進(jìn)行修改,按照實際數(shù)據(jù)庫連接參數(shù)進(jìn)行配置

hibernate.cfg.xml

hibernate.cfg.xml 修改完成后,我們在 Persistence 選項卡中選中 hibernate.cfg.xml 點擊右鍵,打開 Gennerate Persistence Mapping 進(jìn)行數(shù)據(jù)庫產(chǎn)生持久化數(shù)據(jù)映射。

Persistence

此時 IDE 會自動加載數(shù)據(jù)庫 Database Schema,我們選擇一個用于存放映射出來實體類的 Package 路徑。

Gennerate Persistence Mapping

然后 IDE 就會自動生成實體類和對應(yīng)的 .hbm.xml 文件

UserEntity
UserEntity.hbm.xml

項目中 hibernate.cfg.xml 也會自動更新,添加 mapping 語句關(guān)聯(lián)
UserEntity.hbm.xml 文件

hibernate.cfg.xml

這里牽涉到 ORM 的概念,如果你還不熟悉這里,建議可以先結(jié)合
Hibernate 的使用過程了解一下。

下面修改運行配置,可以設(shè)置運行時啟動的瀏覽器和地址,這里使用默認(rèn)的即可,注意下圖藍(lán)色選中標(biāo)識的內(nèi)容,選中之前配置的 Build Artifacts 選項,如果沒有出現(xiàn)可以點擊提示出現(xiàn)的 fix 按鈕自動導(dǎo)入

Run Configurations

6. 編碼實現(xiàn)

盡可能結(jié)合注釋內(nèi)容理解吧,各個知識點就不單獨展開說明了

<?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負(fù)責(zé)創(chuàng)建的,而SessionFactory的實現(xiàn)是線程安全的,
 * 多個并發(fā)的線程可以同時訪問一個 SessionFactory 并從中獲取 Session 實例,而Session不是線程安全的。
 * Session 中包含了數(shù)據(jù)庫操作相關(guān)的狀態(tài)信息,那么說如果多個線程同時使用一個 Session 實例進(jìn)行 CRUD,就很有可能導(dǎo)致數(shù)據(jù)存取的混亂
 */
public class HibernateUtil {

    /**
     *
     */
    private static SessionFactory sessionFactory;

    /**
     * 使用 ThreadLocal 保存當(dāng)前業(yè)務(wù)線程中的 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();

    /**
     * 靜態(tài)代碼塊
     */
    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;
    }


    /**
     * 關(guān)閉 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;
    }

    /**
     * 構(gòu)建 SessionFactory
     */
    private static void buildSessionFactory() {
        System.out.println("start buildSessionFactory.");

        try {
            // 讀取 Hibernate 的配置文件(默認(rèn) hibernate.cfg.xml)
            if (configuration == null){
                configuration = new Configuration();
            }
            configuration.configure("/hibernate.cfg.xml");

            // 創(chuàng)建 ServiceRegistry,通過 StandardServiceRegistryBuilder 構(gòu)建并設(shè)置 Configuration 信息
            ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
                    .configure() // 可以指定配置文件(默認(rèn)hibernate.cfg.xml)
                    .build();

            try {
                // 創(chuàng)建 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;

/**
 * 數(shù)據(jù)訪問對象 DAO
 * 作為用戶數(shù)據(jù)的訪問接口
 *
 * @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;

/**
 * 數(shù)據(jù)訪問對象 DAO
 * 作為用戶數(shù)據(jù)的訪問接口
 *
 * @author baishixian
 */
public class UserDaoImpl implements UserDao {

    private final Session session;

    // 提交數(shù)據(jù)的事務(wù)
    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 方法統(tǒng)一處理
        doPost(request, response);
    }

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

        // 設(shè)置內(nèi)容類型
        response.setContentType("text/html;charset=utf-8");

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

        // 獲取請求提交的內(nèi)容
        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("兩次輸入的密碼不一致!"));
        }

        // 創(chuàng)建 User 對象
        UserEntity user = new UserEntity();
        user.setUserName(username);
        user.setPassword(password);

        // 往數(shù)據(jù)庫插入新用戶信息
        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">確認(rèn)密碼:</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. 運行應(yīng)用

上面運行參數(shù)配置后,點擊 run 按鈕,啟動 Tomcat:

run

Tomcat 運行起來后,會自動打開 localhost:8080 頁面

歡迎頁

跳轉(zhuǎn)到注冊頁面,輸入用戶信息:

注冊頁面

點擊注冊,檢測數(shù)據(jù)庫是否已有該用戶,沒有則新增一條。

注冊成功

注冊成功以后的數(shù)據(jù)庫表成功新增一條記錄:

數(shù)據(jù)表中新增內(nèi)容

進(jìn)入登錄頁面,試試剛剛注冊的賬號能否做登錄驗證:

登錄頁面

登錄數(shù)據(jù)驗證成功后,提示登錄成功:

登錄成功

測試密碼輸出的情況,提示一切正常:

密碼輸出的情況

Github Project

文中示例項目代碼:WebApplicationDemo-Github

參考文章:

理解 IntelliJ IDEA 的項目配置和Web部署
處理 com.mysql.jdbc.Driver Not Found
Mac 系統(tǒng) Tomcat 配置
Hibernate實現(xiàn)登錄注冊小例子

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,253評論 6 342
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,623評論 18 399
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 3,988評論 0 11
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,502評論 19 139
  • 文/一個苞谷 1 我是一個愛周期性買書的人。何為周期性?就是空虛放縱了一段時間后,一次性將排行榜前幾名的書全買回來...
    一個苞谷閱讀 2,005評論 27 7

友情鏈接更多精彩內(nèi)容