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>
你只有十分努力,才能看上去毫不費力。