喜歡就點個贊唄!
GitHub項目ssm-learn-crm
show me the code and take to me,做的出來更要說的明白
1.1 克隆
git clone https://github.com/buerbl/ssm-learn-crm.git
1. 2 結果
2 分析需求
我們需要做一個客戶系統,使用者可以在系統上面保存、編輯、刪除、客戶信息。
3 技術選型
這次我們選擇 ssm 三大框架搭建系統的后端,前端頁面的話用 JSP 以及 JQuery EasyUI;數據庫使用 MySQL;項目構想使用 Maven 工具。
技術 | 作用 |
---|---|
Spring | 管理對象,管理事務等 |
SpringMVC | 路徑跳轉,請求訪問等 |
Mybatis | 數據獲取等 |
JQuery EasyUI | 頁面展示等 |
MySQL | 存取數據等 |
IDEA | 快速寫代碼等 |
Navicat | 數據庫可視化軟件 |
4 數據庫
我們需要保存客戶的名字、性別、聯系方式和地址,因此我們的數據庫腳本如下
CREATE table t_customer(
id int PRIMARY KEY auto_increment,
name VARCHAR(20),
gender char(1),
telephone VARCHAR(20),
address VARCHAR(50)
);
5 Maven 管理
5.1 jar 包
一次性導入我們需要的jar,依賴如下
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.4.2</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.26</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.12</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.6.0</version>
</dependency>
</dependencies>
5.2 編譯問題
可能當我們編譯的時候,我們發現 webapp 的文件並沒有編譯進來,我們需要在 pom.xml 中加入如下,告訴 Mavne 需要編譯特定文件。
<build>
<resources>
<resource>
<directory>src/main/webapp</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
6 划分層次
來到這里的話,我們需要建立文件夾,准備開始寫代碼。一般按照套路的話,我喜歡如下的規則
文件夾 | 作用 |
---|---|
controller | 控制層代碼 |
domain | 實體類代碼 |
dao | Mapper代碼 |
service | 服務層代碼 |
7 實體類代碼
我們根據數據庫字段編寫實體類代碼,代碼如下,我使用了 lombok 框架,這個東西需要 IDEA 安裝一個 lombok 插件。
package com.buer.domain;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
* @Description:
* @Author: boolean
* @Date: 2019/12/22 11:51
*/
@Getter
@Setter
@ToString
@AllArgsConstructor
public class Customer {
private Integer id;
private String name;
private String gender;
private String telephone;
private String address;
}
有個問題,這些字段是怎樣和數據庫字段一一對應的呢?下面揭曉。
8 Mapper代碼
這里我們需要的 Mybatis 要上場了,首先我們需要如下Mapper代碼
package com.buer.dao;
import com.buer.domain.Customer;
import java.util.List;
public interface CustomerMapper {
/**
* 添加客戶
*/
void saveCustomer(Customer customer);
/**
* 查詢所有客戶
* @return
*/
List<Customer> list();
/***
* 查找某個客戶
* @param id
* @return
*/
Customer findById(Integer id);
}
9 Mapper 對應的 xml
有了 Mapper 代碼,我們需要給 Mapper 配上相應的 xml 文件。如下
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 該文件編寫mybatis中的mapper接口里面的方法提供對應的sql語句 -->
<mapper namespace="com.buer.dao.CustomerMapper">
<!-- 添加客戶 -->
<insert id="saveCustomer" parameterType="com.buer.domain.Customer">
INSERT INTO ssm.t_customer
(
NAME,
gender,
telephone,
address
)
VALUES
(
#{name},
#{gender},
#{telephone},
#{address}
)
</insert>
<select id="list" resultType="com.buer.domain.Customer">
select * from t_customer
</select>
<select id="findById" resultType="com.buer.domain.Customer">
select * from t_customer where id = #{id}
</select>
</mapper>
解答上面的問題,實體類字段是怎樣和數據庫字段一一對應,通過 resultType 來自動映射。
10 服務層代碼
先來接口層的代碼。代碼如下
package com.buer.service;
import com.buer.domain.Customer;
import java.util.List;
public interface IcustomerService {
/**
* 添加客戶
*/
void saveCustomer(Customer customer);
/**
* 返回所有數據
* @return
*/
List<Customer> list();
/**
* 修數據
* @return
*/
Customer findById(Integer id);
}
然后實現接口,代碼如下
package com.buer.service.Impl;
import com.buer.dao.CustomerMapper;
import com.buer.domain.Customer;
import com.buer.service.IcustomerService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
/**
* @Description:
* @Author: boolean
* @Date: 2019/12/22 18:28
*/
@Service("customerService")
public class IcustomerServiceImpl implements IcustomerService {
@Resource
private CustomerMapper customerMapper;
@Override
@Transactional
public void saveCustomer(Customer customer) {
customerMapper.saveCustomer(customer);
}
@Override
public List<Customer> list() {
return customerMapper.list();
}
@Override
public Customer findById(Integer id) {
return customerMapper.findById(id);
}
}
這里我們看到@Service("customerService")
,@Resource
, @Transactional
,這些注解他們的作用是啥子哦?請看下面
注解 | 作用 |
---|---|
@Service("customerService") | 告訴 Spring, 這是一個叫 customerService 的東西,你要照顧好她,給他在初始化的時候創建一個對象。 |
@Resource | Java里面的注解,注入對象 |
@Transactional | 告訴 Spring,需要開始事務 |
11 控制層代碼
這里就是 SpringMVC 的舞台了。代碼如下
package com.buer.controller;
import com.buer.domain.Customer;
import com.buer.service.IcustomerService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import java.util.List;
/**
* @Description:
* @Author: boolean
* @Date: 2019/12/22 18:50
*/
@Controller
@RequestMapping("/customer")
public class CustomerController {
@Resource
private IcustomerService service;
@RequestMapping("/index")
public String test(){
System.out.println("ssss");
return "index";
}
@RequestMapping("/save")
public String save(Customer customer){
System.out.println("save");
service.saveCustomer(customer);
return "success";
}
@RequestMapping("/list")
@ResponseBody
public List<Customer> list(){
System.out.println("list");
return service.list();
}
@RequestMapping("/findById")
@ResponseBody
public Customer findById(Integer id){
System.out.println("findById");
return service.findById(id);
}
}
注解 | 作用 |
---|---|
@Controller | 告訴 SpringMVC, 這是你負責的代碼 |
@RequestMapping("/save") | 告訴 SpringMVC,用 “/save”路徑訪問 |
@ResponseBody | 告訴 SpringMVC,需要返回JSON |
以上就是代碼的編寫,但是還沒有完成哈,我們需要一些配置文件。
12 jdbc.properties
我們要連接數據庫,代碼如下
jdbc.url=jdbc:mysql://localhost:3306/ssm
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.user=root
jdbc.password=123456
13 applicationContext.xml
我們要告訴 Spring 連接數據庫,以及我們寫的代碼在哪里,怎么去操作我們的代碼。代碼如下
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 讀取jdbc.properties -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 創建DataSource -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="url" value="${jdbc.url}"/>
<property name="driverClassName" value="${jdbc.driverClass}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
<property name="maxActive" value="10"/>
<property name="maxIdle" value="5"/>
</bean>
<!-- 創建SqlSessionFactory對象 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 關聯連接池 -->
<property name="dataSource" ref="dataSource"/>
<!-- 加載mapper.xml -->
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean>
<!-- Mapper所有接口的掃描 -->
<!--注意:如果使用Mapper接口包掃描,那么每個Mapper接口在Spring容器中的id名稱為類名: 例如 CustomerMapper -> customerMapper-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 配置Mapper接口所在包路徑 -->
<property name="basePackage" value="com.buer.dao"></property>
</bean>
<!-- 開啟Spring的IOC注解掃描 -->
<context:component-scan base-package="com.buer"/>
<!-- 開啟Spring的事務 -->
<!-- -事務管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 啟用Spring事務注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
14 spring-mvc.xml
我們需要告訴 SpringMVC,他需要的代碼在哪里,怎么去操作我們的代碼
15 web.xml
我們需要啟動項目了,以及一些字體指定。代碼如下
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>01.mybatis</display-name>
<!-- 配置SpringMVC編碼過濾器 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 啟動SpringMVC -->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 參數:讀取spring-mvc.xml -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<!-- 啟動spring -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 修改路徑 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
</web-app>
這里的話,后端就搭起來了。
16 頁面編寫
16.1 index.jsp
我們需要編寫首頁,代碼如下
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>booleanbl 公眾號 客戶關系管理系統</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">
<script type="text/javascript" src="easyui/jquery.min.js"></script>
<script type="text/javascript" src="easyui/jquery.easyui.min.js"></script>
<script type="text/javascript" src="easyui/locale/easyui-lang-zh_CN.js"></script>
<link rel="stylesheet" type="text/css" href="easyui/themes/icon.css">
<link id="themeLink" rel="stylesheet" type="text/css" href="easyui/themes/default/easyui.css">
<style type="text/css">
ul{
line-height: 30px;
}
</style>
</head>
<body class="easyui-layout">
<!-- 頂部 -->
<div data-options="region:'north',split:true" style="height:80px;">
<!-- logo -->
<div id="logo">
<img src="images/20191223003101.png"/>
</div>
<!-- 登錄用戶信息 -->
<div id="loginDiv" style="position: absolute;right: 20px;top: 20px;">
歡迎你,[超級管理員],你使用[192.156.21.22]IP登錄!
</div>
<div id="themesDiv" style="position: absolute;right: 20px;top:40px;">
<a href="javascript:void(0)" id="mb" class="easyui-menubutton"
data-options="menu:'#Themesmeus',iconCls:'icon-edit'">切換風格</a>
<div id="Themesmeus" style="width:150px;">
<div>default</div>
<div>gray</div>
<div>black</div>
<div>bootstrap</div>
<div>material</div>
<div>metro</div>
</div>
</div>
</div>
<!-- 底部 -->
<div data-options="region:'south',split:true" style="height:30px;">
<div id="copyrightDiv" style="text-align: center;">
booleanbl出品©2018版權所有
</div>
</div>
<!-- 左邊系統菜單 -->
<div data-options="region:'west',title:'系統菜單',split:true" style="width:200px;">
<div id="aa" class="easyui-accordion" style="width:193px;" data-options="border:0,multiple:true" >
<div title="系統管理" data-options="iconCls:'icon-reload',selected:true" style="padding:10px;">
<ul>
<li><a href="javascript:void(0)" pageUrl="customer_manage.jsp">客戶管理</a></li>
</ul>
</div>
</div>
</div>
<!-- 中間編輯區域 -->
<div data-options="region:'center'" style="padding:5px;background:#eee;">
<div id="tt" class="easyui-tabs" style="width:500px;height:250px;" data-options="fit:true">
<div title="起始頁" style="padding:20px;display:none;">
歡迎登錄booleanbl客戶關系管理系統
</div>
</div>
</div>
<script type="text/javascript">
$(function(){
//給a標簽綁定時間
$("a[pageUrl]").click(function(){
//1.獲取pageUrl屬性值(需要跳轉的頁面地址)
var pageUrl = $(this).attr("pageUrl");
//獲取a標簽的內容,標題
var title = $(this).text();
//2.判斷是否存在指定標題的選項卡
if( $("#tt").tabs("exists",title) ) {
//3.如果存在,則選項該選項卡
$("#tt").tabs("select",title);
}else{
//4.如果不存在,則添加選項卡
$("#tt").tabs("add",{
title:title,
content:"<iframe src='"+pageUrl+"' width='100%' height='100%' frameborder='0'><iframe>",
closable:true
});
}
});
//點擊切換模塊菜單的時候,進行切換模塊
$("#Themesmeus").menu({
onClick:function(item){
//1.獲取需要改變的模塊名稱
var themeName = item.text;
//2.獲取link標簽的href屬性
var href= $("#themeLink").attr("href");
//3.更改href的屬性值
// easyui/themes/default/easyui.css
href = href.substring(0,href.indexOf("themes"))+"themes/"+themeName+"/easyui.css";
//4.更新link的href屬性
$("#themeLink").attr("href",href);
}
});
});
</script>
</body>
</html>
16.2 customer_manage.jsp
我們需要詳情頁,代碼如下
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>客戶管理</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">
<!-- 導入easyui的資源文件 -->
<script type="text/javascript" src="easyui/jquery.min.js"></script>
<script type="text/javascript" src="easyui/jquery.easyui.min.js"></script>
<script type="text/javascript" src="easyui/locale/easyui-lang-zh_CN.js"></script>
<link rel="stylesheet" type="text/css" href="easyui/themes/icon.css">
<link id="themeLink" rel="stylesheet" type="text/css" href="easyui/themes/default/easyui.css">
</head>
<body>
<table id="list"></table>
<!-- 工具條 -->
<div id="tb">
<a id="addBtn" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-add',plain:true">添加</a>
<a id="editBtn" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-edit',plain:true">修改</a>
<a id="deleteBtn" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-remove',plain:true">刪除</a>
</div>
<!-- 編輯窗口 -->
<div id="win" class="easyui-window" title="客戶數據編輯" style="width:500px;height:300px"
data-options="iconCls:'icon-save',modal:true,closed:true">
<form id="editForm" method="post">
<%--提供id隱藏域 --%>
<input type="hidden" name="id">
客戶姓名:<input type="text" name="name" class="easyui-validatebox" data-options="required:true"/><br/>
客戶性別:
<input type="radio" name="gender" value="男"/>男
<input type="radio" name="gender" value="女"/>女
<br/>
客戶手機:<input type="text" name="telephone" class="easyui-validatebox" data-options="required:true"/><br/>
客戶住址:<input type="text" name="address" class="easyui-validatebox" data-options="required:true"/><br/>
<a id="saveBtn" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-save'">保存</a>
</form>
</div>
<script type="text/javascript">
$(function(){
$("#list").datagrid({
//url:后台數據查詢的地址
url:"customer/list.action",
//columns:填充的列數據
//field:后台對象的屬性
//tille:列標題
columns:[[
{
field:"id",
title:"客戶編號",
width:100,
checkbox:true
},
{
field:"name",
title:"客戶姓名",
width:200
},
{
field:"gender",
title:"客戶性別",
width:200
},
{
field:"telephone",
title:"客戶手機",
width:200
},
{
field:"address",
title:"客戶住址",
width:200
}
]],
//顯示分頁
pagination:true,
//工具條
toolbar:"#tb"
});
//打開編輯窗口
$("#addBtn").click(function(){
//清空表單數據
$("#editForm").form("clear");
$("#win").window("open");
});
//保存數據
$("#saveBtn").click(function(){
$("#editForm").form("submit",{
//url: 提交到后台的地址
url:"customer/save.action",
//onSubmit: 表單提交前的回調函數,true:提交表單 false:不提交表單
onSubmit:function(){
//判斷表單的驗證是否都通過了
return $("#editForm").form("validate");
},
//success:服務器執行完畢回調函數
success:function(data){ //data: 服務器返回的數據,類型字符串類
//要求Controller返回的數據格式:
//成功:{success:true} 失敗:{success:false,msg:錯誤信息}
//把data字符串類型轉換對象類型
data = eval("("+data+")");
if(data.success){
//關閉窗口
$("#win").window("close");
//刷新datagrid
$("#list").datagrid("reload");
$.messager.alert("提示","保存成功","info");
}else{
$.messager.alert("提示","保存失敗:"+data.msg,"error");
}
}
});
});
//修改數據
$("#editBtn").click(function(){
//判斷只能選擇一行
var rows = $("#list").datagrid("getSelections");
if(rows.length!=1){
$.messager.alert("提示","修改操作只能選擇一行","warning");
return;
}
//表單回顯
$("#editForm").form("load","customer/findById.action?id="+rows[0].id);
$("#win").window("open");
});
//刪除
$("#deleteBtn").click(function(){
var rows =$("#list").datagrid("getSelections");
if(rows.length==0){
$.messager.alert("提示","刪除操作至少選擇一行","warning");
return;
}
//格式: id=1&id=2&id=3
$.messager.confirm("提示","確認刪除數據嗎?",function(value){
if(value){
var idStr = "";
//遍歷數據
$(rows).each(function(i){
idStr+=("id="+rows[i].id+"&");
});
idStr = idStr.substring(0,idStr.length-1);
//傳遞到后台
$.post("customer/delete.action",idStr,function(data){
if(data.success){
//刷新datagrid
$("#list").datagrid("reload");
$.messager.alert("提示","刪除成功","info");
}else{
$.messager.alert("提示","刪除失敗:"+data.msg,"error");
}
},"json");
}
});
});
});
</script>
</body>
</html>
完成
常見問題
java-lang-illegalargumentexception-no-converter-found-for-return-value-of-type
原因是沒有轉換json返回
- 在 CustomerController 上添加
@ResponseBody
- 需要添加 jackson 依賴