該系列將記錄一份完整的實戰專案的完成過程,該篇屬於第二天
案例來自B站黑馬程式設計師Java專案實戰《瑞吉外賣》,請結合課程資料閱讀以下內容
該篇我們將完成以下內容:
我們的功能完善一般分為三步
我們在前面的文章中已經實現了login的系統登入
但是我們頁面的存取並沒有設定限制,如果我們直接跳過登陸頁面直接輸入系統內部頁面的url同樣可以進入
所以我們在進入內部頁面時需要先進行檢測使用者是否登入
我們在之前的login功能中如果登陸成功就會給Session加入一個employee的ID值,我們憑藉ID來判斷是否登入
此外,我們需要在進入頁面之前進行判斷,那麼我們就需要構造一個過濾器或者攔截器,下面我們採用過濾器Filter實現
我們建立一個filter資料夾專門存放filter過濾器
下面我們根據邏輯進行程式碼實現過程:
package com.qiuluo.reggie.filter;
import com.alibaba.fastjson.JSON;
import com.qiuluo.reggie.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 檢查使用者是否已經完成登入
*/
// 注意:需要在啟動類上新增@ServletComponentScan註解來幫助識別過濾器
// 過濾器需要新增@WebFilter,設定filterName過濾器名,urlPatterns選擇過濾路徑
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
@Slf4j
// 注意:需要繼承Filter過濾器
public class LoginCheckFilter implements Filter{
//路徑匹配器,支援萬用字元(類似於工具類,帶有方法)
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
// 實現doFilter方法
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// 型別轉換,便於使用對應方法
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//1、獲取本次請求的URI:/backend/index.html
String requestURI = request.getRequestURI();
log.info("攔截到請求:{}",requestURI);
// 中間步驟:定義不需要處理的請求路徑
String[] urls = new String[]{
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**"
};
//2、判斷本次請求是否需要處理
boolean check = check(urls, requestURI);
//3、如果不需要處理,則直接放行
if(check){
log.info("本次請求{}不需要處理",requestURI);
filterChain.doFilter(request,response);
return;
}
//4、判斷登入狀態,如果已登入,則直接放行
if(request.getSession().getAttribute("employee") != null){
log.info("使用者已登入,使用者id為:{}",request.getSession().getAttribute("employee"));
filterChain.doFilter(request,response);
return;
}
log.info("使用者未登入");
//5、如果未登入則返回未登入結果,通過輸出流方式向用戶端頁面響應資料
//(前端程式碼需要我們返回一個"NOTLOGIN"來告訴前端沒有登入)
response.getWriter().write(JSON.toJSONString(Result.error("NOTLOGIN")));
return;
}
/**
* 路徑匹配,檢查本次請求是否需要放行
* @param urls
* @param requestURI
* @return
*/
public boolean check(String[] urls,String requestURI){
for (String url : urls) {
boolean match = PATH_MATCHER.match(url, requestURI);
if(match){
return true;
}
}
return false;
}
}
我們首先需要採用clean,清除之前存有的資料操作
直接在瀏覽器輸入系統內部網路頁的登入URL,如果程式碼正確,我們會閃回到登陸介面進行登入
我們的功能完善一般分為三步
我們在系統內部頁面中點選新增員工,會跳轉到另一個頁面,這屬於前端工作
接下來我們在頁面中填寫資訊,前端會將這些資訊封裝起來,以Employee的形式傳送給後端埠
我們開啟F12,輸入資料點選儲存後檢視資料的請求方式(點選負載,可以檢視到填寫資訊的Employee內容,這裡不再展示):
這個請求方式的路徑就是我們需要完善的程式碼URL的路徑
現在我們來到IDEA中進行簡單的開發:
package com.qiuluo.reggie.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.Employee;
import com.qiuluo.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
/**
* 新增員工
* @param employee
* @return
*/
@PostMapping
public Result<String> save(HttpServletRequest request,@RequestBody Employee employee){
// 紀錄檔輸出
log.info("新增員工");
// 1.根據資料庫的設定,補全相關資訊(密碼,註冊事件,修改時間,註冊人ID,修改人ID)
employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
employee.setCreateTime(LocalDateTime.now());
employee.setUpdateTime(LocalDateTime.now());
Long empId = (Long) request.getSession().getAttribute("employee");
employee.setCreateUser(empId);
employee.setUpdateUser(empId);
// 2.呼叫業務層方法直接新增資料進入資料庫中
employeeService.save(employee);
// 3.返回Result返回體
return Result.success("新增員工成功");
}
}
在主頁面輸入相關資料後,檢視資料庫是否發生改變即可(因為主頁面的分頁操作還未完成,我們無法在前臺看到資訊)
在介紹下一節之前,我們需要注意:
因此,如果我們連續兩次輸入ID相同的員工建立,就會報錯導致程式出現異常
因此我們需要對異常進行處理,例外處理通常分為兩種方法:
第一種方法只能作用在當前情況下,但這種情況並不僅僅在當前情況出現,例如我們修改id如果修改為相同id也會報錯
第二種方法可以作用在全域性狀態下,只要遇見這種問題,我們都會進行處理
因此我們採用第二種方法處理:
package com.qiuluo.reggie.common;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.sql.SQLIntegrityConstraintViolationException;
/**
* 全域性例外處理
* @ControllerAdvice 來書寫需要修改異常的註解類(該類中包含以下註解)
* @ResponseBody 因為返回資料為JSON資料,需要進行格式轉換
*/
@ControllerAdvice(annotations = {RestController.class, Controller.class})
@ResponseBody
@Slf4j
public class GlobalExceptionHandler {
/**
* 處理異常
* @ExceptionHandler 來書寫需要修改的異常
* SQLIntegrityConstraintViolationException.class是我們錯誤時系統彈出的,直接複製即可
* @return
*/
@ExceptionHandler(SQLIntegrityConstraintViolationException.class)
public Result<String> exceptionHandler(SQLIntegrityConstraintViolationException ex){
// 我們可以通過log.error輸出錯誤提醒
// (我們可以得到以下提示資訊:Duplicate entry '123' for key 'employee.idx_username')
log.error(ex.getMessage());
// 我們希望將id:123提取出來做一個簡單的反饋資訊
if (ex.getMessage().contains("Duplicate entry")){
String[] split = ex.getMessage().split(" ");
String msg = split[2] + "已存在";
return Result.error(msg);
}
return Result.error("未知錯誤");
}
}
我們的功能完善一般分為三步
我們要將資料庫資訊通過分頁查詢的方法查詢出來並反饋到頁面中
我們開啟頁面後,直接查詢報錯的部分,檢視其請求資訊以及相關URL:
開啟負載,檢視傳遞的資訊:
還需要注意的是,當我們輸入查詢資訊後,我們會多一個引數name,這個引數也需要進行後臺操作:
我們需要注意的是我們採用的是資料庫的分頁查詢,因此我們需要設定一個分頁外掛來將資料插入
此外我們的程式碼書寫只需要採用page,pageSize查詢資料,將name進行近似匹配並當作查詢條件即可
首先我們先來實現分頁外掛:
package com.qiuluo.reggie.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 設定MP的分頁外掛
* 注意:設定為設定類,使Spring可以搜尋到
*/
@Configuration
public class MyBatisPlusConfig {
// 設定為Bean,受管理許可權
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
// 1.建立一個大型Interceptor
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
// 2.新增PaginationInnerInterceptor進Interceptor裡即可
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
// 3.返回Interceptor
return mybatisPlusInterceptor;
}
}
接下來再來實現主頁面的程式碼:
package com.qiuluo.reggie.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.Employee;
import com.qiuluo.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
/**
* 員工資訊分頁查詢
*/
@GetMapping("/page")
public Result<Page> page(int page, int pageSize, String name){
// 構造分頁構造器
Page pageInfo = new Page(page,pageSize);
// 構造條件構造器
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.like(StringUtils.isNotEmpty(name),Employee::getName,name);
// 新增排序條件
queryWrapper.orderByDesc(Employee::getUpdateTime);
// 執行查詢
employeeService.page(pageInfo,queryWrapper);
return Result.success(pageInfo);
}
}
開啟主頁面,資料出現即為成功
我們的功能完善一般分為三步
當點選我們的員工行列後的啟動/禁止,資料庫的Status進行轉換
我們同樣點選後開啟F12檢視請求URL以及引數:
我們可以看到它將id作為判斷員工的標準,將status的值傳入便於我們修改
其中前端將修改狀態的操作和修改員工資訊的操作列為同一個請求,所以我們直接完成修改員工全部資訊的操作即可
我們直接書寫後端程式碼:
package com.qiuluo.reggie.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.Employee;
import com.qiuluo.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
/**
* 根據id修改員工資訊
* @param employee
* @return
*/
@PutMapping
public Result<String> update(HttpServletRequest request,@RequestBody Employee employee){
// 1.得到當前修改人的id
long empId = (long)request.getSession().getAttribute("employee");
// 2.對被修改員工的修改時間和修改人進行修改
employee.setUpdateTime(LocalDateTime.now());
employee.setUpdateUser(empId);
// 3.直接將資料修改即可(被修改的資料已經被封裝到了employee中,所以我們直接傳遞即可)
employeeService.updateById(employee);
return Result.success("更新成功");
}
}
我們點選啟動或者禁用,資料庫或前端頁面的狀態碼發生變化,即為成功
如果按照上述操作進行,是無法成功修改狀態的,但是程式也不會發生報錯
這是因為我們的資料庫ID中設定長度為19位,但是我們的JS處理器的Long型別只能精確到前16位元
這就會導致我們的ID資料的最後三位在傳遞時變化為000,導致前端傳遞ID與資料庫實際ID無法匹配,無法成功修改
我們採用的處理方法是將伺服器端傳遞的JSON資料進行處理,我們希望將Long型別的資料全部轉變為String型別,這樣就不會省略為0
具體步驟如下:
package com.qiuluo.reggie.common;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;
/**
* 物件對映器:基於jackson將Java物件轉為json,或者將json轉為Java物件
* 將JSON解析為Java物件的過程稱為 [從JSON反序列化Java物件]
* 從Java物件生成JSON的過程稱為 [序列化Java物件到JSON]
*/
public class JacksonObjectMapper extends ObjectMapper {
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
public JacksonObjectMapper() {
super();
//收到未知屬性時不報異常
this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
//反序列化時,屬性不存在的相容處理
this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
SimpleModule simpleModule = new SimpleModule()
.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
.addSerializer(BigInteger.class, ToStringSerializer.instance)
.addSerializer(Long.class, ToStringSerializer.instance)
.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
//註冊功能模組 例如,可以新增自定義序列化器和反序列化器
this.registerModule(simpleModule);
}
}
package com.qiuluo.reggie.config;
import com.qiuluo.reggie.common.JacksonObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import java.util.List;
@Slf4j
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
log.info("開始靜態對映");
registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");
registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/");
}
/**
* 擴充套件mvc框架的訊息轉換器
* @param converters
*/
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
log.info("擴充套件訊息轉換器...");
//建立訊息轉換器物件
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
//設定物件轉換器,底層使用Jackson將Java物件轉為json
messageConverter.setObjectMapper(new JacksonObjectMapper());
//將上面的訊息轉換器物件追加到mvc框架的轉換器集合中
converters.add(0,messageConverter);
}
}
我們的功能完善一般分為三步
當我們點選頁面員工的編輯後,跳轉頁面:
這裡我們需要注意,我們的資料會直接出現在頁面中,這說明我們在點選編輯時,後臺會將我們的資料傳遞給前端,前端才能將資料展現出來
所以我們回到上一步,F12檢視操作:
我們會發現,它呼叫了GET型別的請求,並將我們的id傳入,這說明我們需要建立一個路徑來根據id獲得資料
然後我們點選編輯裡的儲存,檢視F12:
我們會發現,這個路徑和我們上一步實現的啟動禁用賬號的路徑相同,所以當我們點選修改後自動呼叫根據id修改引數的方法
我們只需要實現第一個方法根據ID獲得資料即可:
package com.qiuluo.reggie.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.Employee;
import com.qiuluo.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
/**
* 根據id查詢員工
* @param id
* @return
*/
@GetMapping("/{id}")
public Result<Employee> getById(@PathVariable Long id){
// 根據路徑獲得id,直接呼叫業務層方法獲得employee
Employee emp = employeeService.getById(id);
if (emp != null){
return Result.success(emp);
}else {
return Result.error("未查詢成功");
}
}
}
返回主頁面,點選員工後面的編輯後,跳轉頁面時帶有資料即可
在這裡我們會點出該專案目前容易出錯的位置
Filter也稱之為過濾器,它是Servlet技術中的技術,Web開發人員通過Filter技術,對web伺服器管理的所有web資源
實現步驟主要分為兩步:
package com.qiuluo.reggie.filter;
import com.alibaba.fastjson.JSON;
import com.qiuluo.reggie.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 檢查使用者是否已經完成登入
*/
// @WebFilter註解設定相關資訊
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
public class LoginCheckFilter implements Filter{
}
package com.qiuluo.reggie.filter;
import com.alibaba.fastjson.JSON;
import com.qiuluo.reggie.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 檢查使用者是否已經完成登入
*/
@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")
@Slf4j
public class LoginCheckFilter implements Filter{
//路徑匹配器,支援萬用字元
public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
/*
doFilter用來實現過濾功能
在最開始我們設定了需要過濾的路徑
doFilter裡在來設定在該路徑下哪些路徑可以直接跳過
doFilter裡也可以設定需要經過哪些判斷或哪些處理才能經過
filterChain攜帶req和resp來表示通過過濾器
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//1、獲取本次請求的URI
String requestURI = request.getRequestURI();// /backend/index.html
log.info("攔截到請求:{}",requestURI);
//定義不需要處理的請求路徑
String[] urls = new String[]{
"/employee/login",
"/employee/logout",
"/backend/**",
"/front/**"
};
//2、判斷本次請求是否需要處理
boolean check = check(urls, requestURI);
//3、如果不需要處理,則直接放行
if(check){
log.info("本次請求{}不需要處理",requestURI);
filterChain.doFilter(request,response);
return;
}
//4、判斷登入狀態,如果已登入,則直接放行
if(request.getSession().getAttribute("employee") != null){
log.info("使用者已登入,使用者id為:{}",request.getSession().getAttribute("employee"));
filterChain.doFilter(request,response);
return;
}
log.info("使用者未登入");
//5、如果未登入則返回未登入結果,通過輸出流方式向用戶端頁面響應資料
response.getWriter().write(JSON.toJSONString(Result.error("NOTLOGIN")));
return;
}
/**
* 路徑匹配,檢查本次請求是否需要放行
* @param urls
* @param requestURI
* @return
*/
public boolean check(String[] urls,String requestURI){
for (String url : urls) {
boolean match = PATH_MATCHER.match(url, requestURI);
if(match){
return true;
}
}
return false;
}
}
資料庫的分頁操作需要在資料庫內部的特定位置(limit)處修改值
所以需要設定一個MyBatisPlus攔截器來完成操作,MyBatisPlus已經為我們簡化了步驟,我們只需要將相對應的攔截器新增即可:
package com.qiuluo.reggie.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 設定MP的分頁外掛
*/
@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
}
然後我們就需要注意業務層繼承的實現類中所給的方法的引數即可:
package com.qiuluo.reggie.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qiuluo.reggie.common.Result;
import com.qiuluo.reggie.domain.Employee;
import com.qiuluo.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
/**
* 員工資訊分頁查詢
*/
@GetMapping("/page")
public Result<Page> page(int page, int pageSize, String name){
// 構造分頁構造器
Page pageInfo = new Page(page,pageSize);
// 構造條件構造器
LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
// 這裡是一個like自帶的判斷,如果StringUtils.isNotEmpty(name)為true,才會執行該操作,否則無效
queryWrapper.like(StringUtils.isNotEmpty(name),Employee::getName,name);
// 新增排序條件
queryWrapper.orderByDesc(Employee::getUpdateTime);
// 執行查詢(引數為Page和qw型別,所以我們前面建立相應型別填充資料)
employeeService.page(pageInfo,queryWrapper);
return Result.success(pageInfo);
}
}
首先我們來簡單解釋一下訊息轉換器是什麼:
但預設的訊息轉換器有時不能滿足我們的需求,例如上述例外處理中,我們希望直接將JSON資料轉化為String型別的資料
這時我們就需要手動設定訊息轉換器:
package com.qiuluo.reggie.config;
import com.qiuluo.reggie.common.JacksonObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import java.util.List;
@Slf4j
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
/**
* 擴充套件mvc框架的訊息轉換器
* 其中JacksonObjectMapper是我們自己建立的/下載的訊息轉換器,裡面設定了我們所需要的轉換方式
* 下述操作只是將該轉換器新增到系統的轉換器佇列中,以便於能夠執行該轉換器的操作
* @param converters
*/
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
//建立訊息轉換器物件
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
//設定物件轉換器,底層使用Jackson將Java物件轉為json
messageConverter.setObjectMapper(new JacksonObjectMapper());
//將上面的訊息轉換器物件追加到mvc框架的轉換器集合中
converters.add(0,messageConverter);
}
}
該篇內容到這裡就結束了,希望能為你帶來幫助~
該文章屬於學習內容,具體參考B站黑馬程式設計師的Java專案實戰《瑞吉外賣》
這裡附上視訊連結:業務開發Day2-01-本章內容介紹_嗶哩嗶哩_bilibili