本博文是按照 how2j.cn教程 Java天貓整站Springboot實戰項目學習的,該教程是我目前見過最好、最完整、最系統的Java入門學習到實戰的課程,做者列了完整的學習路線圖,有大量的實戰項目,由淺入深,很容易上手。
使用 IDEA 新建項目,點擊 Create New Project,選中maven webapp格式,而後next:
html
GroupId: com.how2java.tmall
Artifact: tmall_springboothtml5
項目路徑選擇:java
e:\project\tmall_springboot
Maven倉庫配置能夠參照咱們上一篇博文:
使用 Springboot 開發電商項目之開發環境搭建 (一)mysql
首先刪除 TmallSpringbootApplication.java
這個自動建立的類,而且把其包也刪除掉。git
複製以下內容到已經存在的pom裏,如圖所示,這個過程會致使idea去下載pom裏聲明的相關jar包,會花必定的時間,視網絡和計算機性能而定。
此時會彈出如圖所示的提醒,爲了不每次修改 pom.xml 都出現這個對話框,點擊 "Enable Auto-Import
"
爲了確保導入成功,右鍵點擊pom.xml->Maven->Reimportgithub
<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>
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; } }
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"; } }
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(); } }
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 語句的目的是爲了觀察 緩存是否起效果。
#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
本項目源代碼託管在GitHub上,地址:https://github.com/corwien/tmall_springboot/
Java學習資源推薦:
Java 最強學習站 https://how2j.cn?p=126405