vue實(shí)現(xiàn)教改系統(tǒng)的相關(guān)需求實(shí)現(xiàn)(后端)

注意:本項(xiàng)目前端頁(yè)面基于Vue.js框架編寫(xiě),后端服務(wù)基于Spring Boot框架編寫(xiě)乡洼。
傳送門(mén):vue實(shí)現(xiàn)教改系統(tǒng)的相關(guān)需求實(shí)現(xiàn)(前端)

1.操作數(shù)據(jù)庫(kù)

  • 第一步:在yml文件中配置數(shù)據(jù)庫(kù)信息
spring:
  # 配置數(shù)據(jù)庫(kù)連接信息
  datasource:
    username: education
    password: 123456
    url: jdbc:mysql://ip地址:端口號(hào)/education
    driver-class-name: com.mysql.jdbc.Driver

    # Spring Boot項(xiàng)目啟動(dòng)時(shí)加載數(shù)據(jù)庫(kù)文價(jià)
    schema:
       - classpath:sql/SD_Scholar.sql
    # SD_Scholar.sql 在與 applicaton.yml 同一目錄下的 sql 目錄中僚纷,下面將會(huì)創(chuàng)建 SD_Scholar.sql 

# mybatis 相關(guān)配置
mybatis:
  configuration:
    map-underscore-to-camel-case: true
  • 第二步,創(chuàng)建數(shù)據(jù)庫(kù)文件
-- 這里列出的是一個(gè)非常簡(jiǎn)單的數(shù)據(jù)庫(kù)創(chuàng)建實(shí)例

-- 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;

注意:第一次加載萬(wàn)數(shù)據(jù)庫(kù)之后脾还,即可在 yml 文件中將 - classpath:sql/SD_Scholar.sql 選項(xiàng)注釋掉性锭,以免重復(fù)創(chuàng)建

  • 第三步:創(chuàng)建訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)的 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);
}

現(xiàn)在數(shù)據(jù)庫(kù)操作工作基本已經(jīng)完成,用戶(hù)只需要在對(duì)應(yīng)的 Service 文件中通過(guò) @Autowired 自動(dòng)注入即可進(jìn)行數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)

2.配置啟動(dòng)端口以及 https 配置

# yml文件

# 設(shè)置端口信息以及配置https文件及其信息
server:
  port: 8081
  ssl:
      key-store: classpath:1343113_www.xztywss.top.pfx
      key-store-password: .abCde1fG
      key-store-type: PKCS12
# 上述屬性值需要根據(jù)自己的情況進(jìn)行填寫(xiě)
# 1343113_www.xztywss.top.pfx 文件與 applicaton.yml 文件在同一目錄下

3.文件上傳功能

傳送門(mén)前端頁(yè)面

public ResultObject insertProject(HttpServletRequest request, MultipartFile file) {
        // 設(shè)置 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())) {
                    // 時(shí)間戳
                    String timeStamp = String.valueOf(System.currentTimeMillis());
                    // 自定義的文件名稱(chēng)
                    String trueFileName = number + "_" + timeStamp + "_" + fileName;

                    // 項(xiàng)目在容器中實(shí)際發(fā)布運(yùn)行的根路徑
                    String realPath = request.getSession().getServletContext().getRealPath("/");

                    // 設(shè)置存放文件的路徑
                    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");
    }
  • 同時(shí)要注意招驴,Spring Boot 內(nèi)嵌的 Tomcat 默認(rèn)允許的最大的文件大小為 1MB,單次上傳最大為 10MB枷畏,如要修改别厘,需在 yml 文件中進(jìn)行配置
spring:
  # 設(shè)置文件傳輸限制
  http:
    multipart:
      enabled: true
      max-file-size: 20MB
      max-request-size: 100MB

4.跨域處理

// 加上注解 @CrossOrigin 即可解決跨域請(qǐng)求問(wèn)題
@CrossOrigin
@RestController
public class TestController {

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

5.返回結(jié)果結(jié)構(gòu)化

  • 想要使前后端交互更加高效,就需要設(shè)計(jì)一個(gè)固定格式的返回對(duì)象 ResultObject拥诡,需要傳遞的數(shù)據(jù)可以存儲(chǔ)在對(duì)象里触趴。
public class ResultObject {

    // 后臺(tái)返回碼
    private int code;
    // 后臺(tái)返回消息
    private String msg;
    // 結(jié)果
    private Object result;

    // 構(gòu)造函數(shù)
    public ResultObject() {
        super();
        // TODO Auto-generated constructor stub
    }

    // 構(gòu)造函數(shù)
    public ResultObject(int code, String msg, Object result) {
        super();
        this.code = code;
        this.msg = msg;
        this.result = result;
    }

    // 后臺(tái)處理成功時(shí)使用的構(gòu)造函數(shù)
    public ResultObject(Object result) {
        super();
        this.code = 0;
        this.msg = "success";
        this.result = result;
    }

    // 屬性的setter、getter方法
    // 此處省略...渴肉,請(qǐng)自行補(bǔ)全冗懦。

    @Override
    public String toString() {
        return "ResultObject [code=" + code + ", msg=" + msg + ", result=" + result + "]";
    }
}
  • 在返回結(jié)果時(shí)使用 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進(jìn)行用戶(hù)狀態(tài)檢測(cè)

  • 第一步:首先需要封裝一個(gè)存儲(chǔ) 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);
    }

}
  • 第二步:創(chuàng)建一個(gè) Session 監(jiān)聽(tīng)器
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);
    }
}
  • 第三步:配置監(jiān)聽(tīng)器
import com.lnpu.demo.Listener.SessionListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

// 標(biāo)識(shí)本類(lèi)為配置類(lèi)
@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) {
      // 創(chuàng)建一個(gè)新的 session
      HttpSession session = request.getSession();

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

      // 通過(guò) sessionId 獲取 session
      session = myc.getSession(sessionId);

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

      // 設(shè)置 session 有效時(shí)間: 86400s,即一個(gè)工作日仇祭。
      session.setMaxInactiveInterval(86400);

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

7.Base64 加密解密

// 導(dǎo)入
import java.util.Base64;

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

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

8.跨域攔截器

  • 第一步:實(shí)現(xiàn)攔截器
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 {
        /*
        * 注意:當(dāng)Access-Control-Allow-Credentials設(shè)置為ture時(shí)披蕉,Access-Control-Allow-Origin不能設(shè)置為*
        * */
        //支持跨域請(qǐng)求
        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;

//標(biāo)識(shí)為配置類(lèi)
@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系統(tǒng)查詢(xún)與結(jié)束指定進(jìn)程

// 查詢(xún)進(jìn)程
netstat -lnp|grep 8080

// 結(jié)束進(jìn)程
kill -9 進(jìn)程id

當(dāng)程序在Linux服務(wù)器上部署時(shí),需從防火墻中打開(kāi)指定的端口號(hào)才能訪(fǎng)問(wèn)到(博主是在阿里云的Linux服務(wù)器上部署的乌奇,需要在服務(wù)器上打開(kāi)端口没讲,并在寶塔面板中放行端口)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末礁苗,一起剝皮案震驚了整個(gè)濱河市爬凑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌试伙,老刑警劉巖嘁信,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異迁霎,居然都是意外死亡吱抚,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)考廉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)秘豹,“玉大人,你說(shuō)我怎么就攤上這事昌粤〖热疲” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵涮坐,是天一觀的道長(zhǎng)凄贩。 經(jīng)常有香客問(wèn)我,道長(zhǎng)袱讹,這世上最難降的妖魔是什么疲扎? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任昵时,我火速辦了婚禮,結(jié)果婚禮上椒丧,老公的妹妹穿的比我還像新娘壹甥。我一直安慰自己,他們只是感情好壶熏,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布句柠。 她就那樣靜靜地躺著,像睡著了一般棒假。 火紅的嫁衣襯著肌膚如雪溯职。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,821評(píng)論 1 290
  • 那天帽哑,我揣著相機(jī)與錄音谜酒,去河邊找鬼。 笑死妻枕,一個(gè)胖子當(dāng)著我的面吹牛甚带,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播佳头,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼鹰贵,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了康嘉?” 一聲冷哼從身側(cè)響起碉输,我...
    開(kāi)封第一講書(shū)人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎亭珍,沒(méi)想到半個(gè)月后敷钾,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡肄梨,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年阻荒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片众羡。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡侨赡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出粱侣,到底是詐尸還是另有隱情羊壹,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布齐婴,位于F島的核電站油猫,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏柠偶。R本人自食惡果不足惜情妖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一睬关、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧毡证,春花似錦共螺、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)匀哄。三九已至秦效,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間涎嚼,已是汗流浹背阱州。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留法梯,地道東北人苔货。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像立哑,于是被迫代替她去往敵國(guó)和親夜惭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349