項目實訓博客 :? 項目后端架構 , 項目的四端交互(前端 ,后端 ,模型端 ,數據庫)的開發和維護 , 項目功能總覽
作為項目的后端和前端交互功能主要開發者,我需要對項目的四端交互進行開發和維護.
總覽:
整體項目結構如圖所示:
?前后端的交互:
前端封裝了request.js :
方便前端向后端發送請求,它可以自請求發送前對請求做一些處理,比如統一加token,對請求參數統一加密,也可以在接受response后自動進行一些處理.
import axios from 'axios'const request = axios.create({baseURL: 'http://localhost:9090', // 這里是全局統一加上了 '/api' 前綴,也就是說所有接口都會加上'/api'前綴在,頁面里面寫接口的時候就不要加 '/api'了,否則會出現2個'/api',類似 '/api/api/user'這樣的報錯,切記!!!timeout: 60000
})// request 攔截器
// 可以自請求發送前對請求做一些處理
// 比如統一加token,對請求參數統一加密
request.interceptors.request.use(config => {//config.headers['Content-Type'] = 'application/json;charset=utf-8';if (!(config.data instanceof FormData)) {config.headers['Content-Type'] = 'application/json;charset=utf-8';}// 設置請求頭let jwtToken = localStorage.getItem('jwtToken');if (jwtToken) {config.headers['jwtToken'] = jwtToken;}return config
}, error => {return Promise.reject(error)
});// response 攔截器
// 可以在接口響應后統一處理結果
request.interceptors.response.use(response => {let res = response.data;// 如果是返回的文件if (response.config.responseType === 'blob') {return res}// 兼容服務端返回的字符串數據if (typeof res === 'string') {res = res ? JSON.parse(res) : res}return res;},error => {console.log('err' + error) // for debugreturn Promise.reject(error)}
)export default request
前端的jwt會被儲存在瀏覽器的內存中登錄不同的用戶會被清除.
后端設置了攔截器:
webconfig:
@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate LoginCheckInterceptor loginCheckInterceptor;@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**") // 允許跨域訪問的路徑.allowedOrigins("http://localhost:8080", "http://127.0.0.1:8080") // 允許跨域訪問的源.allowedMethods("GET", "POST", "PUT", "DELETE","INSERT") // 允許的HTTP方法.allowedHeaders("*") // 允許的請求頭.allowCredentials(true) // 是否允許發送cookie.maxAge(3600); // 預檢請求的緩存時間}@Overridepublic void addInterceptors(InterceptorRegistry registry) {//注冊攔截器 并制定攔截的路徑資源 /**為攔截所有資源 不攔截那些資源registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**").excludePathPatterns("/login","/register");}}
InterceptorRegistry:
@Slf4j
@Component
public class LoginCheckInterceptor implements HandlerInterceptor {//目標方法資源運行之前執行,true為放行,false為不放行@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//System.out.println("preHandle運行了");//獲取請求的urlString url = request.getRequestURI().toString();//判斷url中是否包含login(config文件中已經實現了這一點,其實可以刪掉)if (url.contains("login") || url.contains("register")) {//登錄操作直接放行return true;}//獲取令牌(token)String jwt = request.getHeader("jwtToken");System.out.println("令牌校驗獲取到的jwt:" + jwt);//判斷令牌是否存在,如果不存在,返回錯誤結果(未登錄)if (jwt == null) {//log.info("請求頭token為空,返回未登錄的信息");Result error = Result.error(Constants.CODE_401,"NOT_LOGIN");//手動將對象轉換為jsonString notLogin = JSONObject.toJSONString(error);//返回錯誤信息response.getWriter().write(notLogin);return false;}//如果jwt存在,則校驗jwttry {JwtUtils.parseJWT(jwt);} catch (Exception e) {//jwt令牌解析失敗e.printStackTrace();//log.info("解析令牌失敗返回未登錄的錯誤信息");Result error = Result.error("NOT_LOGIN");//手動將對象轉換為jsonString notLogin = JSONObject.toJSONString(error);//返回錯誤信息response.getWriter().write(notLogin);return false;}//令牌解析成功//放行資源(重要的一部)return true;}
}
兩個組合起來可以攔截除了登錄注冊以外的所有請求,攔截下來會校驗jwt令牌,校驗通過才會直接放行.
后端統一返回結果Result:
package com.example.demo.common;
public class Result {private Integer code;//響應碼,1 代表成功; 0 代表失敗private String msg; //響應信息 描述字符串private Object data; //返回的數據public Result() {}public Result(Integer code, String msg, Object data) {this.code = code;this.msg = msg;this.data = data;}//增刪改 成功響應public static Result success(){return new Result(200,"success",null);}//查詢 成功響應public static Result success(Object data){return new Result(200,"success",data);}public static Result success(String msg){return new Result(200,msg,null);}public static Result success(Integer code,String msg,Object data){return new Result(code,msg,data);}//失敗響應public static Result error(String msg){return new Result(Constants.CODE_500,msg,null);}public static Result error(Integer code,String msg){return new Result(code,msg,null);}public static Result error(Integer code,String msg,Object data){return new Result(code,msg,data);}public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}public String toString() {return "Result{code = " + code + ", msg = " + msg + ", data = " + data + "}";}
}
?后端的所有返回結果都會被封裝進這個類中,方便前端使用.
后端與模型端的交互:
使用了java的HttpClient庫:
以下是其中一個方法的示例:
ObjectMapper mapper = new ObjectMapper();Map<String, Object> data = new HashMap<>();data.put("conversation_id",conversation_id);data.put("instruction", content);data.put("max_turns", "10");String jsonBody = mapper.writeValueAsString(data);HttpRequest request = HttpRequest.newBuilder().uri(URI.create("http://localhost:7860/chat")).header("Content-Type", "application/json").POST(HttpRequest.BodyPublishers.ofString(jsonBody)).build();// 發送請求并處理響應HttpClient client = HttpClient.newHttpClient();HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());System.out.println("Status code: " + response.statusCode());System.out.println("Response body: " + response.body());
?模型端會提供fastAPI生成的文檔,以供后端使用;
后端與數據庫的交互:
在?application.properties
?中配置 MongoDB 連接參數:
spring.data.mongodb.uri=mongodb://localhost:27017/test
通過service層和repository層來進行交互
?
項目整體功能總覽:
登錄注冊功能:
?首頁:
法律文書摘要生成:
?其中星號和下載按鈕是收藏功能和下載pdf功能
?
?法律文書摘要收藏功能:

?
可點開查看詳情和刪除,查看詳情可進一步打印成pdf
?法律預測功能:

?
可打印為pdf
?法律問答功能:
?
支持顯示歷史記錄:
?
同是還可以清空歷史記錄:
?
?
感想:?
通過這次創新實訓,我們學到了很多東西,如mongodb的使用,模型的訓練,模型的微調,fastAPI等等,了解到了大模型在當有著無比深厚的潛力