使用 Springboot 開發電商項目之 IDEA 建立項目 (二)

本博文是按照 how2j.cn教程 Java天貓整站Springboot實戰項目學習的,該教程是我目前見過最好、最完整、最系統的Java入門學習到實戰的課程,做者列了完整的學習路線圖,有大量的實戰項目,由淺入深,很容易上手。

1、開發環境

  • OS MacOS
  • JDK 1.8
  • SpringBoot 1.5.9
  • IDEA IDEA 2019

2、新建項目

一、新建項目

使用 IDEA 新建項目,點擊 Create New Project,選中maven webapp格式,而後next:
filehtml

二、項目參數

GroupId: com.how2java.tmall
Artifact: tmall_springboothtml5

file

三、依賴

    1. 左邊選中 Web
    1. 右邊選中 Web

file

四、項目路徑

項目路徑選擇:java

e:\project\tmall_springboot

五、Maven倉庫

Maven倉庫配置能夠參照咱們上一篇博文:
使用 Springboot 開發電商項目之開發環境搭建 (一)mysql

file

六、刪除默認類

首先刪除 TmallSpringbootApplication.java 這個自動建立的類,而且把其包也刪除掉。git

七、配置 pom.xml

複製以下內容到已經存在的pom裏,如圖所示,這個過程會致使idea去下載pom裏聲明的相關jar包,會花必定的時間,視網絡和計算機性能而定。
此時會彈出如圖所示的提醒,爲了不每次修改 pom.xml 都出現這個對話框,點擊 "Enable Auto-Import"
爲了確保導入成功,右鍵點擊pom.xml->Maven->Reimportgithub

file

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.how2java.tmall</groupId>
  <artifactId>tmall_springboot</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>tmall_springboot</name>
  <description>tmall_springboot</description>
  <packaging>war</packaging>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
    </parent>
    <dependencies>
        <!-- springboot web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- springboot tomcat 支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- 熱部署 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>       
        <!-- jpa-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>        
        <!-- redis -->      
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>    
        <!-- springboot test --> 
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency> 
        <!-- thymeleaf -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!-- elastic search -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        <!-- 用了 elasticsearch 就要加這麼一個,否則要com.sun.jna.Native 錯誤 -->
        <dependency>
            <groupId>com.sun.jna</groupId>
            <artifactId>jna</artifactId>
            <version>3.0.9</version>
        </dependency>        
                 
        <!-- thymeleaf legacyhtml5 模式支持 -->      
        <dependency>
            <groupId>net.sourceforge.nekohtml</groupId>
            <artifactId>nekohtml</artifactId>
            <version>1.9.22</version>
        </dependency>        
        <!-- 測試支持 -->
        <dependency>
              <groupId>junit</groupId>
              <artifactId>junit</artifactId>
              <version>4.12</version>
              <scope>test</scope>
        </dependency>   
        <!-- tomcat的支持.-->
        <dependency>
               <groupId>org.apache.tomcat.embed</groupId>
               <artifactId>tomcat-embed-jasper</artifactId>
               <version>8.5.23</version>
        </dependency>    
        <!-- mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.21</version>
        </dependency>
      
        <!-- junit -->
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version> 4.12</version>
        </dependency>                
        <!-- commons-lang -->
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>       
        <!-- shiro -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.3.2</version>
        </dependency>        
        <!-- hsqldb -->
        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
        </dependency>    
    </dependencies>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

3、後臺分類管理

一、實體類

Category.javaweb

首先新建包,菜單 -> File -> Package -> 而後輸入ajax

com.how2java.tmall.pojo

而後建立類 Category,接下來.講解這個類。redis

@Entity

表示這是一個實體類spring

@Table(name = "category")

表示對應的表名是 category

@JsonIgnoreProperties({ "handler","hibernateLazyInitializer" })

由於是作先後端分離,而先後端數據交互用的是 json 格式。 那麼 Category 對象就會被轉換爲 json 數據。 而本項目使用 jpa 來作實體類的持久化,jpa 默認會使用 hibernate, 在 jpa 工做過程當中,就會創造代理類來繼承 Category ,並添加 handler 和 hibernateLazyInitializer 這兩個無須 json 化的屬性,因此這裏須要用 JsonIgnoreProperties 把這兩個屬性忽略掉。

package com.how2java.tmall.pojo;
 
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
 
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 
@Entity
@Table(name = "category")
@JsonIgnoreProperties({ "handler","hibernateLazyInitializer" })
 
public class Category {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")   
    int id;
     
    String name;
     
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
     
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

二、建立DAO類

CategoryDAO.java

在 Category.java 步驟裏已經講解過了如何建立包,這裏就不講解如何建立包,而是直接給出類了。
CategoryDAO 類集成了 JpaRepository,就提供了CRUD和分頁 的各類常見功能。 這就是採用 JPA 方便的地方~

package com.how2java.tmall.dao;
  
import org.springframework.data.jpa.repository.JpaRepository;
 
import com.how2java.tmall.pojo.Category;
 
public interface CategoryDAO extends JpaRepository<Category,Integer>{
 
}

三、服務類

CategoryService.java

@Service

標記這個類是 Service類

@Autowired CategoryDAO categoryDAO;

自動裝配 上個步驟的 CategoryDAO 對象

public List<Category> list() {
       Sort sort = new Sort(Sort.Direction.DESC, "id");
       return categoryDAO.findAll(sort);
   }

首先建立一個 Sort 對象,表示經過 id 倒排序, 而後經過 categoryDAO進行查詢。

注: 這裏拋棄了 CategoryService 接口 加上 CategoryService 實現類的這種累贅的寫法,而是直接使用 CategoryService 做爲實現類來作。
package com.how2java.tmall.service;
 
import java.util.List;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
 
import com.how2java.tmall.dao.CategoryDAO;
import com.how2java.tmall.pojo.Category;
 
@Service
public class CategoryService {
    @Autowired CategoryDAO categoryDAO;
 
    public List<Category> list() {
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        return categoryDAO.findAll(sort);
    }
}

四、頁面控制器類

AdminPageController.java
後臺管理頁面跳轉專用控制器。
由於是作先後端分離,因此數據是經過 RESTFUL接口來取的,而在業務上,除了 RESTFUL 服務要提供,還要提供頁面跳轉服務,因此全部的後臺頁面跳轉都放在 AdminPageController 這個控制器裏。 而RSTFUL 專門放在 Category 對應的控制器 CategoryController.java 裏面。 這樣代碼更清晰,不會攪起攪起的~

@Controller

表示這是一個控制器。

@GetMapping(value="/admin")
public String admin(){
   return "redirect:admin_category_list";
}

訪問地址 admin,就會客戶端跳轉到 admin_category_list去。

@GetMapping(value="/admin_category_list")
public String listCategory(){
    return "admin/listCategory";
}

訪問地址 admin_category_list 就會訪問 admin/listCategory.html 文件。

package com.how2java.tmall.web;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
 
@Controller
public class AdminPageController {
    @GetMapping(value="/admin")
    public String admin(){
        return "redirect:admin_category_list";
    }
    @GetMapping(value="/admin_category_list")
    public String listCategory(){
        return "admin/listCategory";
    }
}

五、REST服務控制器

CategoryController.java
這個就是專門用來提供 RESTFUL 服務器控制器了

@RestController

表示這是一個控制器,而且對每一個方法的返回值都會直接轉換爲 json 數據格式。

@Autowired CategoryService categoryService;

自動裝配 CategoryService

@GetMapping("/categories")
    public List<Category> list() throws Exception {
        return categoryService.list();
    }

對於categories 訪問,會獲取全部的 Category對象集合,並返回這個集合。 由於是聲明爲 @RestController, 因此這個集合,又會被自動轉換爲 JSON數組拋給瀏覽器。

package com.how2java.tmall.web;
 
import com.how2java.tmall.pojo.Category;
import com.how2java.tmall.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
 
import java.util.List;
  
@RestController
public class CategoryController {
    @Autowired CategoryService categoryService;
     
    @GetMapping("/categories")
    public List<Category> list() throws Exception {
        return categoryService.list();
    }
}

六、啓動類

啓動類,代替自動生成的 TmallSpringbootApplication.java

package com.how2java.tmall;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);    
    }
}

七、跨域配置類

CORSConfiguration.java
配置類,用於容許全部的請求都跨域。
由於是二次請求,第一次是獲取 html 頁面, 第二次經過 html 頁面上的 js 代碼異步獲取數據,一旦部署到服務器就容易面臨跨域請求問題,因此容許全部訪問都跨域,就不會出現經過 ajax 獲取數據獲取不到的問題了。

package com.how2java.tmall.config;
 
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
 
@Configuration
public class CORSConfiguration extends WebMvcConfigurerAdapter{
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        //全部請求都容許跨域
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("*")
                .allowedHeaders("*");
    }
}

八、異常處理類

GloabalExceptionHandler.java
異常處理,主要是在處理刪除父類信息的時候,由於外鍵約束的存在,而致使違反約束。

package com.how2java.tmall.exception;
 
import javax.servlet.http.HttpServletRequest;
 
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
@ControllerAdvice
public class GloabalExceptionHandler {
    @ExceptionHandler(value = Exception.class)
    public String defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
        e.printStackTrace();
        Class constraintViolationException = Class.forName("org.hibernate.exception.ConstraintViolationException");
        if(null!=e.getCause()  && constraintViolationException==e.getCause().getClass()) {
            return "違反了約束,多半是外鍵約束";
        }
        return e.getMessage();
    }
 
}

九、springboot配置文件

application.properties
springboot 配置文件,有些項目會用 application.yml ,站長習慣用 .properties ,以爲更易讀。

下面是配置文件的內容:

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/tmall_springboot?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=admin
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto = none

分別是數據庫訪問地址,帳號密碼,驅動以及表結構自動生成策略(none)。

spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.cache=false

使用 thymeleaf 做爲視圖,這個是springboot 官方推薦視圖,它的好處是能夠是純 html
其中LEGACYHTML5表示經典html5模式,即容許非嚴格的html出現,元素少點什麼也能夠編譯經過, 這個比較符合你們的編寫習慣,太過嚴格的html,寫起來累。
cache=false 表示不要緩存,以避免在開發過程當中由於停留在緩存而給開發人員帶來困擾。

server.context-path=/tmall_springboot

上下文地址爲 tmall_springboot, 因此訪問的時候,都要加上這個,好比:

http://127.0.0.1:8080/tmall_springboot/admin
spring.http.multipart.maxFileSize=100Mb
spring.http.multipart.maxRequestSize=100Mb

設置上傳文件大小,默認只有1 m

spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

jpa對實體類的默認字段會把駝峯命名的屬性,轉換爲字段名的時候自動加上下劃線。 這個配置的做用就是去掉下劃線
好比屬性名稱是 createDate, jpa 默認轉換爲字段名 create_Date。 有了這個配置以後,就會轉換爲同名字段 createDate

spring.jpa.show-sql=true

顯示 hibernate 執行的sql語句。 這個在上線以後,應該是關掉的,由於大量的 控制檯輸出會嚴重影響系統性能。 可是呢,由於本項目會和 redis 和 es 整合,打印 sql 語句的目的是爲了觀察 緩存是否起效果。
file

#database
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/tmall_springboot?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=admin
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto = none
 
#thymeleaf
spring.thymeleaf.mode=LEGACYHTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.cache=false
 
#context
server.context-path=/tmall_springboot
 
#設置上傳文件大小,默認只有1 m
spring.http.multipart.maxFileSize=100Mb
spring.http.multipart.maxRequestSize=100Mb
 
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
 
#顯示 hibernate運行的 sql 語句
spring.jpa.show-sql=true

4、項目源代碼

本項目源代碼託管在GitHub上,地址:https://github.com/corwien/tmall_springboot/


Java學習資源推薦:
Java 最強學習站 https://how2j.cn?p=126405

相關文章
相關標籤/搜索