建站四部曲以後端接口篇(SpringBoot+上線)

本系列分爲四篇:

零、前言

本系列爲了總結一下手上的知識,致敬個人2018
本篇的重點在於:搭建一個後端的url接口服務,並運行到服務器上
本篇總結的技術點:SpringBootmybaits整合mysql簡單操做ResetFul接口文件上傳跨域處理html


1、SpringBoot初始搭建

一、Idea中新建SpringBoot項目(分包以下):

按哪一個鍵新建項目,這裏就不廢話了,新手請轉到:SpringBoot-01-之初體驗前端

項目分包.png


二、pom.xml添加依賴:
<dependencies>
    <!--mysql依賴-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!--mybatis依賴-->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>1.3.2</version>
    </dependency>
    <!--web依賴-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>RELEASE</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
複製代碼

3.配置application.properties(或application.yml,我喜歡後者)

注意修改的:數據庫名mycode,用戶名:username: XXXX,密碼:password: XXXXjava

spring:
    datasource:
      url: jdbc:mysql://localhost:3306/mycode?useSSL=true&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&serverTimezone=Asia/Shanghai&URIEncoding="UTF-8"
      username: root
      password: ****
      driver-class-name: com.mysql.jdbc.Driver

#坑點0 配置mybatis的xml位置
mybatis:
  mapper-locations: classpath:mapper/*.xml
複製代碼

mark一下踩的兩個坑:mysql

1).好像是MySQL時區的問題,致使鏈接異常:
>配置時數據庫鏈接參數添加:`&serverTimezone=Asia/Shanghai`可解決

2).一開始用get測試是否插入成功,可是報錯了,仔細看了看,貌似是從中文的地方:
>配置時數據庫鏈接參數添加:`&URIEncoding="UTF-8"`
複製代碼

2、MySQL的簡單總結

一、建庫建表
1).肯定想要的單體
{
    "id":"1"
    "type": "繪圖相關",
    "name": "Android關於Canvas你所知道的和不知道的一切",
    "localPath":"I:\Java\Android\Unit\C\app\src\main\java\com\toly1994\c\view\CanvasView.java",
    "jianshuUrl":"https://www.jianshu.com/p/4bc05f646bfe",
    "juejinUrl":"https://juejin.im/post/5be29aa2e51d45228170ff33",
    "imgUrl":"域名:端口/android/Android關於Canvas你所知道的和不知道的一切.png",
    "createTime":"2018-11-05"
}
複製代碼

2).建立數據庫mycode和表android
//建立數據庫
CREATE DATABASE mycode;
USE mycode;
//建立表
CREATE TABLE android (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
type VARCHAR(8) NOT NULL,
name VARCHAR(32) NOT NULL,
localPath VARCHAR(120) NOT NULL,
jianshuUrl VARCHAR(120) NOT NULL,
juejinUrl VARCHAR(120) NOT NULL,
imgUrl VARCHAR(120) NOT NULL,
createTime DATE NOT NULL
);
複製代碼

建立數據庫成功.png


3).爲了總結一下聯合查詢,建立表type
CREATE TABLE type(
   id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
   type_idx  VARCHAR(4)   NOT NULL,
   type  VARCHAR(48)  NOT NULL
 );
複製代碼
4).插入類型數據:
INSERT INTO type(type_idx, type)
VALUES('ABCS', '四大組件'), ('C', '繪圖相關'), ('D', '自定義控件'),
('F', 'Fragment'), ('G', '開源計劃'), ('V', '原生View'),
('MD', '材料設計'), ('L', '底層核心'), ('M', '多媒體相關'),
('N', '網絡相關'), ('O', '三方框架'), ('P', '手機設備相關'),
('S', '數據存讀相關'), ('T', '紛雜小技術');
複製代碼

type.png


2.MySQL語句的簡單回顧
-->插入數據:
insert into android(type,name,localPath,jianshuUrl,juejinUrl,imgUrl,createTime)
values (XX,XX,XX,XX,XX,XX,XX)

-->更新數據:
UPDATE android
SET type=XX,name=XX,localPath=XX,jianshuUrl=XX,juejinUrl=XX,imgUrl=XX,createTime=XX
WHERE id=XX

-->查詢全部+INNER JOIN
<select id="findALL" resultType="toly1994.com.android_project.bean.Note">
   SELECT a.id,name,t.type,localPath,jianshuUrl,juejinUrl,imgUrl,createTime FROM android AS a
   INNER JOIN type AS t ON a.type = t.type_idx;
</select>

-->根據id查詢
SELECT a.id,name,t.type,localPath,jianshuUrl,juejinUrl,imgUrl,createTime FROM android AS a
INNER JOIN type AS t ON a.type = t.type_idx
WHERE a.id=XX

-->根據type查詢
SELECT a.id,name,t.type,localPath,jianshuUrl,juejinUrl,imgUrl,createTime FROM android AS a
INNER JOIN type AS t ON a.type = t.type_idx
 WHERE a.type=XX;


-->根據name部分字符查詢
SELECT a.id,name,t.type,localPath,jianshuUrl,juejinUrl,imgUrl,createTime FROM android AS a
INNER JOIN type AS t ON a.type = t.type_idx
WHERE name like '%XX%';

-->根據id刪除數據
DELETE FROM android
WHERE id=#{id}
複製代碼

3、書寫流程+插入測試:

1.文件簡介

初級搭建.png

1.AndroidProjectApplication.java 啓動文件,坑點在加掃包範圍  
2.application.yml 配置文件
3.Note.xml 經過sql語句操做數據庫映射出實體類返給dao
4.NoteDao.java 數據庫操做接口
5.NoteService.java 根據業務邏輯對dao返回的數據進行必定加工
6.Note.java 實體類,用於承接數據庫中的數據
7.NoteController.java 核心操做層,生成可訪問的url接口,向外暴露
複製代碼

下面以插入數據來演示一下操做流程android


2.建立實體類:toly1994.com.android_project.bean.Note.java
public class Note {
    private int id;//id
    private String type;//類型
    private String name;//名稱
    private String localPath;//路徑
    private String jianshuUrl;//簡書地址
    private String juejinUrl;//掘金地址
    private String imgUrl;//掘金地址
    private String createTime;//建立時間
    //構造方法,get、set、toString略
}
複製代碼

3.映射xml:mapper/Note.xml

根據規範,在相應的位置寫出sql語句就能夠了
其中#{type}表明dao中方法傳入的參數git

<?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">
<!--坑點2:命名空間指向對應dao類名-->
<mapper namespace="toly1994.com.android_project.dao.NoteDao">
    <!--坑點3:id爲dao中相應方法名-->
    <insert id="insert">
      insert into android(type,name,localPath,jianshuUrl,juejinUrl,imgUrl,createTime)
      values (#{type},#{name},#{localPath},#{jianshuUrl},#{juejinUrl},#{imgUrl},#{createTime})
    </insert>
</mapper>

複製代碼

4.數據庫操做:toly1994.com.android_project.dao.NoteDao
/**
 * 做者:張風捷特烈
 * 時間:2018/11/19 0019:13:27
 * 郵箱:1981462002@qq.com
 * 說明:dao層---數據庫操做
 */
public interface NoteDao {
    //坑點1 java沒有保存形參的記錄,因此多參數用戶@Param("name")起名字,否則沒法識別
    int insert(@Param("type") String type,
               @Param("name") String name,
               @Param("localPath") String localPath,
               @Param("jianshuUrl") String jianshuUrl,
               @Param("juejinUrl") String juejinUrl,
               @Param("imgUrl") String imgUrl,
               @Param("createTime") String createTime);
}
複製代碼

5.業務層:toly1994.com.android_project.service.NoteService
/**
 * 做者:張風捷特烈
 * 時間:2018/11/19 0019:13:48
 * 郵箱:1981462002@qq.com
 * 說明:Service層---操做dao
 */
@Service
public class NoteService {
    @Autowired
    private NoteDao mNoteDao;
    @Transactional
    public String insertNote(Note note) {
        mNoteDao.insert(note.getType(), note.getName(),
                note.getLocalPath(), note.getJianshuUrl(),
                note.getJuejinUrl(), note.getImgUrl(),
                note.getCreateTime());
        return "OK";
    }
}
複製代碼

6.控制層:toly1994.com.android_project.controller.NoteController
/**
 * 做者:張風捷特烈
 * 時間:2018/11/19 0019:13:34
 * 郵箱:1981462002@qq.com
 * 說明:控制層---生成url接口
 */
@RestController
public class NoteController {
    @Autowired
    private NoteService mNoteService;
    
    @GetMapping("/test/insert")
    public String insert() {
        Note note = new Note("C", "Android關於Canvas你所知道的和不知道的一切",
                "I:\\Java\\Android\\Unit\\C\\app\\src\\main\\java\\com\\toly1994\\c\\view\\CanvasView.java"
                , "https://www.jianshu.com/p/4bc05f646bfe", "https://juejin.im/post/5be29aa2e51d45228170ff33",
                "http://localhost:8080/android/Android關於Canvas你所知道的和不知道的一切.png", "null");
        mNoteService.insertNote(note);
        return "ok";
    }
}
複製代碼

7.啓動類:注意坑點,啓動類,加掃包
@SpringBootApplication
//坑點5:將dao添加掃包範圍
@MapperScan(basePackages = {"toly1994.com.android_project.dao"})
public class AndroidProjectApplication {
    public static void main(String[] args) {
        SpringApplication.run(AndroidProjectApplication.class, args);
    }
}
複製代碼

在瀏覽器上訪問接口即可以將數據插入數據庫:(這裏用GET先測試一下,後面會作成POST)github

插入成功.png


4、實現RESTFUL的api接口(簡單的CRUD)

1.POST添加數據:http://域名:端口/api/android/note

接口統一採用RESTFUL風格:/api/android/XXX,關於RESTFUL風格,詳見:
修改控制器:NoteController,將插入方法改成POST,並在插入後,向訪問者返回插入信息(json格式)web

/**
 * 做者:張風捷特烈
 * 時間:2018/11/19 0019:13:34
 * 郵箱:1981462002@qq.com
 * 說明:控制層---生成url接口
 */
@RestController
@RequestMapping(value = "/api/android")

public class NoteController {

    @Autowired
    private NoteService mNoteService;

    @PostMapping(value = "/note")
    public Note addOne(@ModelAttribute Note note) {
        mNoteService.insertNote(note);
        return note;
    }
}
複製代碼

使用Postman新建一個測試文件夾進行測試.png

POST插入成功.png


2.PUT修改數據:http://192.168.43.60:8089/api/android/note/[id]
1).mapper/Note.xml:添加SQL語句
<update id="updateById">
    UPDATE android
    SET type=#{type},name=#{name},localPath=#{localPath},jianshuUrl=#{jianshuUrl},juejinUrl=#{juejinUrl},imgUrl=#{imgUrl}
    WHERE id=#{id}
</update>
複製代碼
2).NoteDao:添加方法接口
/**
 * 經過id修改一條記錄
 *
 * @param id
 * @return
 */
void updateById(@Param("id") int id,
                @Param("type") String type,
                @Param("name") String name,
                @Param("localPath") String localPath,
                @Param("jianshuUrl") String jianshuUrl,
                @Param("juejinUrl") String juejinUrl,
                @Param("imgUrl") String imgUrl,
                @Param("createTime") String createTime);
複製代碼
3).NoteService:添加Service層方法
@Transactional
public Note updateNote(int id, Note note) {
    mNoteDao.updateById(id,
            note.getType(),
            note.getName(),
            note.getLocalPath(),
            note.getJianshuUrl(),
            note.getJuejinUrl(),
            note.getImgUrl(),
            note.getCreateTime());
    return note;
}
複製代碼
4).NoteController:添加url訪問接口
@PutMapping(value = "/note/{id}")
public Note updateById(@PathVariable("id") Integer id, @ModelAttribute Note note) {
    mNoteService.updateNote(id,note);
    return note;
}
複製代碼

PUT修改爲功.png


3.查詢數據:

通過上面幾個,應該熟悉寫法了:
先在dao添加方法,再寫SQL,再將dao用Service過渡一下給Controllerspring

//DAO
/**
 * 查詢全部
 * @return
 */
List<Note> findALL();

//SQL語句
<select id="findALL" resultType="toly1994.com.android_project.bean.Note">
    SELECT*FROM android
</select>

//Service
public List<Note> findAll() {
    return mNoteDao.findALL();
}

//Controller
@GetMapping(value = "/note")
public List<Note> findAll() {
    return mNoteService.findAll();
}
複製代碼

get請求全部.png


4.查詢單個(以id字段爲例,其餘字段相似)
//DAO
/**
 * 根據id查詢
 * @return
 */
Note findById(@Param("id") int id);

//SQL語句
<select id="findById" resultType="toly1994.com.android_project.bean.Note">
    SELECT*FROM android
    WHERE id=#{id}
</select>

//Service
public Note findById(int id){
    return mNoteDao.findById(id);
}

//Controller
@GetMapping(value = "/note/{id}")
public Note findById(@PathVariable("id") Integer id) {
    return mNoteService.findById(id);
}
複製代碼

根據id查詢.png


5.刪除單個數據(以id字段爲例,其餘字段相似)
//DAO
/**
 * 根據id刪除
 * @param id
 */
void deleteById(@Param("id") int id);

//SQL語句
<delete id="deleteById">
    DELETE FROM android
    WHERE id=#{id}
</delete>

//Service
@Transactional
public int deleteById(int id){
    mNoteDao.deleteById(id);
    return id;
}

//Controller
@DeleteMapping(value = "/note/{id}")
public int deleteById(@PathVariable("id") Integer id) {
    return mNoteService.deleteById(id);
}
複製代碼

根據id刪除.png


3、數據返回形式優化統一與異常捕捉

統一返回.png


1.結果統一返回形式
//成功的json:
{
    "code": 200,
    "msg": "操做成功",
    "data": {
        "id": 2,
        "type": "B",
        "name": "BASE",
        "localPath": "c",
        "jianshuUrl": "http://jianshu",
        "juejinUrl": "http://juejin",
        "imgUrl": "imgUrl",
        "create": null
    }
}

//失敗的json:
{
    "code": 500,
    "msg": "/ by zero",
    "data": null
}
複製代碼

統一數據返回格式.png


2.統一格式實現:
/**
 * 做者:張風捷特烈
 * 時間:2018/5/25:15:30
 * 郵箱:1981462002@qq.com
 * 說明:格式化請求返回值
 */
public class ResultBean<T> {
    private int code;
    private String msg;
    private T data;

    public ResultBean(int code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }
    //get、set、toString省略
}
複製代碼
3.使用枚舉類統一錯誤碼與錯誤信息維護

用來維護一些錯誤枚舉,可自定義,在捕獲異常時對應拋出,以便管理
如默認狀況查詢一個數據庫沒有的id是不會報錯的,這時能夠自定義一個id未知異常,在Service層捕獲一下sql

自定義異常.png

/**
 * 做者:張風捷特烈
 * 時間:2018/5/25:17:36
 * 郵箱:1981462002@qq.com
 * 說明:使用枚舉類統一錯誤碼與錯誤信息維護
 */
public enum ResultEnum {
    SUCCESS(200, "操做成功"),
    EXCEPTION(500, "起它異常"),
    NOT_FOUND_ID(102, "未知id");
    private int code;
    private String msg;
    ResultEnum(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }
    public int getCode() {
        return code;
    }
    public String getMsg() {
        return msg;
    }
}
複製代碼
/**
 * 做者:張風捷特烈
 * 時間:2018/5/25:17:14
 * 郵箱:1981462002@qq.com
 * 說明:id未知異常
 */
public class NotFoundIdException extends RuntimeException {
    private int code;
    private static String msg = ResultEnum.NOT_FOUND_ID.getMsg();
    public NotFoundIdException() {
        super(msg);
    }
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
}

複製代碼
//Service中捕獲異常
public Note findById(int id) {
    Note byId = mNoteDao.findById(id);
    if (byId == null) {
        throw new NotFoundIdException();
    }
    return byId;
}
複製代碼

4.結果處理類

使用該類將全部結果轉化爲ResultBean對象,實現返回值的統一

/**
 * 做者:張風捷特烈
 * 時間:2018/5/30:18:37
 * 郵箱:1981462002@qq.com
 * 說明:結果處理類
 */
public class ResultHandler {
    /**
     * 成功時將object對象轉化爲ResultBean對象
     *
     * @param o
     * @return
     */
    public static ResultBean ok(Object o) {
        return new ResultBean(ResultEnum.SUCCESS.getCode(), ResultEnum.SUCCESS.getMsg(), o);
    }

    /**
     * 使用枚舉列舉錯誤類型
     *
     * @param error
     * @return
     */
    public static ResultBean error(ResultEnum error) {
        return new ResultBean(error.getCode(), error.getMsg(), null);
    }

    public static ResultBean error(String e) {
        return new ResultBean(ResultEnum.EXCEPTION.getCode(), e, null);
    }
}
複製代碼

5.異常的捕獲:

@ExceptionHandler和@ControllerAdvice會讓全部的異常走這裏,用ResultHandler統一處理
這裏能夠爲項目自定義一些異常

/**
 * 異常捕獲類
 */
@ControllerAdvice
public class ExceptionHandle {

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResultBean handle(Exception e) {
        return ResultHandler.error(e.getMessage());
    }
}

複製代碼

6.將Controller中的全部返回結果都包裹成ResultBean
@RestController
@RequestMapping(value = "/api/android")

public class NoteController {

    @Autowired
    private NoteService mNoteService;

    @PostMapping(value = "/note")
    public ResultBean addOne(@ModelAttribute Note note) {
        mNoteService.insertNote(note);
        return ResultHandler.ok(note);
    }

    @PutMapping(value = "/note/{id}")
    public ResultBean updateById(@PathVariable("id") Integer id, @ModelAttribute Note note) {
        mNoteService.updateNote(id, note);
        return ResultHandler.ok(note);
    }

    @GetMapping(value = "/note")
    public ResultBean findAll() {
        return ResultHandler.ok(mNoteService.findAll());
    }

    @GetMapping(value = "/note/{id}")
    public ResultBean findById(@PathVariable("id") Integer id) {
        return ResultHandler.ok(mNoteService.findById(id));
    }

    @DeleteMapping(value = "/note/{id}")
    public ResultBean deleteById(@PathVariable("id") Integer id) {
        return ResultHandler.ok(mNoteService.deleteById(id));
    }
}

複製代碼

五:優化與補充

1.請求總結

總的來講接口有這些:(域名是http://192.168.43.60,端口是:8089 自行修改)

查詢:GET請求
查詢全部:http://192.168.43.60:8089/api/android/note
查詢id=1: http://192.168.43.60:8089/api/android/note/1
查詢type=C: http://192.168.43.60:8089/api/android/note/type/C
查詢名字有View的:http://192.168.43.60:8089/api/android/note/name/View

插入:POST請求
插入數據:http://192.168.43.60:8089/api/android/note

修改:PUT請求
修改id=1的數據:http://192.168.43.60:8089/api/android/note/1

刪除:DELETE請求
刪除id=1的數據:http://192.168.43.60:8089/api/android/note/1
複製代碼

二、使用內聯查詢和模糊查詢的SQL映射以下:

dao、Service、Controller操做相似,就不貼了

<select id="findALL" resultType="toly1994.com.android_project.bean.Note">
   SELECT a.id,name,t.type,localPath,jianshuUrl,juejinUrl,imgUrl,createTime FROM android AS a
   INNER JOIN type AS t ON a.type = t.type_idx
</select>

<select id="findByType" resultType="toly1994.com.android_project.bean.Note">
   SELECT a.id,name,t.type,localPath,jianshuUrl,juejinUrl,imgUrl,createTime FROM android AS a
   INNER JOIN type AS t ON a.type = t.type_idx
   WHERE a.type=#{type}
</select>

<select id="findById" resultType="toly1994.com.android_project.bean.Note">
   SELECT a.id,name,t.type,localPath,jianshuUrl,juejinUrl,imgUrl,createTime FROM android AS a
   INNER JOIN type AS t ON a.type = t.type_idx
   WHERE a.id=#{id}
</select>

<select id="findByName" resultType="toly1994.com.android_project.bean.Note">
   SELECT a.id,name,t.type,localPath,jianshuUrl,juejinUrl,imgUrl,createTime FROM android AS a
   INNER JOIN type AS t ON a.type = t.type_idx
   where name LIKE concat(concat('%',#{name}),'%')
</select>
複製代碼

查詢.png

3.服務器資源的訪問
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //在F:/SpringBootFiles/Image/下若是有一張 Excalibar.jpg的圖片,那麼:
        //【1】訪問:http://localhost:8080/imgs/Excalibar.jpg 能夠訪問到
        //【2】html 中 <img src="imgs/Excalibar.jpg">
        registry.addResourceHandler("/imgs/**").addResourceLocations("file:F:/SpringBootFiles/imgs/");
        registry.addResourceHandler("/mp3/**").addResourceLocations("file:F:/SpringBootFiles/mp3/");
        registry.addResourceHandler("/file/**").addResourceLocations("file:F:/SpringBootFiles/file/");
    }
}
複製代碼

訪問服務器上的文件.png


4.文件的上傳接口: UploadController.java
表單上傳:http://192.168.43.60:8089/api/android/upload
寫流上傳:http://192.168.43.60:8089/api/android/postfile

//注意,SpringBoot中表單上傳有限定大小2M,修改方式:
spring:
    servlet:
      multipart:
        max-file-size: 10MB
        max-request-size: 100MB
複製代碼

@RestController
@RequestMapping(value = "/api/android")
public class UploadController {
    /**
     * 表單上傳:多文件上傳(包括一個)
     *
     * @param files 上傳的文件
     * @return 上傳反饋信息
     */
    @PostMapping(value = "/upload")
    public @ResponseBody
    ResultBean uploadImg(@RequestParam("file") List<MultipartFile> files) {
        StringBuilder result = new StringBuilder();
        for (MultipartFile file : files) {
            if (file.isEmpty()) {
                return ResultHandler.error("Upload Error");
            }
            String fileName = file.getOriginalFilename();//獲取名字
            String path = "F:/SpringBootFiles/imgs/";
            File dest = new File(path + "/" + fileName);
            if (!dest.getParentFile().exists()) { //判斷文件父目錄是否存在
                dest.getParentFile().mkdir();
            }
            try {
                file.transferTo(dest); //保存文件
                result.append(fileName).append("上傳成功!\n");
            } catch (IllegalStateException | IOException e) {
                e.printStackTrace();
                result.append(fileName).append("上傳失敗!\n");
            }
        }
        return ResultHandler.ok(result.toString());
    }
    /**
     * 經過流寫入服務器
     * @param name
     * @param request
     * @return
     */
    @PostMapping(value = "/postfile")
    public @ResponseBody
    ResultBean postFile(@RequestParam(value = "name") String name, HttpServletRequest request) {
        String result = "";
        ServletInputStream is = null;
        FileOutputStream fos = null;
        try {
            File file = new File("F:/SpringBootFiles/imgs", name);
            fos = new FileOutputStream(file);
            is = request.getInputStream();
            byte[] buf = new byte[1024];
            int len = 0;
            while ((len = is.read(buf)) != -1) {
                fos.write(buf, 0, len);
            }
            result = "SUCCESS";
        } catch (IOException e) {
            e.printStackTrace();
            result = "ERROR";
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return ResultHandler.ok(result);
    }
}
複製代碼

上傳文件.png


4.跨域的處理

跨域問題主要就是請求頭的問題,詳細分析可見:SpringBoot-12-之Ajax跨域訪問全解析

AndroidProjectApplication
@SpringBootApplication
//坑點5:將dao添加掃包範圍
@MapperScan(basePackages = {"toly1994.com.android_project.dao"})
public class AndroidProjectApplication {

    public static void main(String[] args) {
        SpringApplication.run(AndroidProjectApplication.class, args);
    }

    @Bean
    public FilterRegistrationBean registerFilter() {
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.addUrlPatterns("/*");//全部請求都通過這個Filter
        bean.setFilter(new CrosFilter());//設置過濾器
        return bean;
    }
}
複製代碼
toly1994.com.android_project.config.CrosFilter
/**
 * 做者:張風捷特烈
 * 時間:2018/7/22:21:44
 * 郵箱:1981462002@qq.com
 * 說明:解決跨域問題...加頭
 */
public class CrosFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse rep = (HttpServletResponse) servletResponse;

        HttpServletRequest req = (HttpServletRequest) servletRequest;

        String origin = req.getHeader("Origin");
        if (!StringUtils.isEmpty(origin)) {
            rep.addHeader("Access-Control-Allow-Origin", origin);
        }
        //動態添加自定義頭
        String headers = req.getHeader("Access-Control-Request-Headers");
        if (!StringUtils.isEmpty(headers)) {
            System.out.println(headers);
            rep.addHeader("Access-Control-Allow-Headers", headers);
        }

        //容許8081訪問:
//        rep.addHeader("Access-Control-Allow-Origin", "*");
//        rep.addHeader("Access-Control-Allow-Origin", "http://localhost:8081");
        //容許訪問方法GET
        rep.addHeader("Access-Control-Allow-Methods", "GET");
        rep.addHeader("Access-Control-Allow-Methods", "POST");
//        rep.addHeader("Access-Control-Allow-Headers", "Content-Type");
        rep.addHeader("Access-Control-Max-Age", "3600");//一小時內緩存預檢請求
        rep.addHeader("Access-Control-Allow-Credentials", "true");//容許cookie

        filterChain.doFilter(servletRequest, rep);
    }

    @Override
    public void destroy() {

    }
}
複製代碼

4、本地SpringBoot項目部署到服務器上運行(使用騰訊雲)

1.打包:

我將端口改成了8089(由於個人服務器開了8089端口)

mvn -Dmaven.test.skip -U clean install
複製代碼

2.數據庫的備份與恢復

本地備份,服務端恢復

備份:mysqldump -uroot -p mycode >D:\\backupSql\\android.sql
還原:mysql -u root -p mycode< D:\\backupSql\\android.sql
複製代碼

數據庫恢復.png

備份數據庫.png


3.上線

拷貝.png

運行:

F:\>java -jar F:\android_project-0.0.1-SNAPSHOT.jar
複製代碼

4.測試url接口api
1)添加:POST:www.toly1994.com:8089/api/android…

線上插入成功.png

2)查詢:www.toly1994.com:8089/api/android…

查詢成功.png

3)訪問圖片

線上訪問圖片.png

至此後端的數據庫簡單操做及RESTFUl的api接口就已經實現了,雖然比較簡單
後期有須要能夠再增長其餘的url,訪問接口有數據了,後端自此告一段落。


2018-12-12補充:添加分頁查詢:

偏移0,一頁20條數據:http://192.168.43.60:8089/api/android/note/0/20

<select id="findByType" resultType="toly1994.com.android_project.bean.Note">
   SELECT a.id,name,t.type,localPath,jianshuUrl,juejinUrl,imgUrl,info,createTime FROM android AS a
   INNER JOIN type AS t ON a.type = t.type_idx
   WHERE a.type=#{type}
   limit #{offset},#{limit}
</select>
複製代碼

分類查詢分頁:http://192.168.43.60:8089/api/android/note/type/ABCS/0/4

<select id="findByName" resultType="toly1994.com.android_project.bean.Note">
   SELECT a.id,name,t.type,localPath,jianshuUrl,juejinUrl,imgUrl,info,createTime FROM android AS a
   INNER JOIN type AS t ON a.type = t.type_idx
   where name LIKE concat(concat('%',#{name}),'%')
   limit #{offset},#{limit}
</select>
複製代碼

下篇:建站四部曲之Python爬蟲+數據準備篇(selenium)


後記:捷文規範

1.本文成長記錄及勘誤表
項目源碼 日期 備註
V0.1 2018-12-11 建站四部曲以後端接口篇(SpringBoot+上線)
V0.2 2018-12-12 分頁查詢的處理,增長info字段
2.更多關於我
筆名 QQ 微信 愛好
張風捷特烈 1981462002 zdl1994328 語言
個人github 個人簡書 個人掘金 我的網站
3.聲明

1----本文由張風捷特烈原創,轉載請註明
2----歡迎廣大編程愛好者共同交流
3----我的能力有限,若有不正之處歡迎你們批評指證,一定虛心改正
4----看到這裏,我在此感謝你的喜歡與支持


icon_wx_200.png
相關文章
相關標籤/搜索