Java NIO(四)開發基於幀的ping-pong伺服器
專案講解
具體功能如何實現
需要到的技術(純後端開發)
josn+spring boot+mybatis puls+mysql資料庫
什麼是josn:
JSON(JavaScript Object Notation) 是一種輕量級的資料交換格式。易於人閱讀和編寫。同時也易於機器解析和生成。
翻譯人能聽懂的話就是 我從後端傳到前端的資料能顯示出來前端需要的格式
什麼是spring boot:
從最根本上來講,Spring Boot就是一些庫的集合,它能夠被任意專案的構建系統所使用。
翻譯成人能聽懂的話就是spring boot 就是一個框架
特點: 自動裝配,控制反轉
什麼是Mybatis:
MyBatis 是一款優秀的持久層框架,它支援自定義 SQL、儲存過程以及高階對映。
MyBatis 免除了幾乎所有的 JDBC 程式碼以及設定引數和獲取結果集的工作。
MyBatis 可以通過簡單的 XML 或註解來配置和對映原始型別、介面和 Java POJO(Plain Old Java Objects,普通老式 Java 物件)為資料庫中的記錄。
翻譯成人能聽懂的話就是Mybatis就是一個高階的JDBC
在翻譯就是java語言怎麼和資料庫連線
這就是Mybatis!
什麼是mysql資料庫:
不想說...
一個java web專案主要分為一下三層
- contorller
- servise
- dao
流程圖:
controller層
- 最重要的一點就是提供api介面與前端互動
以下是我擷取的片段程式碼(controller層)具體的一個前端互動實現
@Api(tags = "裝置臺賬-裝置列表") @RestController @RequestMapping("/ledger") @Slf4j public class LedgerController { @Autowired private ApparatusInfoService apparatusInfoService; @Autowired private SysDdictionariesService sysDdictionariesService; @Autowired private ApparatusProcessService apparatusProcessService; @Autowired private ApparatusStatsService apparatusStatsService; @SysLog("建立裝置") @ApiOperation("建立") @PostMapping("/apparatus") @RequiresPermissions("ledger:apparatusinfo:save") public R create(@RequestBody ApparatusInfoDTO apparatusInfoDTO) { String categoryName = apparatusInfoDTO.getCategoryName(); if (StringUtils.isEmpty(categoryName) || StringUtils.isEmpty(apparatusInfoDTO.getSn()) || StringUtils.isEmpty(apparatusInfoDTO.getUsestate())) { log.error("faield to ledger create, 必要引數為空"); return R.ok("建立失敗,請填寫完整資訊"); } boolean b = apparatusInfoService.createCheckSn(apparatusInfoDTO.getSn()); if (!b) { log.error("faield to ledger create, 裝置編碼已存在"); return R.error("裝置編碼已存在"); } JSONObject infoTemplate = null; String statsInfo = null; try { statsInfo = JsonUtils.getStrToJson(categoryName, "realtime"); } catch (Exception e) { log.error("faield to ledger create statsInfo", e); return R.error("建立失敗"); } ApparatusStatsEntity status = new ApparatusStatsEntity(); String infoString = apparatusInfoDTO.getInfoString(); if (StringUtils.isEmpty(infoString)) { try { infoTemplate = apparatusInfoService.getInfoTemplate(categoryName, "static"); apparatusInfoDTO.setInfo(infoTemplate); } catch (Exception e) { log.error("faield to ledger create infoTemplate", e); return R.error("建立失敗"); } } else { JSONObject info = JSONObject.parseObject(infoString); apparatusInfoDTO.setInfo(info); } SysUserEntity user = (SysUserEntity) SecurityUtils.getSubject().getPrincipal(); apparatusInfoDTO.setCreatetime(new Date()); JSONObject statusTemplate = (JSONObject) JSONObject.parse(statsInfo); apparatusInfoDTO.setStatusthreshold(statusTemplate); apparatusInfoDTO.setCreateuser(user.getUsername()); ApparatusInfoEntity apparatusInfo = ApparatusInfoDTO.getInfoEntity(apparatusInfoDTO); try { apparatusInfoService.save(apparatusInfo); Long infoid = apparatusInfoService.selectInfoid(apparatusInfoDTO.getSn()); status.setInfoid(infoid); status.setInfo(statsInfo); status.setCreatetime(new Date()); status.setCreateuser(user.getUsername()); apparatusStatsService.createStatus(status); log.info("ledger create, infoEntity:{}, apparatusInfoDTO:{}", apparatusInfo, apparatusInfoDTO); return R.ok("建立成功"); } catch (Exception e) { log.error("faield to ledger create createStatus", e); return R.error("建立失敗"); } } } //Class R 返回狀態碼與資訊 public class R extends HashMap<String, Object> { private static final long serialVersionUID = 1L; public R() { put("code", 0); put("msg", "success"); } public static R error() { return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知異常,請聯絡管理員"); } public static R error(String msg) { return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg); } public static R error(int code, String msg) { R r = new R(); r.put("code", code); r.put("msg", msg); return r; } public static R ok(String msg) { R r = new R(); r.put("msg", msg); return r; } public static R ok(Map<String, Object> map) { R r = new R(); r.putAll(map); return r; } public static R ok() { return new R(); } public R put(String key, Object value) { super.put(key, value); return this; }
}
程式開頭 有這4個註解
註解:spring 4.0特性 幫助開發
分析一下這4個註解
@Api(tags = "裝置臺賬-裝置列表")這是個swagerr註解
表示標識這個類是swagger的資源
@RestController
@RestController註解是@Controller和@ResponseBody的合集,表示這是個控制器bean,並且是將函式的返回值直 接填入HTTP響應體中,是REST風格的控制器。
翻譯一下就是 後臺返回資料用這個
@RequestMapping(/ledger)
@RequestMapping:提供路由資訊,負責URL到Controller中的具體函式的對映。
就是相當於返回對映到這個url下 http://localhost :8080/xxx/ledger
@Slf4j
log的註解 列印日誌到哪裡的註解 (java程式碼規範有寫:log可以設定級別,可以控制輸出到哪裡,容易區分是在程式碼的什麼地方列印的,而System.out.print則不行。而且,System.out.print的速度很慢。所以,除非是有意的,否則,都要用log。至少在提交到svn之前把System.out.print換成log。--來源gittab)
再往下看程式碼
@Autowired
@Autowired 註釋,它可以對類成員變數、方法及建構函式進行標註,完成自動裝配的工作。 通過 @Autowired的使用來消除 set ,get方法
翻譯一下就是 把你的Controller與service連線起來
再看
點進來
就進到了你的Service
extends繼承
IService<> 一個方法
ApparatusStatsEntity 這個是其他類中的class程式碼具體就是把資料庫有的欄位定義出來
Entity中具體程式碼
package cn.galaiot.modules.ledger.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* @author zhangtong
* @date 2020-09-04 14:06:29
*/
@Data //註解 有了這個就不需要get set方法了
@TableName(value = "apparatus_process", autoResultMap = true)
public class ApparatusProcessEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主鍵id
*/
@TableId
private Long id;
/**
* 裝置id
*/
private Long infoid;
/**
* 操作時間
*/
@JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd")
private Date operationtime;
/**
* 管理內容
*/
private String managecontent;
/**
* 實施方式
*/
private String implement;
/**
* 實施方
*/
private String executor;
/**
* 費用
*/
private Double expense;
;
/**
* 完好待用時間
*/
private Long readyforusetime;
/**
* 運轉時間
*/
private Long runningtime;
/**
* 故障時間
*/
private Long faulttime;
/**
*正常保養時間
*/
private Long normalmaintenancetime;
/**
* 維保時間
*/
private String maintenancetime;
/**
* 備註
*/
private String remark;
/**
* 值班人
*/
private String inspector;
/**
* 開始維保時間
*/
@JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd")
private Date starttime;
/**
* 維保結束時間
*/
@JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd")
private Date endtime;
/**
* 責任人
*/
private String responsible;
/**
* 任務描述
*/
private String description;
/**
* 配套裝置
*/
private String equipment;
/**
* 詳細資訊
*/
@TableField(typeHandler = FastjsonTypeHandler.class)
private String info;
/**
* 建立時間
*/
private Date createtime;
/**
* 建立人
*/
private String createuser;
/**
* 修改時間
*/
private Date updatetime;
/**
* 修改人
*/
private String updateuser;
/**
* 裝置狀態, -1表示刪除, 0表示正常
*/
private Integer status;
}
暫且不談Entity包是個什麼東西
繼續上面程式碼
又是4個註解
@SysLog
與上面 @Slf4j對應 寫出log列印到哪裡
@ApiOperation
首先@ApiOperation註解不是Spring自帶的,它是是swagger裡的
註解@ApiOperation是用來構建Api文件的
@ApiOperation(value = “介面說明”, httpMethod = “介面請求方式”, response =
“介面返回引數型別”, notes = “介面釋出說明”;其他引數可參考原始碼;
提到swagger不得不提到RESTful風格
RESTFUL是一種網路應用程式的設計風格和開發方式,基於HTTP,可以使用XML格式定義或JSON格式定義。RESTFUL適用於移動網際網路廠商作為業務使能介面的場景,實現第三方OTT呼叫行動網路資源的功能,動作型別為新增、變更、刪除所呼叫資源。
一個@ApiOperation的通用寫法 下面是舉例
@ApiOperation(value="建立使用者", notes="根據User物件建立使用者")
@ApiImplicitParam(name = "user", value = "使用者詳細實體user", required = true, dataType = "User")
@RequestMapping(value="", method=RequestMethod.POST)
public String postUser(@RequestBody User user) {
users.put(user.getId(), user);
return "success";
}
下一個的@PostMapping註解
- @PostMapping
- @PutMapping
- @DeleteMapping
- @PatchMapping
- @GetMapping
為什麼這麼寫:
@PostMapping("/apparatus")
這裡的和Swagger上顯示的一樣就行
什麼是@PostMapping:
對映一個POST請求 處理post請求
等價於@RequestMapping(value = "/user/login",method = RequestMethod.POST)
Spring官方文件說:
@GetMapping是一個組合註解,是@RequestMapping(method = RequestMethod.GET)的縮寫。該註解將HTTP Get 對映到 特定的處理方法上。
@PostMapping 是一個組合註解,是@RequestMapping(method = RequestMethod.POST)的縮寫。該註解將HTTP Post 對映到 特定的處理方法上。
到public R create(@RequestBody ApparatusInfoDTO apparatusInfoDTO)
@ResponseBody:表示該方法的返回結果直接寫入HTTP response body中,一般在非同步獲取資料時使用,用於構建RESTful的api。在使用@RequestMapping後,返回值通常解析為跳轉路徑,加上@responsebody後返回結果不會被解析為跳轉路徑,而是直接寫入HTTP response body中。
比如非同步獲取json資料,加上@responsebody後,會直接返回json資料。該註解一般會配合@RequestMapping一起使用。
點選ApparatusInfoDTO 跳轉到public class ApparatusInfoDTO extends ApparatusInfoEntity
寫到這裡可以緩一緩了 不要急來到service層
至於為什麼 就因為這個程式裡的第一行程式碼~
HashMap<String, Object> date = apparatusInfoService.getAll(params);
分析程式碼
HashMap<String,Object> date 定義一個hashmap集合 名字為 date
apparatusInfoService.getAll(params)
apparatusInfoService.得到所有 引數
這就是重點了 因為apparatusInfoService在這!
這裡實現了Controller層互動service層。