基於SpringBoot開發的RESTFul風格的API

上次我們講到前後端開發的時候要以RESTFul風格的API進行開發,這樣減少了前後端交流的口舌,所以我們就來實戰一下,寫一個以RESTFul風格的開發的API

一、前提準備

  1. IEDA
  2. Mysql-8.0.18
  3. Navigator

二、數據庫的建立

​ 首先建立一個叫做RESTFulDemo的數據庫,然後在數據庫裏面建立一個叫做demo_user的表,表的結構如下:

MxQXWQ.png

​ 然後導入我事先準備好的數據,這樣就有了數據了

MxlUmt.png

​ 然後建立一個叫做data的表(這個表的名字沒有什麼邏輯,只是爲了此次寫API所寫的demo),並導入我事前準備的數據

Mx1sUK.png

Mx84tf.png

三、代碼編寫

  1. 首先我們需要連接到數據庫,所以加上相關的pom依賴
<!--jdbcTemplate支持-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.1.RELEASE</version>
</dependency>

<!--mysql驅動-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

<!--添加lombok依賴-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
  1. 然後再application.properties裏添加數據庫配置
# 添加的數據庫連接
spring.datasource.url=jdbc:mysql://localhost:3306/restfuldemo?useUnicode=true&characterEncoding=utf-8serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=XXXXXX
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.type=com.mysql.cj.jdbc.MysqlConnectionPoolDataSource

其中XXXXXX指的是你的密碼

  1. 然後寫相關的實體類,與數據庫表相對應

ChartData.java

package com.example.demo.Model;

import lombok.Data;
import lombok.NoArgsConstructor;

@NoArgsConstructor
@Data
public class ChartData {

    private String name;//電視臺名稱

    private String price;//廣告價格
}

demoUser.java

package com.example.demo.Model;

import lombok.Data;
import lombok.NoArgsConstructor;

@NoArgsConstructor
@Data
public class demoUser {

    private String id;//id號

    private String name;//姓名

    private Integer age;//年齡

    private String qq;//qq

    private String address;//地址

    private String Email;//電子郵件
}
  1. 然後編寫Dao層接口

IDemoUserDao.java

package com.example.demo.Dao;

import com.example.demo.Model.demoUser;

import java.util.*;

/**
 * demoUserDao的接口
 */
public interface IDemoUserDao {

    int add(demoUser user);//增加一個demoUser對象

    int delete(demoUser user);//刪除一個demoUser對象

    int update(demoUser user);//修改

    demoUser findOne(String id);//查找到一個

    List<demoUser> findAll();//找到所有的demoUser對象
}

由於我此時想測試數據庫是不是能夠連接成功,於是在pom依賴裏面添加了Junit測試starter

<!--添加junit測試依賴-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
</dependency>

然後我們實現IDemoUserDao這個接口並實現其中的add功能

DemoUserDao.java

package com.example.demo.Dao.Impl;

import com.example.demo.Dao.IDemoUserDao;
import com.example.demo.Model.demoUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Repository
public class DemoUserDao implements IDemoUserDao {

    @Autowired
    private NamedParameterJdbcTemplate jdbcTemplate;

    @Override
    public int add(demoUser user){
        String sql = "insert into demo_user(id,name,age,qq,address,email) "
                + "values(:id,:name,:age,:qq,:address,:email)";
        Map<String,Object> param = new HashMap<>();
        param.put("id",user.getId());
        param.put("name",user.getName());
        param.put("age",user.getAge());
        param.put("qq",user.getQq());
        param.put("address",user.getAddress());
        param.put("email",user.getEmail());
        return (int) jdbcTemplate.update(sql,param);
    }

    @Override
    public int delete(demoUser user){
        return 0;
    }

    @Override
    public int update(demoUser user){
        return 0;
    }

    @Override
    public demoUser findOne(String id){
        return null;
    }

    @Override
    public List<demoUser> findAll(){
        return null;
    }
}

然後就要生成我們的測試類,至於idea裏如何生成測試類,還請讀者自行百度。在DemoUser.java文件裏面按住ctrl+shift+t彈出創建測試類的窗口,然後勾選你需要測試的方法。

測試類編寫如下:

package com.example.demo.Dao.Impl;

import com.example.demo.DemoApplication;
import com.example.demo.Model.demoUser;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static org.junit.jupiter.api.Assertions.*;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = DemoApplication.class)
class DemoUserDaoTest {

    @Autowired
    private DemoUserDao userDao;

    @Test
    void add() {
        demoUser user = new demoUser();
        user.setId("7988256100");
        user.setName("張三娘");
        user.setAge(18);
        user.setQq("8008208820");
        user.setAddress("北京市朝陽區世紀東方城125棟5單元3103室");
        user.setEmail("[email protected]");

        System.out.println(userDao==null);

        userDao.add(user);
        System.out.println("插入成功,返回");
    }
}

之後運行測試類,發現數據庫有了這條數據,並返回

MzMxTf.png

然後數據庫也有了這條數據

MzQZ7V.png

這說明我們的數據庫連接是正常的,接下來我們就要實現其他的代碼了

4.當我們的DAO層寫好之後我們開始寫我們的Service層

部分代碼如下:

package com.example.demo.Service;

import com.example.demo.Dao.Impl.DemoUserDao;
import com.example.demo.Model.demoUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserService {
    @Autowired
    private DemoUserDao userDao;

    public int add(demoUser user){
        return userDao.add(user);
    }

    public int delete(demoUser user){
        return userDao.delete(user);
    }

    public int update(demoUser user){
        return userDao.update(user);
    }

    public demoUser findOne(String id){
        return userDao.findOne(id);
    }

    public List<demoUser> findAll(){
        return userDao.findAll();
    }
}
  1. 然後我們要開始寫我們的RESTFul接口的,在寫RESTFul接口之前,我們得寫一個AjaxResponse的Model

AjaxResponse.java

package com.example.demo.Model;

import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
public class AjaxResponse {

    private boolean isOk;

    private int code;

    private String message;

    private Object data;

    /**
     * 當調用成功不返回數據
     * @return
     */
    public static AjaxResponse success(){
        AjaxResponse resultBean = new AjaxResponse();
        resultBean.setOk(true);
        resultBean.setCode(200);
        resultBean.setMessage("success");

        return resultBean;
    }

    /**
     * 當調用成功返回數據
     * @param data
     * @return
     */
    public static AjaxResponse success(Object data){
        AjaxResponse resultBean = new AjaxResponse();
        resultBean.setOk(true);
        resultBean.setCode(200);
        resultBean.setMessage("success");
        resultBean.setData(data);
        return resultBean;
    }

    /**
     * 當調用失敗時
     * @return
     */
    public static  AjaxResponse fail(){
        AjaxResponse resultBean = new AjaxResponse();
        resultBean.setOk(false);
        resultBean.setCode(400);
        resultBean.setMessage("failed");
        return resultBean;
    }
}

爲什麼要寫這樣的一個實體呢,其實寫這個實體是爲了前端調用我們的接口的時候,當成功調用和失敗調用能夠以此返回相應的數據

  1. 然後編寫相應的contorller類

UserRestController.java

package com.example.demo.Controller;

import com.example.demo.Model.AjaxResponse;
import com.example.demo.Model.demoUser;
import com.example.demo.Service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

import static org.springframework.web.bind.annotation.RequestMethod.*;

@RestController
@RequestMapping("/api")
public class UserRestController {
    @Autowired
    private UserService userService;

    @RequestMapping(value="/users",method = POST,produces = "application/json")
    public AjaxResponse addUser(@RequestBody demoUser user){
        if(userService.add(user)==1){
            return AjaxResponse.success();
        }else{
            return AjaxResponse.fail();
        }
    }

    @RequestMapping(value="/users/{id}",method = DELETE,produces="application/json")
    public AjaxResponse deleteUser(@PathVariable String id){
        demoUser user = new demoUser();
        user.setId(id);
        if(userService.delete(user)==1){
            return AjaxResponse.success();
        }else{
            return AjaxResponse.fail();
        }
    }

    @RequestMapping(value="/users/{id}/{name}",method = PUT,produces="application/json")
    public AjaxResponse updateUser(@PathVariable String id,@PathVariable String name,@RequestBody demoUser user){
        user.setId(id);
        user.setName(name);
        if(userService.update(user)==1){
            return AjaxResponse.success();
        }else{
            return AjaxResponse.fail();
        }
    }

    @RequestMapping(value="/users/{id}",method = GET,produces="application/json")
    public AjaxResponse getOneUser(@PathVariable String id){
        demoUser user;
        user = userService.findOne(id);
        if(user!=null){
            return AjaxResponse.success(user);
        }else{
            return AjaxResponse.fail();
        }
    }

    @RequestMapping(value="/users",method = GET,produces="application/json")
    public AjaxResponse getAllUser(){
        List<demoUser> userList;
        userList = userService.findAll();
        if(userList!=null){
            return AjaxResponse.success(userList);
        }else{
            return AjaxResponse.fail();
        }
    }
}
  1. 寫完了controller之後,我們啓動項目並用postman這個工具來做接口測試,至於postman工具如何安裝並使用請讀者自行百度。

MzWRm9.png

當我們在postman發送一個GET請求的時候,請求的路徑爲http://localhost:8080/api/users,這個請求的路徑其實就是獲取所有用戶的信息。

當我們將請求的路徑後面加上用戶的id的時候就能夠獲取到id爲這個的用戶的信息了

MzfehV.png

三、使用Swagger2構建API發佈文檔

其實寫到前面那裏,我們的RESTFul風格的接口就已經寫好了。現在我們想一下,我們後端寫的接口是要提供給前端使用的,所以前端需要後端接口的API文檔,衆所周知,程序員討厭寫文檔,所以就出現了Swagger2這樣的一個API文檔自動生成的工具,而且能夠實時更新

  1. 首先添加相關的pom依賴
<!--Swagger2的依賴-->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>2.6.1</version>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>2.6.1</version>
</dependency>
  1. 然後新建一個叫做config的包,在包裏新建swagger2.java文件

Swagger2.java

package com.example.demo.Config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class Swagger2 {
    @Bean
    public Docket createRestApi(){
        return new Docket(DocumentationType.SWAGGER_2)
        .apiInfo(apiInfo()).select()
        .apis(RequestHandlerSelectors.basePackage("com.example.demo"))
        .paths(PathSelectors.regex("/api/.*"))
        .build();
    }

    private ApiInfo apiInfo(){
        return new ApiInfoBuilder()
            .title("SpringBoot利用swagger構建api文檔")
            .description("簡單優雅的RESTFul風格")
            .termsOfServiceUrl("http://www.example.com")
            .version("1.0")
            .build();
        }
}

然後運行項目,訪問http://localhost:8080/swagger-ui.html就會顯示下面的樣子

Mzv3Hx.png

以上就是這次要講的全部內容,源代碼已經上傳至Gitee(碼雲),有需要的小夥伴可以自行下載

源碼地址

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