前言
感谢各位能读到这里,这应该是这个初始版本网站的最后一篇博客了,之后网站功能升级会另外开一个系列来记录。在我们成功搭建数据库框架、创建spring boot项目、连接数据库和编写用户登陆认证系统之后,可以开始写一些端口为用户提供数据库访问的方法了。
对于后端提供的接口,一般由两个部分组成:Control层和Service层
Control层集合了各个接口,根据将接口的数据传输给Service层实现相应的数据库访问。
Service层由一个个功能类组成,每一个类负责一张表,其函数负责实现对该表数据的访问。
一开始写代码的时候,很多人不习惯把接口的功能实现放在两个层次里(包括我),特别是Service层还分两个部分。为了省事,不少人会直接在Control层完成功能实现,这是一种不好的编程习惯(我也要改 捂脸)。因为当项目逐渐增大时,一个路径下所有页面的功能都在一个文件里实现,这是非常危险的,不仅使得代码变得冗余,而且代码管理会非常混乱。因此,我们编写端口的时候最好要去耦。
用户登录端口
先写一个用户登录的请求类,这个类可以直接由前端发来的用户账号密码的json数据流进行初始化,只用作登录信息检验。
LoginRequest
package com.manager.system.controller;
import javax.validation.constraints.NotBlank;
public class LoginRequest {
@NotBlank
private String username;
@NotBlank
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
在Control层里面编写一个登录端口,根据用户的账号密码进行信息有效性检验,同时生成返回信息,以json格式的数据流传回前端。
AuthController
package com.manager.system.controller;
import com.manager.system.config.security.JwtAuthenticationResponse;
import com.manager.system.config.security.JwtTokenProvider;
import com.manager.system.config.security.SecurityUser;
import com.manager.system.config.security.SecurityUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@RestController
@RequestMapping("/auth")
public class AuthController {
private static final Logger logger = LoggerFactory.getLogger(AuthController.class);
@Autowired
AuthenticationManager authenticationManager;
@Autowired
JwtTokenProvider tokenProvider;
@Autowired
SecurityUserService userService;
@PostMapping("/login")
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
try {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
String authority = (String) ((SecurityUser) authentication.getPrincipal()).getAuthorities().toArray()[0]
.toString();
String jwt = tokenProvider.generateToken(authentication);
logger.info("username: {}", loginRequest.getUsername());
//在这里加上生成数量的清零
return ResponseEntity.ok(new JwtAuthenticationResponse(jwt, authority));
} catch (Exception e) {
return ResponseEntity.ok(new JwtAuthenticationResponse(null, e.getMessage()));
}
}
}
一个用户登录系统,当然还要有账号注册与账号注销。作为一个内网管理系统,我们采用管理员限制模式,只允许超级管理员添加和删除用户账号。
UserController
package com.manager.system.controller;
import com.google.gson.JsonObject;
import com.manager.system.dao.ManagerUserMapper;
import com.manager.system.model.ManagerUser;
import com.manager.system.model.ManagerUserExample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
ManagerUserMapper userMapper;
@PostMapping(value = "/addUser")
@ResponseBody
public void addNewUser(@RequestBody Map<String,String> in,
HttpServletResponse response) {
PrintWriter writer = null;
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String password = encoder.encode(in.get("password"));
JsonObject res = new JsonObject();
ManagerUser newuser = new ManagerUser();
newuser.setUsername(in.get("username"));
newuser.setPassword(password);
newuser.setStatus(Integer.parseInt(in.
get("status")));
newuser.setGroupPkid(Integer.parseInt(in.
get("groupId")));
ManagerUserExample temp = new ManagerUserExample();
temp.or().andUsernameEqualTo(in.get("username"));
if(userMapper.countByExample(temp)==0){
userMapper.insert(newuser);
res.addProperty("result", true);
res.addProperty("status",200);
}else{
res.addProperty("result", false);
res.addProperty("status",500);
}
try {
writer = response.getWriter();
}catch (Exception e) {
e.printStackTrace();
}finally{
writer.print(res);
writer.flush();
}
writer.close();
}
@RequestMapping(value = "/deleteUser")
@ResponseBody
public void deleteUser(@RequestBody Map<String, List<Integer>> in,
HttpServletResponse response){
ManagerUserExample temp = new ManagerUserExample();
PrintWriter write = null;
JsonObject out = new JsonObject();
List<Integer> pkids = in.get("pkids");
for (int i = 0; i < pkids.size(); i++){
temp.or().andUserPkidEqualTo(pkids.get(i));
}
int res = userMapper.deleteByExample(temp);
try {
response.setContentType("text/html;charset=UTF-8");
out.addProperty("total", res);
write = response.getWriter();
}catch (Exception e) {
e.printStackTrace();
}finally {
write.print(out);
write.flush();
}
write.close();
}
}
最后是数据库各个表的数据访问功能,在该系统中,我们有三张表。一个是健康资产表,记录着目前还在使用的设备或者资产物品,另一张表是废弃资产表,负责记录曾存在库里,现在已经不再使用的资产物品,还有一张表负责记录整个库所有资产的操作记录,可以根据资产号查询它的历史操作记录。
以下为三张表的数据库设计:
健康资产表
废弃资产表
操作记录表
操作记录表只支持查询访问,每当另外两张表发生数据变更时,系统会自动把变更信息记录在该表中。健康资产表支持资产信息录入,一般物品查询和特定设备查询,健康资产和报废资产查询,资产信息修改(目前开放修改的属性有,责任人,状态和使用人,资产照片, 报废资产),和资产废弃操作。废弃资产表只支持查询访问。
端口的具体设计和实现会在以后逐个讲解,目前就先贴个代码。
AdminController
package com.manager.system.controller;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.manager.system.config.security.JwtTokenProvider;
import com.manager.system.config.security.SecurityUserService;
import com.manager.system.dao.ManagerDeviceMapper;
import com.manager.system.dao.ManagerRetireMapper;
import com.manager.system.dao.ManagerUserMapper;
import com.manager.system.dao.SystemHistoryMapper;
import com.manager.system.model.*;
import com.manager.system.model.ManagerDevice;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import sun.plugin2.applet.SecurityManagerHelper;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/admin")
public class AdminController {
private static final Logger logger = LoggerFactory.getLogger(AuthController.class);
@Autowired
ManagerUserMapper userMapper;
@Autowired
SecurityUserService userService;
@Autowired
ManagerRetireMapper retireMapper;
@Autowired
ManagerDeviceMapper deviceMapper;
@Autowired
SystemHistoryMapper systemHistoryMapper;
@PostMapping(value = "/addDevice")
@ResponseBody
public void addNewDevice(@RequestBody Map<String,String> in,
HttpServletResponse response) {
PrintWriter writer = null;
JsonObject res = new JsonObject();
ManagerDevice newDevice = new ManagerDevice();
SystemHistory systemHistory = new SystemHistory();
String record="";
newDevice.setItemType(in.get("itemType"));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss" );
newDevice.setRecordTime(sdf.format(new Date()));
newDevice.setModifyTime(sdf.format(new Date()));
record += sdf.format(new Date()) + " ";
if (in.get("itemType").equals("device")){
newDevice.setSn(in.get("sn"));
newDevice.setMac(in.get("mac"));
record += "Add Device.";
}
else {record += "Add Item.";}
newDevice.setKeeper(in.get("keeper"));
newDevice.setSupervisor(in.get("supervisor"));
newDevice.setStatus(in.get("status"));
newDevice.setCfrom(in.get("cfrom"));
newDevice.setMessage(in.get("message"));
String itemid = getTodayId();
newDevice.setItemId(itemid);
systemHistory.setItemId(itemid);
systemHistory.setModifyHistory(record);
ManagerDeviceExample temp = new ManagerDeviceExample();
temp.or().andItemIdEqualTo(itemid);
if(deviceMapper.countByExample(temp)==0){
deviceMapper.insertSelective(newDevice);
systemHistoryMapper.insertSelective(systemHistory);
res.addProperty("result", true);
res.addProperty("status",200);
}else{
res.addProperty("result", false);
res.addProperty("status",500);
}
try {
writer = response.getWriter();
}catch (Exception e) {
e.printStackTrace();
}finally{
writer.print(res);
writer.flush();
}
writer.close();
}
@PostMapping(value = "/retire")
@ResponseBody
public void retired(@RequestBody Map<String,String> in,
HttpServletResponse response) {
PrintWriter writer = null;
JsonObject res = new JsonObject();
int pkId = Integer.parseInt(in.get("pkId"),10);
String itemid = in.get("itemId");
SystemHistory systemHistory = new SystemHistory();
String record="";
systemHistory.setItemId(itemid);
ManagerRetire newRetire = new ManagerRetire();
ManagerDeviceKey key = new ManagerDeviceKey(pkId,itemid);
ManagerDevice oldItem = deviceMapper.selectByPrimaryKey(key);
newRetire.setItemId(itemid);
newRetire.setPkid(pkId);
newRetire.setItemType(oldItem.getItemType());
newRetire.setKeeper(oldItem.getKeeper());
newRetire.setSupervisor(oldItem.getSupervisor());
newRetire.setRecorder(in.get("recorder"));
newRetire.setDetail(in.get("detail"));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss" );
newRetire.setRetireTime(sdf.format(new Date()));
newRetire.setRecordTime(oldItem.getRecordTime());
record += sdf.format(new Date()) + " Item retire.";
systemHistory.setModifyHistory(record);
ManagerDeviceExample temp = new ManagerDeviceExample();
ManagerDeviceExample right = new ManagerDeviceExample();
temp.or().andItemIdEqualTo(itemid);
right.or().andPkidEqualTo(pkId);
if(deviceMapper.countByExample(temp)!=0 && deviceMapper.countByExample(right)!=0){
deviceMapper.deleteByPrimaryKey(key);
retireMapper.insertSelective(newRetire);
systemHistoryMapper.insertSelective(systemHistory);
res.addProperty("result", true);
res.addProperty("status",200);
}else{
res.addProperty("result", false);
res.addProperty("status",500);
}
try {
writer = response.getWriter();
}catch (Exception e) {
e.printStackTrace();
}finally{
writer.print(res);
writer.flush();
}
writer.close();
}
@RequestMapping(value = "/editItem")
@ResponseBody
public void editItem(@RequestBody Map<String,String> in,
HttpServletResponse response) {
boolean notnull=false;
PrintWriter writer = null;
JsonObject res = new JsonObject();
ManagerDevice modifyDevice = new ManagerDevice();
SystemHistory systemHistory = new SystemHistory();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss" );
String time = sdf.format(new Date());
String record = time;
int pkId = Integer.parseInt(in.get("pkId"),10);
String itemid = in.get("itemId");
systemHistory.setItemId(itemid);
modifyDevice.setPkid(pkId);
modifyDevice.setItemId(itemid);
if (in.get("status") != null) {
modifyDevice.setStatus(in.get("status"));
record += " Status changes to "+in.get("status")+".";
notnull = true;
}
if (in.get("keeper")!=null){
modifyDevice.setKeeper(in.get("keeper"));
record += " Keeper changes to "+in.get("keeper")+".";
notnull = true;
}
if (in.get("supervisor")!=null){
modifyDevice.setSupervisor(in.get("supervisor"));
record += " Supervisor changes to "+in.get("supervisor")+".";
notnull = true;
}
modifyDevice.setMessage("editItem");
modifyDevice.setModifyTime(time);
systemHistory.setModifyHistory(record);
ManagerDeviceExample temp = new ManagerDeviceExample();
ManagerDeviceExample right = new ManagerDeviceExample();
temp.or().andItemIdEqualTo(itemid);
right.or().andPkidEqualTo(pkId);
if(deviceMapper.countByExample(temp)!=0 && deviceMapper.countByExample(right)!=0 && notnull){
deviceMapper.updateByPrimaryKeySelective(modifyDevice);
systemHistoryMapper.insertSelective(systemHistory);
res.addProperty("result", true);
res.addProperty("status",200);
}else{
res.addProperty("result", false);
res.addProperty("status",500);
}
try {
writer = response.getWriter();
}catch (Exception e) {
e.printStackTrace();
}finally{
writer.print(res);
writer.flush();
}
writer.close();
}
@RequestMapping(value = "/serviceItem")
@ResponseBody
public void getServiceItem(@RequestParam(name = "rowsPerPage") int rowsPerPage, @RequestParam(name = "page",required=false) int page,
HttpServletResponse response){
ManagerDeviceExample temp = new ManagerDeviceExample();
temp.or().andPkidIsNotNull();
PrintWriter write = null;
JsonObject out = new JsonObject();
List<ManagerDevice> deviceList = deviceMapper.selectByExample(temp);
JsonArray jsonArray = new JsonArray();
int head = (page-1) * rowsPerPage;
int tail = Math.min(page * rowsPerPage, deviceList.size());
for (int i = head; i < tail; i++){
JsonObject json = new JsonObject();
json.addProperty("pkId", deviceList.get(i).getPkid());
json.addProperty("item_id", deviceList.get(i).getItemId());
json.addProperty("itemType", deviceList.get(i).getItemType());
json.addProperty("sn", deviceList.get(i).getSn());
json.addProperty("mac", deviceList.get(i).getMac());
json.addProperty("keeper", deviceList.get(i).getKeeper());
json.addProperty("supervisor", deviceList.get(i).getSupervisor());
json.addProperty("status", deviceList.get(i).getStatus());
json.addProperty("cfrom", deviceList.get(i).getCfrom());
json.addProperty("recordTime", deviceList.get(i).getRecordTime());
json.addProperty("modifyTime", deviceList.get(i).getModifyTime());
jsonArray.add(json);
}
try {
response.setContentType("text/html;charset=UTF-8");
out.addProperty("total", deviceList.size());
out.add("list", jsonArray);
write = response.getWriter();
}catch (Exception e) {
e.printStackTrace();
}finally {
write.print(out);
write.flush();
}
write.close();
}
@RequestMapping(value = "/retireItem")
@ResponseBody
public void getRetireItem(@RequestParam(name = "rowsPerPage") int rowsPerPage, @RequestParam(name = "page",required=false) int page,
HttpServletResponse response){
ManagerRetireExample temp = new ManagerRetireExample();
temp.or().andPkidIsNotNull();
PrintWriter write = null;
JsonObject out = new JsonObject();
List<ManagerRetire> deviceList = retireMapper.selectByExample(temp);
JsonArray jsonArray = new JsonArray();
int head = (page-1) * rowsPerPage;
int tail = Math.min(page * rowsPerPage, deviceList.size());
for (int i = head; i < tail; i++){
JsonObject json = new JsonObject();
json.addProperty("pkId", deviceList.get(i).getPkid());
json.addProperty("item_id", deviceList.get(i).getItemId());
json.addProperty("itemType", deviceList.get(i).getItemType());
json.addProperty("keeper", deviceList.get(i).getKeeper());
json.addProperty("supervisor", deviceList.get(i).getSupervisor());
json.addProperty("recordTime", deviceList.get(i).getRecordTime());
json.addProperty("retireTime", deviceList.get(i).getRetireTime());
json.addProperty("detail",deviceList.get(i).getDetail());
jsonArray.add(json);
}
try {
response.setContentType("text/html;charset=UTF-8");
out.addProperty("total", deviceList.size());
out.add("list", jsonArray);
write = response.getWriter();
}catch (Exception e) {
e.printStackTrace();
}finally {
write.print(out);
write.flush();
}
write.close();
}
@RequestMapping(value = "/Item")
@ResponseBody
public void getItem(@RequestParam(name = "rowsPerPage") int rowsPerPage, @RequestParam(name = "page",required=false) int page,
HttpServletResponse response){
ManagerDeviceExample temp = new ManagerDeviceExample();
temp.or().andSnIsNull();
PrintWriter write = null;
JsonObject out = new JsonObject();
List<ManagerDevice> deviceList = deviceMapper.selectByExample(temp);
JsonArray jsonArray = new JsonArray();
int head = (page-1) * rowsPerPage;
int tail = Math.min(page * rowsPerPage, deviceList.size());
for (int i = head; i < tail; i++){
JsonObject json = new JsonObject();
json.addProperty("pkId", deviceList.get(i).getPkid());
json.addProperty("item_id", deviceList.get(i).getItemId());
json.addProperty("itemType", deviceList.get(i).getItemType());
json.addProperty("keeper", deviceList.get(i).getKeeper());
json.addProperty("supervisor", deviceList.get(i).getSupervisor());
json.addProperty("status", deviceList.get(i).getStatus());
json.addProperty("cfrom", deviceList.get(i).getCfrom());
json.addProperty("recordTime", deviceList.get(i).getRecordTime());
json.addProperty("modifyTime", deviceList.get(i).getModifyTime());
jsonArray.add(json);
}
try {
response.setContentType("text/html;charset=UTF-8");
out.addProperty("total", deviceList.size());
out.add("list", jsonArray);
write = response.getWriter();
}catch (Exception e) {
e.printStackTrace();
}finally {
write.print(out);
write.flush();
}
write.close();
}
@RequestMapping(value = "/Device")
@ResponseBody
public void getDevice(@RequestParam(name = "rowsPerPage") int rowsPerPage, @RequestParam(name = "page",required=false) int page,
HttpServletResponse response){
ManagerDeviceExample temp = new ManagerDeviceExample();
temp.or().andSnIsNotNull();
PrintWriter write = null;
JsonObject out = new JsonObject();
List<ManagerDevice> deviceList = deviceMapper.selectByExample(temp);
JsonArray jsonArray = new JsonArray();
int head = (page-1) * rowsPerPage;
int tail = Math.min(page * rowsPerPage, deviceList.size());
for (int i = head; i < tail; i++){
JsonObject json = new JsonObject();
json.addProperty("pkId", deviceList.get(i).getPkid());
json.addProperty("item_id", deviceList.get(i).getItemId());
json.addProperty("itemType", deviceList.get(i).getItemType());
json.addProperty("sn", deviceList.get(i).getSn());
json.addProperty("mac", deviceList.get(i).getMac());
json.addProperty("keeper", deviceList.get(i).getKeeper());
json.addProperty("supervisor", deviceList.get(i).getSupervisor());
json.addProperty("status", deviceList.get(i).getStatus());
json.addProperty("cfrom", deviceList.get(i).getCfrom());
json.addProperty("recordTime", deviceList.get(i).getRecordTime());
json.addProperty("modifyTime", deviceList.get(i).getModifyTime());
jsonArray.add(json);
}
try {
response.setContentType("text/html;charset=UTF-8");
out.addProperty("total", deviceList.size());
out.add("list", jsonArray);
write = response.getWriter();
}catch (Exception e) {
e.printStackTrace();
}finally {
write.print(out);
write.flush();
}
write.close();
}
@RequestMapping(value = "/history")
@ResponseBody
public void gethistory(@RequestParam(name = "rowsPerPage") int rowsPerPage,
@RequestParam(name = "page",required=false) int page,
@RequestParam(name = "itemId") String itemId,
HttpServletResponse response){
PrintWriter write = null;
JsonObject out = new JsonObject();
SystemHistoryExample example = new SystemHistoryExample();
example.or().andItemIdEqualTo(itemId);
List<SystemHistory> historyList = systemHistoryMapper.selectByExampleWithBLOBs(example);
JsonArray jsonArray = new JsonArray();
int head = (page-1) * rowsPerPage;
int tail = Math.min(page * rowsPerPage, historyList.size());
for (int i = head; i < tail; i++){
JsonObject json = new JsonObject();
json.addProperty("item_id", historyList.get(i).getItemId());
json.addProperty("modify_history", historyList.get(i).getModifyHistory());
jsonArray.add(json);
}
try {
response.setContentType("text/html;charset=UTF-8");
out.addProperty("total", historyList.size());
out.add("list", jsonArray);
write = response.getWriter();
}catch (Exception e) {
e.printStackTrace();
}finally {
write.print(out);
write.flush();
}
write.close();
}
@RequestMapping(value = "/lately")
public void gethistory(HttpServletResponse response){
PrintWriter write = null;
JsonObject out = new JsonObject();
SystemHistoryExample example = new SystemHistoryExample();
example.or().andItemIdIsNotNull();
List<SystemHistory> historyList = systemHistoryMapper.selectByExampleWithBLOBs(example);
JsonArray jsonArray = new JsonArray();
int three=0,total=0;
if (historyList.size() > 3)
three = historyList.size()-3;
else
three = 1;
for (int i = three; i < historyList.size(); i++,total++){
JsonObject json = new JsonObject();
json.addProperty("item_id", historyList.get(i).getItemId());
json.addProperty("modify_history", historyList.get(i).getModifyHistory());
jsonArray.add(json);
}
try {
response.setContentType("text/html;charset=UTF-8");
out.addProperty("total", total);
out.add("list", jsonArray);
write = response.getWriter();
}catch (Exception e) {
e.printStackTrace();
}finally {
write.print(out);
write.flush();
}
write.close();
}
private String getTodayId(){
SimpleDateFormat sdf =new SimpleDateFormat("yyyyMMdd" );
String today = sdf.format(new Date());
SystemHistory date = systemHistoryMapper.selectByPrimaryKey(999999999);
String old = date.getModifyHistory();
if (today.equals(old.substring(0,8))){
int i = Integer.parseInt(old.substring(8),10)+1;
today += String.format("%04d", i);
}
else{
today += "0001";
}
date.setModifyHistory(today);
systemHistoryMapper.updateByPrimaryKeySelective(date);
return today;
}
}
结语
经过四篇博客粗略的讲解,基本记录了我这个月以来研究后端开发的历程,中间遇到过很坑,也试过debug到凌晨两三点。初次学习一门新的技术总是艰难的,但当你翻过这座山,成功入门之后,会发现更多的乐趣和挑战。
这四篇博客的代码其实是不完整的,如果想要源码的朋友可以在评论区留言。大部分的功能实现都讲得不是很详细,以后有时间会把每一个函数都分解一遍,希望到时候能有人来看吧。