Idea + maven 搭建 SSH (struts2 +hibernate5 + spring5) 環境

最近要使用 SSH 來編寫期末的考覈任務,之前也在網上查閱了很久,也試出了很多的問題。也很感謝很多前輩們的總結,我也查到了很多用用的內容。

本次項目,我將以一個簡單的登錄案例實現 SSH 的項目整合,項目我會放到 Github 上面,需要的同學可以 clone 下來在本地跑一跑

項目地址:SSH 腳手架

一、項目環境搭建

使用 maven 搭建一個 Java Web 項目
在這裏插入圖片描述

1.1 配置 Spring 座標依賴

引入 Spring 座標依賴

 <!-- spring-context -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.1.0.RELEASE</version>
    </dependency>
    <!-- spring-web -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.1.0.RELEASE</version>
    </dependency>
    <!--spring-jdbc -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.1.0.RELEASE</version>
    </dependency>
    <!-- spring-orm -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version>5.1.0.RELEASE</version>
    </dependency>
    <!-- aop面向切面依賴的jar包 -->
    <!-- aspectjrt -->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>1.9.1</version>
    </dependency>
    <!-- aspectjweaver -->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.1</version>
    </dependency>

1.2 配置 hibernate 座標依賴

我們的目標是要整合 SSH,所以需要 hibernate 的核心依賴, mysql 數據庫驅動,以及 c3p0 數據庫連接池

   <!-- hibernate核心依賴 -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>5.2.17.Final</version>
    </dependency>
    <!-- mysql數據庫驅動依賴 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.47</version>
    </dependency>
        <!-- c3p0連接池 -->
    <dependency>
      <groupId>com.mchange</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.5.2</version>
    </dependency>

1.3 配置 struts2 座標依賴

我們需要 struts 核心,以及 struts 整合 spring 的插件,以及 struts 對 json 數據處理的插件

    <!-- struts2 -->
    <dependency>
      <groupId>org.apache.struts</groupId>
      <artifactId>struts2-core</artifactId>
      <version>2.3.35</version>
    </dependency>
    <!-- struts2-spring-plugin整合spring和struts2 -->
    <dependency>
      <groupId>org.apache.struts</groupId>
      <artifactId>struts2-spring-plugin</artifactId>
      <version>2.3.35</version>
    </dependency>
    <!-- json 數據處理,struts 插件 -->
    <dependency>
      <groupId>org.apache.struts</groupId>
      <artifactId>struts2-json-plugin</artifactId>
      <version>2.3.8</version>
    </dependency>

1.4 配置Java EE 座標依賴

這裏可以引入 servlet api,jstl 標籤庫等一系列工具

<!-- servlet api -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>javax.servlet.jsp-api</artifactId>
      <version>2.3.1</version>
      <scope>provided</scope>
    </dependency>
    <!-- lombok 一個插件,可以免 getter 和 setter 方法,但是需要我們在 idea 中裝對應的插件纔可以使用,可以不要-->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.0</version>
      <scope>provided</scope>
    </dependency>
    <!-- jstl -->
    <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>taglibs</groupId>
      <artifactId>standard</artifactId>
      <version>1.1.2</version>
    </dependency>

1.5 其他工具

json 處理工具

      <dependency>
          <groupId>org.jetbrains</groupId>
          <artifactId>annotations-java5</artifactId>
          <version>RELEASE</version>
          <scope>compile</scope>
      </dependency>
    <!-- 官方給的 json 包,建議使用這個,但是我後面好像並沒有用到 -->
    <dependency>
      <groupId>org.json</groupId>
      <artifactId>json</artifactId>
      <version>20160810</version>
    </dependency>

二、項目結構搭建

2.1 配置文件

使用如下方式創建
在這裏插入圖片描述

  1. applicationContext.xml
  2. jdbc.properties
  3. struts.xml

2.2 包結構

創建如下的基本包結構
在這裏插入圖片描述

三、編寫配置文件

3.1 web.xml 文件配置

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <!-- Spring 的配置文件-->
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <!-- struts2核心過濾器,過濾所有的請求 -->
  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <!-- 上下文監聽器 -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
</web-app>

3.2 編寫 jdbc.properties 文件

這裏我們需要自己手動修改數據庫的信息配置

jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/hibernate?characterEncoding=utf-8&autoReconnect=true&useSSL=false
jdbc.user=root
jdbc.password=root
#連接池中保留的最小連接數
jdbc.minPoolSize=1
#連接池中保留的最大連接數
jdbc.maxPoolSize=20
#初始化連接數
jdbc.initialPoolSize=1

3.3 編寫 applicationContext.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:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd 
       http://www.springframework.org/schema/tx 
       http://www.springframework.org/schema/tx/spring-tx.xsd 
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context.xsd">
    
    <!-- 引入資源文件 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!-- 自動掃描與裝配bean-->
    <context:component-scan base-package="dao.*,service.*"/>
    <context:component-scan base-package="action"/>
    <!--引入註解解析器-->
    <context:annotation-config/>
    <!-- 數據源連接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClass}"/>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
        <property name="user" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="minPoolSize" value="${jdbc.minPoolSize}"/>
        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"/>
        <property name="initialPoolSize" value="${jdbc.initialPoolSize}"/>
    </bean>
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="hibernateProperties">
            <props>
                <!--配置Hibernate的方言-->
                <prop key="hibernate.dialect">
                    org.hibernate.dialect.MySQLDialect
                </prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.current_session_context_class">thread</prop>
                <!--格式化輸出sql語句-->
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.use_sql_comments">false</prop>
            </props>
        </property>
        <!-- 自動掃描實體 -->
        <property name="packagesToScan"  value="entity" />
    </bean>
    <!-- 配置 HibernateTemplate 對象 -->

    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
        <!-- 注入 SessionFactory 對象 -->
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <!-- 用註解來實現事務管理 -->
    <bean id="txManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    <tx:annotation-driven transaction-manager="txManager"/>
</beans>

3.4 struts 配置文件

我們還沒有編寫的具體的 action 服務,所以這裏先跳過

四、使用 hibernate 逆向生成工具生成實體

4.1 配置數據庫連接信息

使用 idea 自帶的數據庫連接的工具
在這裏插入圖片描述
完善基本配置信息
在這裏插入圖片描述

4.2 逆向生成實體類

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

4.3 實體類配置

生成好後可以看到和數據庫對應的實體類,我的表很簡單,一個簡單的用戶表,只有 id, username, password 字段
在這裏插入圖片描述

但是我們發現裏面的部分內容會爆紅,這是因爲我們沒有指定數據源
在這裏插入圖片描述
選擇我們剛纔連接的數據庫
在這裏插入圖片描述
然後就沒問題了。

五、JavaBean 編寫

看到包結構,大家應該可以猜出來,我是使用的典型的 MVC 三層架構來編寫的

5.1 編寫 dao 層

創建 UserDao 以及 它的實現類 UserDaoImpl

在這裏插入圖片描述

UserDao 編寫

package dao;

import entity.User;

public interface UserDao {

    // 用戶登錄驗證
    public User selectByUsernameAndPassword(String username, String password);
}

UserDaoImpl

package dao.Impl;

import dao.UserDao;
import entity.User;
import org.hibernate.Session;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;

// 使用 Spring 來接管持久層的所有操作
@Repository
public class UserDaoImpl implements UserDao {

    // 使用 Hibernate 提供的模板
    @Autowired
    @Resource
    private HibernateTemplate hibernateTemplate;

    // 生成對應的 get 和 set 方法
    public HibernateTemplate getHibernateTemplate() {
        return hibernateTemplate;
    }

    public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
        this.hibernateTemplate = hibernateTemplate;
    }

    @Override
    public User selectByUsernameAndPassword(String username, String password) {
        // 登錄的邏輯不算難,就是使用 sql 語句查詢,username 和 password 兩個字段是否存在即可,我們使用的是 hibernate 框架,所以要寫 hql 語句
        Session session = hibernateTemplate.getSessionFactory().openSession();
        Query q = session.createQuery("from User u where u.username = ? and u.password = ?");
        q.setParameter(0,username);
        q.setParameter(1,password);
        User u = (User) q.uniqueResult();
        return u;
    }
}

我們寫好了 dao 層,這時候發現出現了爆紅的問題,這裏我們需要手動添加項目的依賴信息
在這裏插入圖片描述
點擊 project structure
在這裏插入圖片描述
在這裏插入圖片描述
添加這個就可以了,問題就解決了
在這裏插入圖片描述
顯示正常了
在這裏插入圖片描述

5.2 編寫 Service 層

同樣,我們創建對應的 UserService 和 對應的 UserServiceImpl

有的同學可能會問道,不就是一個簡單的登錄功能嘛,有必要這麼麻煩嗎?是的,這麼做確實沒必要,但是隨着項目的越來越大,只有把具體的功能全部分開來做,這樣纔不至於整個項目太過於亂

編寫用戶的業務層 接口 UserService

package service;

import entity.User;

public interface UserService {
    // 登錄驗證
    User checklogin(String username, String password);
}

編寫 業務層對應的實現類 UserServiceImpl

package service.Impl;

import dao.UserDao;
import entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import service.UserService;

@Service
public class UserServiceImpl implements UserService {
    
    // 這裏業務層調用持久層的方法
    @Autowired
    private UserDao ud;
    
    @Override
    public User checklogin(String username, String password) {
        return ud.selectByUsernameAndPassword(username,password);
    }
}

5.3 編寫 Controller 層 (UserAction)

這裏的邏輯思路,是 controller 層 調用 service 的方法,service 層調用 dao 層的方法

package action;

import com.opensymphony.xwork2.ActionContext;
import entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import service.UserService;

import java.util.Map;

// 使用 Controller 表示這是控制層,使用 ua 表示這個類被 Spring 所管理
@Controller("ua")
public class UserAction {
    // 編寫兩個屬性,使用 struts2 的 ognl 表達式可以直接接收到前端穿過來的數據,不再需要 request.getParameter("xxxx") 接收數據了
    private String username;
    private String password;

    // 調用業務層的方法
    @Autowired
    private UserService us;

    // get 方法可以不要, set 方法必須有,不然前端的數據就無法注入進來
    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 login() {
        System.out.println(username + " " + password); // 打印穿過來的數據
        ActionContext ac = ActionContext.getContext();
        // 得到 servlet 中的三大域的 session 域,在這裏我們要將數據保存至 session,並在前端展示
        Map<String,Object> session = ac.getSession(); // 我們可以看到 session 的實質就是一個 map
        User user = us.checklogin(username,password); // 登錄驗證
        if ( user!=null ) {
            session.put("user",username);
            return "success";
        } else {
            return "error";
        }
    }
}

5.4 編寫 struts 路由映射

記得在 Project Structure 添加如下配置
在這裏插入圖片描述

stucts action 配置

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>

    <package name="user" namespace="/" extends="struts-default">
        <action name="checklogin" class="ua" method="login">
        	<!-- 登錄成功挑戰至首頁 -->
            <result name="success" type="redirect">/index.jsp</result>
            <!-- 登錄失敗跳轉至錯誤頁面 -->
            <result name="error" type="redirect">/error.jsp</result>
        </action>
    </package>
</struts>

六、前端界面編寫

6.1 登錄界面編寫

<%--
  Created by IntelliJ IDEA.
  User: Gorit
  Date: 2020/6/13
  Time: 23:18
  Contact: [email protected]
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="checklogin" method="post">
        <label for="username">賬戶:</label>
        <input type="text" name="username" id="username"><br>
        <label for="password">密碼:</label>
        <input type="password" name="password" id="password"><br>
        <input type="submit" value="登錄">
    </form>

</body>
</html>

在這裏插入圖片描述

6.1 登錄成功

<%--
  Created by IntelliJ IDEA.
  User: Gorit
  Date: 2020/6/13
  Time: 23:21
  Contact: [email protected]
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>歡迎你 ${sessionScope.user} 登錄!!</h3>
</body>
</html>

在這裏插入圖片描述
在這裏插入圖片描述

6.3 登錄失敗

<%--
  Created by IntelliJ IDEA.
  User: Gorit
  Date: 2020/6/13
  Time: 23:21
  Contact: [email protected]
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h2>出錯啦!!!</h2>
</body>
</html>

在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章