1. 程式人生 > 其它 >C# HttpClient 請求認證、資料傳輸筆記

C# HttpClient 請求認證、資料傳輸筆記

yaml 語法

# application.yml
people:
  name: _Nice
  age: 10
  happy: true
  birth: 2020/5/6
  maps: {k1: v1,k2: v2}
  lists:
    - code
    - music
    - girl
  dog:
    name: 旺財
    age: 3
// yml檔案屬性值注入
package com.kuang.pojo;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Component
@ConfigurationProperties(prefix = "people")
public class People {

    private String name;
    private Integer age;
    private Boolean happy;
    private Date birth;
    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;
    public People() {
    }

    public People(String name, Integer age, Boolean happy, Date birth, Map<String, Object> maps, List<Object> lists, Dog dog) {
        this.name = name;
        this.age = age;
        this.happy = happy;
        this.birth = birth;
        this.maps = maps;
        this.lists = lists;
        this.dog = dog;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Boolean getHappy() {
        return happy;
    }

    public void setHappy(Boolean happy) {
        this.happy = happy;
    }

    public Date getBirth() {
        return birth;
    }

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    public Map<String, Object> getMaps() {
        return maps;
    }

    public void setMaps(Map<String, Object> maps) {
        this.maps = maps;
    }

    public List<Object> getLists() {
        return lists;
    }

    public void setLists(List<Object> lists) {
        this.lists = lists;
    }

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }
    
}

使用 @ConfigurationProperties 報紅,但實際上可以正常執行。要想解決可以匯入如下依賴(注意要有 @Component):

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-configuration-processor</artifactId>
   <optional>true</optional>
</dependency>

也可以通過外部 properties 檔案和 SPEL 進行屬性注入,但我這種方式注入中文亂碼就很迷惑,如果不使用 SPEL 匯入值就不會亂碼,留坑。但大多數情況都是使用 yml 配置,這個瞭解即可。

name=哈哈哈
age=8
package com.kuang.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Component
@PropertySource("classpath:people.properties")
public class People {

    @Value("${name}")
    // 使用 @Value("哈哈哈") 就不會亂碼
    private String name;
    @Value("${age}")
    private Integer age;
    private Boolean happy;
    private Date birth;
    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;
    
    public People() {
    }

    public People(String name, Integer age, Boolean happy, Date birth, Map<String, Object> maps, List<Object> lists, Dog dog) {
        this.name = name;
        this.age = age;
        this.happy = happy;
        this.birth = birth;
        this.maps = maps;
        this.lists = lists;
        this.dog = dog;
    }

JSR303校驗

處理一段業務邏輯,首先要確保資料輸入的正確性,所以需要先對資料進行檢查,保證資料在語義上的正確性,再根據資料進行下一步的處理。前端可以通過 js 程式校驗資料是否合法,後端同樣也需要進行校驗。

JSR 303 使用 Bean Validation,即在 Bean 上新增相應的註解,去實現資料校驗。這樣在執行業務方法前,都會根據註解對資料進行校驗,從而減少自定義的校驗邏輯,減少程式碼冗餘。下面是其中一部分註解。更高階用法參考其他相關部落格。

@Null                  被指定的註解元素必須為 Null
@NotNull               任意型別,不能為 Null,但可以為空,比如空陣列、空字串。
@NotBlank              針對字串,不能為 Null,且去除前後空格後的字串長度要大於 0。
@NotEmpty              針對字串、集合、陣列,不能為 Null,且長度要大於 0。
@Size                   針對字串、集合、陣列,判斷長度是否在給定範圍內。
@Length                 針對字串,判斷長度是否在給定範圍內。
@AssertTrue             針對布林值,用來判斷布林值是否為 true
@AssertFalse            針對布林值,用來判斷布林值是否為 false
@Max(value)         針對字串、數值,用來判斷是否小於等於某個指定值
@Min(value)         針對字串、數值,用來判斷是否大於等於某個指定值

配置檔案位置

配置檔案可以放在以上四個位置,注意目錄名和檔名是固定的不能改。不同版本的 SpringBoot 對於配置檔案位置的優先順序規定不同,可以自己測一下。

靜態檔案

放在 public/resources/static 目錄下的靜態檔案可以被訪問到,SpringBoot 會去找這三個目錄下的檔案,如果不同目錄下有同名檔案,優先順序自測。如 http://localhost:8080/3.js 就可以訪問到 3.js 的內容

頁面

.html 也可以放在 public/resources/static 目錄下直接訪問。如果將 .html 放在 templates 目錄下,則不能直接訪問,需要通過 controller 層訪問,跟 springMVC 一樣,下面是個例子:

package com.horizon.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class indexController {

    @RequestMapping("/test")
    public String test() {
        return "test";
    }
}

然後訪問 http://localhost:8080/test 即可跳轉到對應的 html 頁面,其中在 thymeleafProperties 類中可以看到 thtmeleaf 的實現,其中就有定義路徑拼接如下:

public static final String DEFAULT_PREFIX = "classpath:/templates/";
public static final String DEFAULT_SUFFIX = ".html";

index.html 除外,可以直接用 localhost:8080 訪問,但不能用 localhost:8080/index.html 直接訪問

攔截器

return true 代表放行,在配置類裡配置攔截哪些請求,見下面擴充套件 SpringMVC。如果登入成功則在登入頁面將登入資訊存在 session 裡,攔截器檢查 session 是否有登入資訊來判斷是否放行

package com.horizon.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginHandlerInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        Object loginUser = request.getSession().getAttribute("loginUser");

        if(loginUser == null) {
            request.setAttribute("msg", "請先登入");
            request.getRequestDispatcher("/index.html").forward(request, response);
            return false;
        }

        return true;
    }

}

擴充套件SpringMVC

新建一個配置類,加上 @Configuration 註解並實現 WebMvcConfigurer 介面,然後重寫裡面方法即可實現擴充套件。注意不能加上 @EnableWebMvc 註解。下面的一個例子是通過 diy 檢視控制來實現直接訪問 localhost:8080/index.html來訪問 templates 目錄下的 index.html 頁面

package com.horizon.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/index.html").setViewName("index");
    }
    
    // 配置攔截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(
            new LoginHandlerInterceptor()).addPathPatterns("/**").excludePathPatterns("/index.html", "/", "/user/login");
    }
}

thymeleaf模板引擎

首先匯入配置

<html lang="en" xmlns:th="http://www.thymeleaf.org">

一些常用方法

<!--表單-->
<form th:action="@{/emp}" th:method="post"></form>

<!--迴圈,th:text為填充文字-->
<select name="department.id">
   <option th:each="dept:${dps}" th:text="${dept.getDepartmentName()}" th:value="${dept.getId()}">		 	</option>
</select>
    
<tr th:each="emp:${emps}">
    <td th:text="${emp.getId()}"></td>
    <td th:text="${emp.getLastName()}"></td>
    <td>
        <a th:href="@{/update(id=${emp.getId()})}">編輯</a>
        <a th:href="@{/delete(id=${emp.getId()})}">刪除</a>
    </td>
</tr>
    
<!--是否選中(預設值)-->
<input th:checked="${emp.getGender()==1}" type="radio" name="gender" value="1"/>
<label>男</label>
<input th:checked="${emp.getGender()==0}" type="radio" name="gender" value="0"/>
<label>女</label>

<select name="department.id">
    <option th:selected="${emp.getDepartment().getId()==dept.getId()}" th:each="dept:${dps}"          		th:text="${dept.getDepartmentName()}" th:value="${dept.getId()}"></option>
</select>

其他用法見官方文件

整合JDBC

在 application.yml 檔案里加入資料庫配置

spring:
  datasource:
    username: root
    password: 123
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
    driver-class-name: com.mysql.cj.jdbc.Driver

然後直接使用 JDBCTemplate 即可,注意要自動裝配

package com.kuang.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

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

@RestController
public class JDBCController {

    @Autowired
    JdbcTemplate jdbcTemplate;

    @GetMapping("/query")
    public List<Map<String, Object>> query() {
        String sql = "select * from user";
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
        return maps;
    }

    @GetMapping("/update/{id}")
    public void update(@PathVariable("id") int id) {
        String sql = "update user set name=?,pwd=? where id=?";
        Object[] objects = new Object[3];
        objects[0] = "哈哈哈";
        objects[1] = "541258";
        objects[2] = id;
        jdbcTemplate.update(sql, objects);
    }
}

整合Mybatis

匯入依賴

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.3</version>
</dependency>

在 application.properties 或 application.yml 中配置資料庫

# application.properties
spring.datasource.username=root
spring.datasource.password=123
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# application.yml
spring:
  datasource:
    username: root
    password: 123
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
    driver-class-name: com.mysql.cj.jdbc.Driver

定義介面,加上 @Mapper 註解

package com.kuang.mapper;

import com.kuang.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

import java.util.List;

@Mapper
@Repository
public interface UserMapper {

    List<User> queryUserList();

}

配置 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">
<mapper namespace="com.kuang.mapper.UserMapper">

    <select id="queryUserList" resultType="user">
        select * from user;
    </select>
</mapper>

使用

package com.kuang.controller;

import com.kuang.mapper.UserMapper;
import com.kuang.pojo.User;
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 UserController {

    @Autowired
    private UserMapper userMapper;

    @GetMapping("/query")
    public List<User> queryUserList() {
        return userMapper.queryUserList();
    }
}

目錄結構

可能的問題

pom.xml 中 maven 外掛爆紅,新增一個版本號重新整理即可,版本號與 parent 版本號一樣

<plugins>
	<plugin>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-maven-plugin</artifactId>
		<version>2.5.3</version>
	</plugin>
</plugins>
你只有十分努力,才能看上去毫不費力。