vue实现教改系统的相关需求实现(后端)

注意:本项目前端页面基于Vue.js框架编写,后端服务基于Spring Boot框架编写。
传送门:vue实现教改系统的相关需求实现(前端)

1.操作数据库

  • 第一步:在yml文件中配置数据库信息
spring:
  # 配置数据库连接信息
  datasource:
    username: education
    password: 123456
    url: jdbc:mysql://ip地址:端口号/education
    driver-class-name: com.mysql.jdbc.Driver

    # Spring Boot项目启动时加载数据库文价
    schema:
       - classpath:sql/SD_Scholar.sql
    # SD_Scholar.sql 在与 applicaton.yml 同一目录下的 sql 目录中,下面将会创建 SD_Scholar.sql 

# mybatis 相关配置
mybatis:
  configuration:
    map-underscore-to-camel-case: true
  • 第二步,创建数据库文件
-- 这里列出的是一个非常简单的数据库创建实例

-- alter table SD_Scholar AUTO_INCREMENT=1;

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for SD_Scholar
----------------------------
DROP TABLE IF EXISTS `SD_Scholar`;
CREATE TABLE `SD_Scholar` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `number` CHAR (15) DEFAULT NULL,
  `password` VARCHAR (32) NOT NULL,
  `identity` INT DEFAULT NULL, 
  `isDelete` INT(2) DEFAULT "0", 
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

注意:第一次加载万数据库之后,即可在 yml 文件中将 - classpath:sql/SD_Scholar.sql 选项注释掉,以免重复创建

  • 第三步:创建访问数据库的 DAO
import com.lnpu.demo.bean.*;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Component;

import java.util.List;

@Mapper
@Component(value = "userMapper")
public interface UserMapper {

    @Insert("INSERT INTO SD_Scholar(number,password,identity) VALUES(#{number},#{password},#{identity})")
    public void insertUser(User user);

    @Select("SELECT * FROM SD_Scholar WHERE number=#{number}")
    public List<User> findUser(String number);

    @Update("UPDATE SD_Scholar SET password=#{password} WHERE number=#{number}")
    public void update(@Param("number") String number,
                       @Param("password") String password);
}

现在数据库操作工作基本已经完成,用户只需要在对应的 Service 文件中通过 @Autowired 自动注入即可进行数据库访问

2.配置启动端口以及 https 配置

# yml文件

# 设置端口信息以及配置https文件及其信息
server:
  port: 8081
  ssl:
      key-store: classpath:1343113_www.xztywss.top.pfx
      key-store-password: .abCde1fG
      key-store-type: PKCS12
# 上述属性值需要根据自己的情况进行填写
# 1343113_www.xztywss.top.pfx 文件与 applicaton.yml 文件在同一目录下

3.文件上传功能

传送门前端页面

public ResultObject insertProject(HttpServletRequest request, MultipartFile file) {
        // 设置 request 编码格式
        try {
            request.setCharacterEncoding("UTF-8");
        } catch (UnsupportedEncodingException e) {
            return new ResultObject("other");
        }

        String number = request.getParameter("number");

        // 这里只给出文件上传逻辑,不包含其他信息的处理 
        // 先处理上传的文件
        if(!file.isEmpty()) {
            String fileName = file.getOriginalFilename();
            String path = null;
            String type = fileName.indexOf(".") != -1 ? fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()) : null;
            if (type != null) {
                if ("ZIP".equals(type.toUpperCase())||"RAR".equals(type.toUpperCase())) {
                    // 时间戳
                    String timeStamp = String.valueOf(System.currentTimeMillis());
                    // 自定义的文件名称
                    String trueFileName = number + "_" + timeStamp + "_" + fileName;

                    // 项目在容器中实际发布运行的根路径
                    String realPath = request.getSession().getServletContext().getRealPath("/");

                    // 设置存放文件的路径
                    path = "G:/workspace/fileSystem/Project_File/" + trueFileName;
                    File dest = new File(path);
                    //判断文件父目录是否存在
                    if (!dest.getParentFile().exists()) {
                        dest.getParentFile().mkdir();
                    }

                    try {
                        file.transferTo(dest);
                    } catch (IOException e) {
                        return new ResultObject("other");
                    }
                    project.setFileName(trueFileName);
                }else {
                    return new ResultObject("format");
                }
            }else {
                return new ResultObject("format");
            }
        }else {
            return new ResultObject("empty");
        }
  
        return new ResultObject("success");
    }
  • 同时要注意,Spring Boot 内嵌的 Tomcat 默认允许的最大的文件大小为 1MB,单次上传最大为 10MB,如要修改,需在 yml 文件中进行配置
spring:
  # 设置文件传输限制
  http:
    multipart:
      enabled: true
      max-file-size: 20MB
      max-request-size: 100MB

4.跨域处理

// 加上注解 @CrossOrigin 即可解决跨域请求问题
@CrossOrigin
@RestController
public class TestController {

    @RequestMapping("/hello")
    public String hello() {
        return "Hello World!";
    }
}

5.返回结果结构化

  • 想要使前后端交互更加高效,就需要设计一个固定格式的返回对象 ResultObject,需要传递的数据可以存储在对象里。
public class ResultObject {

    // 后台返回码
    private int code;
    // 后台返回消息
    private String msg;
    // 结果
    private Object result;

    // 构造函数
    public ResultObject() {
        super();
        // TODO Auto-generated constructor stub
    }

    // 构造函数
    public ResultObject(int code, String msg, Object result) {
        super();
        this.code = code;
        this.msg = msg;
        this.result = result;
    }

    // 后台处理成功时使用的构造函数
    public ResultObject(Object result) {
        super();
        this.code = 0;
        this.msg = "success";
        this.result = result;
    }

    // 属性的setter、getter方法
    // 此处省略...,请自行补全。

    @Override
    public String toString() {
        return "ResultObject [code=" + code + ", msg=" + msg + ", result=" + result + "]";
    }
}
  • 在返回结果时使用 ResultObject
import com.lnpu.demo.bean.ResultObject;

@RestController
public class UserController {
    @PostMapping("/test")
    public ResultObject test(HttpServletRequest request, HttpServletResponse response) {
        return new ResultObject(404, "false", "null");
    }

}

6.Session进行用户状态检测

  • 第一步:首先需要封装一个存储 Session 的容器
import javax.servlet.http.HttpSession;
import java.util.HashMap;

public class MySessionContext {
    private static MySessionContext instance;
    private HashMap<String, HttpSession> mymap;

    private MySessionContext() {
        mymap = new HashMap<String, HttpSession>();
    }

    public static MySessionContext getInstance() {
        if (instance == null) {
            instance = new MySessionContext();
        }
        return instance;
    }

    public synchronized void AddSession(HttpSession session) {
        if (session != null) {
            mymap.put(session.getId(), session);
        }
    }

    public synchronized void DelSession(HttpSession session) {
        if (session != null) {
            mymap.remove(session.getId());
        }
    }

    public synchronized HttpSession getSession(String session_id) {
        if (session_id == null) return null;
        return (HttpSession) mymap.get(session_id);
    }

    public synchronized boolean containsSession(String session_id) {
        if (session_id == null) return false;
        return mymap.containsKey(session_id);
    }

}
  • 第二步:创建一个 Session 监听器
import com.lnpu.demo.context.MySessionContext;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

@WebListener
public class SessionListener implements HttpSessionListener {

    private MySessionContext myc = MySessionContext.getInstance();

    @Override
    public void sessionCreated(HttpSessionEvent httpSessionEvent) {
        myc.AddSession(httpSessionEvent.getSession());
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
        HttpSession session = httpSessionEvent.getSession();
        myc.DelSession(session);
    }
}
  • 第三步:配置监听器
import com.lnpu.demo.Listener.SessionListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

// 标识本类为配置类
@Configuration
public class ListenerConfig {

    @Bean
    public SessionListener init() {
        return new SessionListener();
    }

}
  • 第四步:操作 Session
// 需要引入的包
import com.lnpu.demo.context.MySessionContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

// 引入 session 容器
MySessionContext myc = MySessionContext.getInstance();

public void login(HttpServletRequest request) {
      // 创建一个新的 session
      HttpSession session = request.getSession();

      // 获取 sessionid
      String sessionId = session.getId();

      // 通过 sessionId 获取 session
      session = myc.getSession(sessionId);

      // 向 session 中添加信息
      session.setAttribute("user", user);

      // 设置 session 有效时间: 86400s,即一个工作日。
      session.setMaxInactiveInterval(86400);

       // 从 session 中获取信息
      User user = (User)session.getAttribute("user");
}

7.Base64 加密解密

// 导入
import java.util.Base64;

// 加密
Base64.Encoder encoder = Base64.getEncoder();
byte[] name= encoder.encode(name.getBytes());

// 解密
Base64.Decoder decoder = Base64.getDecoder();
decoder.decode(name);

8.跨域拦截器

  • 第一步:实现拦截器
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class SessionInterceptor implements HandlerInterceptor{
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        /*
        * 注意:当Access-Control-Allow-Credentials设置为ture时,Access-Control-Allow-Origin不能设置为*
        * */
        //支持跨域请求
        response.setHeader("Access-Control-Allow-Origin",request.getHeader("Origin"));

        response.setHeader("Access-Control-Allow-Methods", "*");

        //是否支持cookie跨域
        response.setHeader("Access-Control-Allow-Credentials", "true");

        response.setHeader("Access-Control-Allow-Headers", "Authorization,Origin, X-Requested-With, Content-Type, Accept,Access-Token");//Origin, X-Requested-With, Content-Type, Accept,Access-Token

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    }
}
  • 第二步:配置拦截器
import com.lnpu.demo.interceptor.SessionInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

//标识为配置类
@Configuration
public class InterpectorConfig extends WebMvcConfigurationSupport {

    @Autowired
    private SessionInterceptor sessionInterceptor;

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(sessionInterceptor).addPathPatterns("/user/*");
        registry.addInterceptor(sessionInterceptor).addPathPatterns("/project/*");
        super.addInterceptors(registry);
    }

}

* Linux系统查询与结束指定进程

// 查询进程
netstat -lnp|grep 8080

// 结束进程
kill -9 进程id

当程序在Linux服务器上部署时,需从防火墙中打开指定的端口号才能访问到(博主是在阿里云的Linux服务器上部署的,需要在服务器上打开端口,并在宝塔面板中放行端口)。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,313评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,369评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,916评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,333评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,425评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,481评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,491评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,268评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,719评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,004评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,179评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,832评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,510评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,153评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,402评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,045评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,071评论 2 352