SpringBoot16 MockMvc的使用、JsonPath的使用、請求參數問題、JsonView、分頁查詢參數、JsonProperty


 

1 MockMvc的使用

  利用MockMvc可以快速實現MVC測試

  坑01:利用MockMvc進行測試時應用上下文路徑是不包含在請求路徑中的

  1.1 創建一個SpringBoot項目

    項目腳手架

  1.2 創建一個用戶實體類

package cn.test.demo.base_demo.entity.po;

import java.util.Date;

/**
 * @author 王楊帥
 * @create 2018-05-05 22:03
 * @desc 用戶實體類
 **/
public class User {
    private Integer userId;
    private String userName;
    private String password;
    private Date birthday;

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}
User.java

  1.3 創建一個用戶控制類

package cn.test.demo.base_demo.controller;

import cn.test.demo.base_demo.entity.po.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 王楊帥
 * @create 2018-05-05 22:02
 * @desc 用戶模塊控制層
 **/
@RestController
@RequestMapping(value = "/user")
public class UserController {

    @GetMapping
    public List<User> queryList() {
        List<User> userList = new ArrayList<>();
        userList.add(new User());
        userList.add(new User());
        userList.add(new User());
        return userList;
    }

}
UserController.java

  1.4 創建一個測試類

    該測試類主要測試用戶控制類中的相關方法

    1.4.1 引入測試類注解以及日志注解

@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j

    1.4.2 依賴注入WebApplicationContext

    @Autowired
    private WebApplicationContext wac;

    1.4.3 實例化MockMvc

    private MockMvc mockMvc;

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
    }

    1.4.4 利用MockMvc對象模擬HTTP請求

    @Test
    public void queryList() throws Exception {
        String result = mockMvc.perform(
                    MockMvcRequestBuilders.get("/user")
                    .contentType(MediaType.APPLICATION_JSON_UTF8)
                )
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn().getResponse().getContentAsString();
        log.info("===/" + className + "/queryList===" + result);
    }

    1.4.5 測試類代碼匯總

package cn.test.demo.base_demo.controller;

import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MockMvcBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import static org.junit.Assert.*;

@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class UserControllerTest {

    private final String className = getClass().getName();

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
    }

    @Test
    public void queryList() throws Exception {
        String result = mockMvc.perform(
                    MockMvcRequestBuilders.get("/user")
                    .contentType(MediaType.APPLICATION_JSON_UTF8)
                )
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn().getResponse().getContentAsString();
        log.info("===/" + className + "/queryList===" + result);
    }

}
View Code

 

2 JsonPath

  JsonPath是GitHub上的一個開源項目,主要用來對Json格式的數據進行一些處理

  技巧:jsonPath是MockMvcResultMatchers中的一個靜態方法

  具體使用:點擊前往

  2.1 簡單實例

    @Test
    public void test01() throws Exception {
        mockMvc.perform(
                        MockMvcRequestBuilders.get("/user")
                            .contentType(MediaType.APPLICATION_JSON_UTF8)
                )
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.jsonPath("$.length()").value(3));
    }

 

3 請求參數

  3.1 PathVarible

    主要獲取請求路徑中的數據

    技巧01:PathVarible獲取到的數據是請求路徑的一部分

    技巧02:@PathVariable注解中的name和value兩個成員的作用是一樣的,是用來解決路徑名和請求處理方法形參名不一致的問題

    技巧03:@PathVariable支持正則表達式,如果路徑參數不滿足正則表達式就會匹配失敗;參考博文

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.web.bind.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PathVariable {
    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";

    boolean required() default true;
}
PathVariable.java

    

    3.1.1 控制類

package cn.test.demo.base_demo.controller;

import cn.test.demo.base_demo.entity.po.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 王楊帥
 * @create 2018-05-05 22:02
 * @desc 用戶模塊控制層
 **/
@RestController
@RequestMapping(value = "/user")
@Slf4j
public class UserController {

    private final String className = getClass().getName();

    @GetMapping
    public List<User> queryList() {
        List<User> userList = new ArrayList<>();
        userList.add(new User());
        userList.add(new User());
        userList.add(new User());
        return userList;
    }

    @GetMapping(value = "/{id}")
    public User queryInfoByUserId(
            @PathVariable(name = "id") String userId
    ) {
        System.out.println("===路徑參數:" + userId);
//        log.info("===/" + className + "/queryInfoByUserId===路徑參數為:{}", userId);
        User user = new User();
        return user;
    }

}
UserController.java

    3.1.2 測試類

package cn.test.demo.base_demo.controller;

        import lombok.extern.slf4j.Slf4j;
        import org.junit.Before;
        import org.junit.Test;
        import org.junit.runner.RunWith;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.boot.test.context.SpringBootTest;
        import org.springframework.http.MediaType;
        import org.springframework.test.context.junit4.SpringRunner;
        import org.springframework.test.web.servlet.MockMvc;
        import org.springframework.test.web.servlet.MockMvcBuilder;
        import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
        import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
        import org.springframework.test.web.servlet.setup.MockMvcBuilders;
        import org.springframework.web.context.WebApplicationContext;

        import static org.junit.Assert.*;

@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class UserControllerTest {

    private final String className = getClass().getName();

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
    }

    @Test
    public void queryList() throws Exception {
        String result = mockMvc.perform(
                MockMvcRequestBuilders.get("/user")
                        .contentType(MediaType.APPLICATION_JSON_UTF8)
        )
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn().getResponse().getContentAsString();
        log.info("===/" + className + "/queryList===" + result);
    }

    /**
     * 測試JosnPath
     * @throws Exception
     */
    @Test
    public void test01() throws Exception {
        mockMvc.perform(
                        MockMvcRequestBuilders.get("/user")
                            .contentType(MediaType.APPLICATION_JSON_UTF8)
                )
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.jsonPath("$.length()").value(3));
    }

    /**
     * 測試:路徑參數
     * @throws Exception
     */
    @Test
    public void test02() throws Exception {
        String result =  mockMvc.perform(
                        MockMvcRequestBuilders.get("/user/123")
                            .contentType(MediaType.APPLICATION_JSON_UTF8)
                )
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn().getResponse().getContentAsString();
        System.out.println("====/" + result );
    }

}
UserControllerTest.java

  3.2 RequestParam

    主要獲取請求路徑后面的 K-V 鍵值對

    技巧01:@RequestParam注解中的name和value屬性的作用都是一樣的,都是為了解決前端變量名和后台請求處理方法形參不一致的問題

    技巧02:@RequestParam 可以指定默認值(即:指定了默認之后,即使前端不傳入參數也不會報400錯誤,而是采用設定的默認值)

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.web.bind.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";

    boolean required() default true;

    String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}
RequestParam.java

    3.2.1 控制類

      

package cn.test.demo.base_demo.controller;

import cn.test.demo.base_demo.entity.po.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 王楊帥
 * @create 2018-05-05 22:02
 * @desc 用戶模塊控制層
 **/
@RestController
@RequestMapping(value = "/user")
@Slf4j
public class UserController {

    private final String className = getClass().getName();

    @GetMapping
    public List<User> queryList() {
        List<User> userList = new ArrayList<>();
        userList.add(new User());
        userList.add(new User());
        userList.add(new User());
        return userList;
    }

    /**
     * 路徑參數
     * @param userId
     * @return
     */
    @GetMapping(value = "/{id}")
    public User queryInfoByUserId(
            @PathVariable(name = "id") String userId
    ) {
        System.out.println("===路徑參數:" + userId);
//        log.info("===/" + className + "/queryInfoByUserId===路徑參數為:{}", userId);
        User user = new User();
        return user;
    }

    @GetMapping(value = "/findByName")
    public void findByName(
            @RequestParam(value = "name") String username
    ) {
        System.out.println("===請求參數為:/" + username);

    }

}
UserController.java

    3.2.2 測試類

      

package cn.test.demo.base_demo.controller;

        import lombok.extern.slf4j.Slf4j;
        import org.junit.Before;
        import org.junit.Test;
        import org.junit.runner.RunWith;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.boot.test.context.SpringBootTest;
        import org.springframework.http.MediaType;
        import org.springframework.test.context.junit4.SpringRunner;
        import org.springframework.test.web.servlet.MockMvc;
        import org.springframework.test.web.servlet.MockMvcBuilder;
        import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
        import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
        import org.springframework.test.web.servlet.setup.MockMvcBuilders;
        import org.springframework.web.context.WebApplicationContext;

        import static org.junit.Assert.*;

@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class UserControllerTest {

    private final String className = getClass().getName();

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
    }

    @Test
    public void queryList() throws Exception {
        String result = mockMvc.perform(
                MockMvcRequestBuilders.get("/user")
                        .contentType(MediaType.APPLICATION_JSON_UTF8)
        )
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn().getResponse().getContentAsString();
        log.info("===/" + className + "/queryList===" + result);
    }

    /**
     * 測試JosnPath
     * @throws Exception
     */
    @Test
    public void test01() throws Exception {
        mockMvc.perform(
                        MockMvcRequestBuilders.get("/user")
                            .contentType(MediaType.APPLICATION_JSON_UTF8)
                )
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.jsonPath("$.length()").value(3));
    }

    /**
     * 測試:路徑參數
     * @throws Exception
     */
    @Test
    public void test02() throws Exception {
        String result =  mockMvc.perform(
                        MockMvcRequestBuilders.get("/user/123")
                            .contentType(MediaType.APPLICATION_JSON_UTF8)
                )
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn().getResponse().getContentAsString();
        System.out.println("====/" + result );
    }

    @Test
    public void test03() throws Exception {
        mockMvc.perform(
                    MockMvcRequestBuilders.get("/user/findByName")
                            .param("username", "王楊帥")
                            .contentType(MediaType.APPLICATION_JSON_UTF8)
                )
                .andExpect(MockMvcResultMatchers.status().isOk());
    }

}
UserControllerTest.java

 

  3.3 RequestBody

    可以將前端參數封裝成一個對象傳到后台

    技巧01:請求體中的數據會自動轉化成字符串進行傳輸

    3.3.1 新建一個數據傳輸類

      該類主要用於整合前端傳過來的數據

package cn.test.demo.base_demo.entity.dto;

public class UserQueryCondition {

    private String username;
    private Integer age;
    private Integer ageTo;
    private String xxx;

    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public Integer getAgeTo() {
        return ageTo;
    }
    public void setAgeTo(Integer ageTo) {
        this.ageTo = ageTo;
    }
    public String getXxx() {
        return xxx;
    }
    public void setXxx(String xxx) {
        this.xxx = xxx;
    }
    
    @Override
    public String toString() {
        return "UserQueryCondition [username=" + username + ", age=" + age + ", ageTo=" + ageTo + ", xxx=" + xxx + "]";
    }
    
}
UserQueryCondition.java

    3.3.2 控制類

      

package cn.test.demo.base_demo.controller;

import cn.test.demo.base_demo.entity.dto.UserQueryCondition;
import cn.test.demo.base_demo.entity.po.User;
import com.fasterxml.jackson.annotation.JsonView;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 王楊帥
 * @create 2018-05-05 22:02
 * @desc 用戶模塊控制層
 **/
@RestController
@RequestMapping(value = "/user")
@Slf4j
public class UserController {

    private final String className = getClass().getName();

    @GetMapping
    @JsonView(value = User.UserSimple.class)
    public List<User> queryList() {
        List<User> userList = new ArrayList<>();
        userList.add(new User());
        userList.add(new User());
        userList.add(new User());
        return userList;
    }

    /**
     * 路徑參數
     * @param userId
     * @return
     */
    @GetMapping(value = "/{id}")
    public User queryInfoByUserId(
            @PathVariable(name = "id") String userId
    ) {
        System.out.println("===路徑參數:" + userId);
//        log.info("===/" + className + "/queryInfoByUserId===路徑參數為:{}", userId);
        User user = new User();
        return user;
    }

    /**
     * 請求參數
     * @param username
     */
    @GetMapping(value = "/findByName")
    public void findByName(
            @RequestParam(value = "name") String username
    ) {
        System.out.println("===請求參數為:/" + username);

    }

    /**
     * 請求體
     * @param userQueryCondition
     */
    @PostMapping()
    public void create(
            @RequestBody UserQueryCondition userQueryCondition
            ) {
        System.out.println("===前端獲取到的數據為:" + userQueryCondition);
    }

}
UserController.java

    3.3.3 測試類

      

package cn.test.demo.base_demo.controller;

        import lombok.extern.slf4j.Slf4j;
        import org.junit.Before;
        import org.junit.Test;
        import org.junit.runner.RunWith;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.boot.test.context.SpringBootTest;
        import org.springframework.http.MediaType;
        import org.springframework.test.context.junit4.SpringRunner;
        import org.springframework.test.web.servlet.MockMvc;
        import org.springframework.test.web.servlet.MockMvcBuilder;
        import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
        import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
        import org.springframework.test.web.servlet.setup.MockMvcBuilders;
        import org.springframework.web.context.WebApplicationContext;

        import static org.junit.Assert.*;

@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class UserControllerTest {

    private final String className = getClass().getName();

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
    }

    @Test
    public void queryList() throws Exception {
        String result = mockMvc.perform(
                MockMvcRequestBuilders.get("/user")
                        .contentType(MediaType.APPLICATION_JSON_UTF8)
        )
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn().getResponse().getContentAsString();
//        log.info("===/" + className + "/queryList===" + result);
        System.out.println("===/結果為:" + result);
    }

    /**
     * 測試JosnPath
     * @throws Exception
     */
    @Test
    public void test01() throws Exception {
        mockMvc.perform(
                        MockMvcRequestBuilders.get("/user")
                            .contentType(MediaType.APPLICATION_JSON_UTF8)
                )
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.jsonPath("$.length()").value(3));
    }

    /**
     * 測試:路徑參數
     * @throws Exception
     */
    @Test
    public void test02() throws Exception {
        String result =  mockMvc.perform(
                        MockMvcRequestBuilders.get("/user/123")
                            .contentType(MediaType.APPLICATION_JSON_UTF8)
                )
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andReturn().getResponse().getContentAsString();
        System.out.println("====/" + result );
    }

    /**
     * 測試:請求參數
     * @throws Exception
     */
    @Test
    public void test03() throws Exception {
        mockMvc.perform(
                    MockMvcRequestBuilders.get("/user/findByName")
                            .param("name", "王楊帥")
                            .contentType(MediaType.APPLICATION_JSON_UTF8)
                )
                .andExpect(MockMvcResultMatchers.status().isOk());
    }

    @Test
    public void test04() throws Exception {

        String content = "{\"username\":\"王楊帥\",\"age\":\"24\"}";
        mockMvc.perform(
                    MockMvcRequestBuilders.post("/user")
                            .content(content)
                            .contentType(MediaType.APPLICATION_JSON_UTF8)
                )
                .andExpect(MockMvcResultMatchers.status().isOk());
    }

}
UserControllerTest.java

    3.3.4 參數驗證

      參考博文:點擊前往

 4 JsonView

  需求:有的請求需要返回一個實體對象的全部字段,而有的請求只需要返回一個實體對象的部分字段;但是兩個請求的數據都來自同一個實體類,怎么樣才可以避免實體類重復定義

  JsonView可以通過一個實體類實現多種視圖顯示

  4.1 聲明多個視圖

    在一個實體類中利用接口實現聲明多個視圖

    技巧01:視圖之間可以繼承,如果視圖A繼承了視圖B,那么在利用視圖A進行顯示時視圖B對應的字段也會被顯示出來

    

  4.2 設置實例屬性

    在實例變量的Get方法上設置視圖

    

package cn.test.demo.base_demo.entity.po;

import com.fasterxml.jackson.annotation.JsonView;

import java.util.Date;

/**
 * @author 王楊帥
 * @create 2018-05-05 22:03
 * @desc 用戶實體類
 **/
public class User {

    public interface UserSimple {};
    public interface UserDetail extends UserSimple {};

    private Integer userId;
    private String userName;
    private String password;
    private Date birthday;

    @JsonView(value = UserSimple.class)
    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    @JsonView(value = UserSimple.class)
    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    @JsonView(value = UserDetail.class)
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @JsonView(value = UserDetail.class)
    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}
User.java

  4.3 設置響應視圖

    在控制類中方法中設置響應視圖

      

package cn.test.demo.base_demo.controller;

import cn.test.demo.base_demo.entity.po.User;
import com.fasterxml.jackson.annotation.JsonView;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 王楊帥
 * @create 2018-05-05 22:02
 * @desc 用戶模塊控制層
 **/
@RestController
@RequestMapping(value = "/user")
@Slf4j
public class UserController {

    private final String className = getClass().getName();

    @GetMapping
    @JsonView(value = User.UserSimple.class)
    public List<User> queryList() {
        List<User> userList = new ArrayList<>();
        userList.add(new User());
        userList.add(new User());
        userList.add(new User());
        return userList;
    }

    /**
     * 路徑參數
     * @param userId
     * @return
     */
    @GetMapping(value = "/{id}")
    public User queryInfoByUserId(
            @PathVariable(name = "id") String userId
    ) {
        System.out.println("===路徑參數:" + userId);
//        log.info("===/" + className + "/queryInfoByUserId===路徑參數為:{}", userId);
        User user = new User();
        return user;
    }

    @GetMapping(value = "/findByName")
    public void findByName(
            @RequestParam(value = "name") String username
    ) {
        System.out.println("===請求參數為:/" + username);

    }

}
UserController.java

 

5 分頁查詢參數

  5.1 控制方法形參類型

    在controller層的控制方法中利用 Pageable 對象去接收前端傳過來的路徑參數

    技巧01:在springBoot項目中需要引入 spring-boot-starter-data-jpa 相關jar包才可以使用 Pageable 去接收分頁查詢參數

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

    技巧02:Pageable 所在的包名為:import org.springframework.data.domain.Pageable;

    技巧03:如果前端沒有傳入先關的參數,Pageable 是有默認值的,即使不用 @PageableDefault 指定默認值也是可以的(如果不指定:默認頁碼為第一頁,默認每頁記錄數為20)

    技巧04:Pagealbe 可以利用 @PageableDefault 設置默認值(即:前端不傳入任何參數,直接使用開發者指定的數值),例如:

@PageableDefault(size = 14, page = 14, sort = "username", direction = Direction.DESC) Pageable pageable

    

  5.2 前端傳參

    在前端直接在請求路徑中利用 k-v 鍵值對傳入即可,形如

    技巧01:分頁查詢的參數變量必須是page、size、sort,分別代表頁碼、每頁記錄數、排序字段及其升降序;前端傳入這三個參數,后台會自動封裝到 Pageable 對象中

http://127.0.0.1:9999/test/page?page=12&size=23&sort=name,asc

     疑惑01:后台明明時利用 Pageable 去接收前端的參數,為什么打印出來的日志信息卻是一個 Page 對象;(理解:SpringMVC框架對Pageable進行了一次封裝)

      

  5.3 SpringJPA 中有直接進行分頁查詢的接口

    參考文檔:點擊前往

 

6  JsonProperty

6.1 需求

  當后台響應實體類的變量名和前台的需要的不一致時該如何解決;前端需要按照前端的變量規則來傳,后端按照后端的變量規則來傳,如何保證前后端的數據對應;例如:

  》前端要求的對象格式

  》后端要求的對象格式

 

6.2 解決辦法

  在定義后端的實體對象時利用 @JsonProperty 指定前端的變量名,例如:

package cn.xiangxu.product.VO;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

import javax.persistence.Column;
import java.util.List;

/**
 * @author 王楊帥
 * @create 2018-07-23 14:22
 * @desc 商品類型視圖
 **/
@Data
public class CategoryVO {

    /**
     * 類目名字
     */
    @JsonProperty(value = "name")
    private String categoryName;
    /**
     * 類目編號
     */
    @JsonProperty(value = "type")
    private Integer categoryType;

    /** 商品視圖列表 */
    @JsonProperty(value = "foods")
    private List<ProductVO> productVOList;

}
View Code

 

  6.3 測試

    6.3.1 准備

      》創建一個SpringBoot項目,並引入lombok、spring-boot-starter-web依賴

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--日志、get\set\toString satrt-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <!--<version>1.18.0</version>-->
            <!--<scope>provided</scope>-->
        </dependency>
        <!--日志、get\set\toString end-->
View Code

      》編寫視圖類和視圖類工具

        》》響應視圖類

          技巧01:@Data注解的目的是自動生成get\set\toString等方法

          坑01:利用IDEA開發時就算引入了lombok依賴,也在相關類中添加了@Data注解,但是啟動應用時會報錯;因為lombok會在應用打包時自動給我們生成相關方法,直接利用IDEA啟動應用時那些方法還沒有生成,所以會報錯;解決辦法是在IDEA中安裝一個lombok插件

package cn.xiangxu.product.VO;

import lombok.Data;

/**
 * @author 王楊帥
 * @create 2018-07-23 13:58
 * @desc 數據封裝視圖
 **/
@Data
public class ResultVO<T> {
    private Integer code;
    private String msg;
    private T data;
}
ResultVO

        》》響應視圖類工具

package cn.xiangxu.product.utils;

import cn.xiangxu.product.VO.ResultVO;

/**
 * @author 王楊帥
 * @create 2018-07-23 14:06
 * @desc 響應視圖工具類
 **/
public class ResultVoUtil {

    public static ResultVO success(Object data) {

        ResultVO resultVO = new ResultVO();
        resultVO.setCode(0);
        resultVO.setMsg("請求成功");
        resultVO.setData(data);

        return resultVO;
    }

}
View Code

        》》數據視圖類

package cn.xiangxu.product.VO;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

import javax.persistence.Column;
import java.util.List;

/**
 * @author 王楊帥
 * @create 2018-07-23 14:22
 * @desc 商品類型視圖
 **/
@Data
public class CategoryVO {

    /**
     * 類目名字
     */
    @JsonProperty(value = "name")
    private String categoryName;
    /**
     * 類目編號
     */
    @JsonProperty(value = "type")
    private Integer categoryType;

    /** 商品視圖列表 */
    @JsonProperty(value = "foods")
    private List<ProductVO> productVOList;

}
View Code

    6.3.2 測試Get請求

    6.3.3 測試POST請求

    6.3.4 代碼匯總

package cn.xiangxu.product.controller;

import cn.xiangxu.product.VO.CategoryVO;
import cn.xiangxu.product.VO.ResultVO;
import cn.xiangxu.product.utils.ResultVoUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

/**
 * @author 王楊帥
 * @create 2018-07-23 15:51
 * @desc 測試控制層
 **/
@RestController
@RequestMapping(value = "/test")
@Slf4j
public class TestController {

    @GetMapping(value = "/connect")
    public ResultVO connect() {
        String result = "前后台連接成功";
        log.info(result);
        return ResultVoUtil.success(result);
    }

    @GetMapping(value = "/test01")
    public ResultVO test01() {

        CategoryVO categoryVO = new CategoryVO();
        categoryVO.setCategoryName("熟食");
        categoryVO.setCategoryType(2);
        categoryVO.setProductVOList(null);

        return ResultVoUtil.success(categoryVO);
    }

    @PostMapping(value = "/test02")
    public ResultVO test02(
            @RequestBody CategoryVO categoryVO
    ) {
        log.info("前端傳過來的參數信息為:" + categoryVO);

        return ResultVoUtil.success(categoryVO);
    }

}
View Code

 

    

 

 

 

 

    

    

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM