欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

springboot+vue項目從第一行代碼到上線部署全流程

 更新時間:2024年11月20日 12:15:12   作者:天天扭碼  
本文詳細(xì)介紹了如何從零開始搭建一個基于Spring Boot和Vue.js的前后端分離項目,并涵蓋項目需求分析、技術(shù)選型、項目結(jié)構(gòu)設(shè)計、前后端交互、部署上線等全過程,感興趣的朋友跟隨小編一起看看吧

一、引言

相信很多前端工程師或后端工程師都有一個全棧夢,或者想了解一下自己寫的代碼是如何融入到整個項目的,或者想知道自己的“另一半”為什么會寫出那么臭的代碼……

后端工程師會想:“前端小子怎么回事,我“費盡心思”傳的那么幾十個數(shù)據(jù),他怎么就展示了一兩個?”

于此同時前端工程師看著“費盡心思”的數(shù)據(jù)暗想,“byd,怎么每個接口的數(shù)據(jù)傳輸?shù)母袷蕉疾灰粯?,還有你登錄接口為什么要求用戶輸入自己的ID主鍵?”

于是兩者氣憤的去找了全棧的流程,想找出對方代碼“又臭又長”的原因,機(jī)緣巧合下他們共同點開了這一篇博客……

本文將帶領(lǐng)大家走完一個springboot+vue前后端分離項目的全流程,以盡可能簡短的語言,幫助大家理解項目的前后端交互和上線部署

注:本人為大二在校生,代碼風(fēng)格參考黑馬程序員和尚硅谷,有所不足,敬請斧正

二、項目效果展示

項目連接?:120.27.247.221:80 (電腦打開哈)

部分項目效果展示——

登錄頁面

主頁

個人信息頁面

發(fā)表文章頁面

注:這是一個簡單的小網(wǎng)站,也是用其部分代碼來帶大家走完全流程的上線網(wǎng)站,里面小bug不少(其實是懶得改,不是)

三、項目準(zhǔn)備

注:這里不包括插件和依賴噢,用到的話后面會說明的

后端部分——

IDEA專業(yè)版、jdk17、Mysql-8.0.31、Maven-3.6.1

前端部分——

VSCode、node.js

部署部分——

云服務(wù)器ECS(或者隨便什么服務(wù)器了)

四、部分項目結(jié)構(gòu)的分析 后端部分

1)項目的總體結(jié)構(gòu)

項目分為三個模塊,分別是common、pojo、server三個模塊

三個模塊有各自的作用和存放的項目文件,使項目更加清晰有條理

2)common模塊

common模塊負(fù)責(zé)管理在整個項目都可以使用到的方法等,如utils就可能放置一些jwt工具,oss工具之類的,exception中放置處理異常的方法,json中放置json轉(zhuǎn)換器等

3)pojo模塊

pojo模塊負(fù)責(zé)管理項目中全局可以用到的實體類等,比如Admin、User等實體類

4)server模塊

server模塊負(fù)責(zé)管理一些具體的業(yè)務(wù)邏輯,比如登錄功能,發(fā)表文章功能等,這里需要特殊說明的是“controller、service、dao”三層架構(gòu),是后端項目常用的項目結(jié)構(gòu),controller層負(fù)責(zé)規(guī)定方法請求的url,service層負(fù)責(zé)處理方法的具體邏輯,比如信息校驗之類的,dao層負(fù)責(zé)依據(jù)方法的需求處理數(shù)據(jù)庫,這三層架構(gòu)層層遞進(jìn),是springboot項目的核心

前端部分

注:這個項目的前端結(jié)構(gòu)挺草率,畢竟本人主要從事后端,但是基本的結(jié)構(gòu)還是能分清的,小項目夠用

這個雖然比較亂,但是基本的結(jié)構(gòu)還是可以介紹一下的

1.public

放置的是項目用到的一部分靜態(tài)資源(特別是那種可以復(fù)用的資源,比如其他大佬寫的炫酷頁面)

2.api

放置的是調(diào)用后端接口的方法,比如下面這一坨代碼

import request from '@/utils/request'
import type { userLogin } from '@/types/userLogin'
// 枚舉管理注冊模塊接口地址
enum API {
  // 注冊接口地址
  REGISTER = '/user/register',
  GET_CODE = '/auth',
  VERIFY_CODE = '/auth',
  LOGIN = '/user/login',
  FIND_PASSWORD = '/user/changePasswordByEmail',
}
//注冊函數(shù)
export const goRegister = (user: userLogin) => {
  // 直接傳遞 user 對象
  return request.post(API.REGISTER, user)
}
export const getCode = (email: string) => {
  return request
    .post(`${API.GET_CODE}/send-code?email=${encodeURIComponent(email)}`) // 將 email 作為查詢參數(shù)
    .then((response) => response.data)
    .catch((error) => {
      console.error('獲取驗證碼失敗:', error)
      throw error // 拋出錯誤以便調(diào)用者處理
    })
}
export const verifyCode = (email: string, code: string) => {
  return request
    .post(
      `${API.VERIFY_CODE}/verify-code?email=${encodeURIComponent(email)}&code=${encodeURIComponent(code)}`
    ) // 將 email 作為查詢參數(shù)
    .then((response) => response.data)
    .catch((error) => {
      console.error('校驗驗證碼失敗:', error)
      throw error // 拋出錯誤以便調(diào)用者處理
    })
}

其中比如/user/register都是后端提供的接口的路徑,前端在這里調(diào)用后端的接口,goRegister()便是前端通過封裝后端接口得出的一個方法

3.components

其中一般封裝全局組件,比如你隨便打開一個頁面,你滑動頁面但是一直保持不動的那一部分,或者是你一個需要重復(fù)使用的組件,比如后面要介紹的富文本編輯器

4.pages

其中是一個個的頁面,比如你現(xiàn)在退出了閱讀我這篇文章回到了主頁,主頁和讀我這篇文章的頁面就是兩個不同的“page”

5.router

里面管理的是每個頁面的路由,你現(xiàn)在可以看一下你瀏覽器的導(dǎo)航欄,是不是有類似http://xxx/xxx/xxx這里的/xxx就是一個路由的路徑它會帶你去到某一個“page”

6.style

里面是放置的一些全局可以用到的樣式,比如這個小項目就是在里面放了清楚全局默認(rèn)樣式的樣式

7.types

里面放置一些實體類,用來接收后端傳來的數(shù)據(jù),或者往后端去傳數(shù)據(jù)

8.utils

顧名思義,里面是一些工具,比如封裝一個我們自己的axios,或者一些解析token的工具

累死我了,先寫這么多吧

牛馬是累不死的,繼續(xù)寫

五、前后端的跨域配置

這一部分來解決連后端跨域配置的問題,相信很多小伙伴有一個問題,前端是如何找到后端接口的,為什么前端用的“/user”是自己電腦上的后端項目規(guī)定的“/user”,如果小編電腦上正好也定義了一個“/user”呢,為什么不會調(diào)用小編電腦上的“/user”接口。其實如果在前后端項目上如果不做配置,就是你后端寫了一個“/user”,前端想用也是找不到“/user”的,那么怎么可以讓彼此找到呢?我們只需要做一些小小的配置即可

后端配置

   @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 允許訪問的路徑
                .allowedOrigins("http://localhost:5173") // 允許的源
                .allowedHeaders("*") // 允許的請求頭
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允許的方法
                .allowCredentials(true); // 是否允許發(fā)送憑證
    }

這是有關(guān)跨域的一部分配置,允許了"http://localhost:5173"的連接,而"http://localhost:5173"正是本地前端的運行端口

前端

  //配置代理跨域
  server: {
    proxy: {
      '/api': {
        target: "http://localhost:8080",
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, '')
      }
    }
  }

這里是前端的配置,它規(guī)定了前端去哪里去找后端接口,去"http://localhost:8080"找,這正是后端的端口

簡而言之,后端允許前端去連接,前端也愿意去連接后端,這就成了

六、部分功能的前后端交互

1.登錄功能 

后端部分

jwt工具

package com.qac.utils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Map;
public class JwtUtils {
    private final static String signKey = "Admin";//管理員登錄signKey
    private final static Long expire = 7200000L;//過期時間為12個小時
    /**
     * 生成JWT令牌
     * @param claims JWT第二部分負(fù)載 payload 中存儲的內(nèi)容
     */
    public static String generateJwt(Map<String, Object> claims){
        String jwt = Jwts.builder()
                .addClaims(claims)
                .signWith(SignatureAlgorithm.HS256, signKey)
                .setExpiration(new Date(System.currentTimeMillis() + expire))
                .compact();
        return jwt;
    }
    /**
     * 解析JWT令牌
     * @param jwt JWT令牌
     * @return JWT第二部分負(fù)載 payload 中存儲的內(nèi)容
     */
    public static Claims parseJWT(String jwt){
        Claims claims = Jwts.parser()
                .setSigningKey(signKey)
                .parseClaimsJws(jwt)
                .getBody();
        return claims;
    }
}

這個工具其實沒必要去理解它的每一部分的底層是怎么生成的,大家只需要明白,如果登錄成功它會生成一個令牌,之后我們每次調(diào)用后端的方法都會先驗證是否攜帶的這個令牌,如果沒有就不讓調(diào)用,這個令牌會在瀏覽器本地存儲(前端去做),另外提一點,這個令牌的校驗是通過攔截器完成的,攔截器如下

package com.qac.interceptor;
import com.alibaba.fastjson.JSONObject;
import com.qac.result.Result;
import com.qac.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * jwt令牌校驗的攔截器
 */
@Component
@Slf4j
public class LoginCheckInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) throws Exception {
        //1.獲取請求url
        String url=req.getRequestURL().toString();
        LoginCheckInterceptor.log.info("請求的url--{}",url);
        //獲取請求頭中的token
        String jwt=req.getHeader("token");
        if(!StringUtils.hasLength(jwt)){
            LoginCheckInterceptor.log.info("token為空,未登錄...");
            Result error=Result.error("NOT_LOGIN");
            //這里不是json格式,要轉(zhuǎn)化
            String notLogin= JSONObject.toJSONString(error);
            res.getWriter().write(notLogin);
            return false;
        }
        //解析token,解析失敗就登錄失敗
        try {
            JwtUtils.parseJWT(jwt);
        }catch (Exception e){
            e.printStackTrace();
            LoginCheckInterceptor.log.info("登錄失敗");
            Result error=Result.error("NOT_LOGIN");
            //這里不是json格式,要轉(zhuǎn)化
            String notLogin= JSONObject.toJSONString(error);
            res.getWriter().write(notLogin);
            return false;
        }
        LoginCheckInterceptor.log.info("token合法,放行");
        return true;
    }
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle....");
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterHandle....");
    }
}

還是那句話,不理解底層沒關(guān)系,知道它的作用就可以了

到這里還有一個關(guān)于攔截器的小問題,那就是它會不會把登錄注冊的接口給攔截了,如果沒有做任何配置的話,答案是會的,會出現(xiàn)這種情況“你想登錄的話就得先登錄,不能登錄的話就不能登錄”,我們只需要做一些配置就可以了——

    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginCheckInterceptor)
                .addPathPatterns("/user/**")
                .excludePathPatterns("/user/login")
                .excludePathPatterns("/user/avatar")
                .excludePathPatterns("/user/register")
                .excludePathPatterns("/user/changePasswordByEmail")
                .excludePathPatterns("/auth/**");
    }

這里的意思是.excludePathPatterns("/user/login")這類的接口不會被攔截器攔截,就算你沒有登錄也可以進(jìn)去

controller層

    @ApiOperation("用戶登錄")
    @PostMapping("/login")
    private Result login(@RequestBody UserLogin userLogin){
        log.info("員工登錄:{}",userLogin);
        User user=service.login(userLogin);
        //登錄成功
        if (user!=null){
            HashMap<String, Object> claims = new HashMap<>();
            claims.put("id",user.getId());
            claims.put("email",user.getEmail());
            String jwt= JwtUtils.generateJwt(claims);//jwt中包含了登錄信息
            return Result.success(jwt);
        }
        return Result.error("用戶名或密碼錯誤");
    }

正如前文所訴,這里規(guī)定了用戶登錄接口的url,其中userLogin便是前端傳來的數(shù)據(jù),里面封裝了前端傳來的郵箱和密碼,后端封裝的userLogin類如下

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserLogin implements Serializable {
    public String email;
    public String password;
}

service層

    @Override
    public User login(UserLogin userLogin) {
        return dao.getByUserEmailAndPassword(userLogin);
    }

這里也是直接選擇調(diào)用了dao層的方法去數(shù)據(jù)庫查詢數(shù)據(jù)了

dao層

    <select id="getByUserEmailAndPassword" resultType="com.qac.entity.User">
        select *from user where email =#{email} AND password = #{password};
    </select>

查一下數(shù)據(jù)庫中有沒有這個用戶

在以上的后端處理完之后,我們來梳理一下傳給前端的是什么數(shù)據(jù),我們會發(fā)現(xiàn),后端最終傳給前端的都是類似于Result.success(jwt)的數(shù)據(jù),這里解釋一下Result是封裝的一個類,其中的.success()也是其中的一個靜態(tài)方法,如下

package com.qac.result;
import lombok.Data;
import java.io.Serializable;
/**
 * 后端統(tǒng)一返回結(jié)果
 * @param <T>
 */
@Data
public class Result<T> implements Serializable {
    private Integer code; //編碼:1成功,0和其它數(shù)字為失敗
    private String msg; //錯誤信息
    private T data; //數(shù)據(jù)
    public static <T> Result<T> success() {
        Result<T> result = new Result<T>();
        result.code = 1;
        return result;
    }
    public static <T> Result<T> success(T object) {
        Result<T> result = new Result<T>();
        result.data = object;
        result.code = 1;
        return result;
    }
    public static <T> Result<T> error(String msg) {
        Result result = new Result();
        result.msg = msg;
        result.code = 0;
        return result;
    }
}

有了這個類以后后端傳給前端的數(shù)據(jù)就是“規(guī)規(guī)矩矩”的了,就不會出現(xiàn)本文引言中前端工程師的抱怨了,OK,前端工程師看到這里就可以撤了(開玩笑的,千萬別撤)。

當(dāng)前端調(diào)用了后端的這個接口之后,它會得到什么具體的數(shù)據(jù)呢?可以在controller層看到,傳的有效數(shù)據(jù)就是那個生成的jwt,其中包涵了用戶的email,id等內(nèi)容,還有就是告訴前端是登錄成功了還是失敗了,OK,后端傳來了這么完美的數(shù)據(jù),讓我們看看前端工程師如何處理吧

前端部分

這次的前端工程師倒是很開心,因為后端不需要用戶給他傳用戶的主鍵ID了

嗯......不開玩笑,前端寫一個登錄頁面就寫了五百多行代碼,這里就只挑重要的代碼展示了

1.后端登錄接口的封裝

import request from '@/utils/request'
import type { userLogin } from '@/types/userLogin'
// 枚舉管理注冊模塊接口地址
enum API {
  LOGIN = '/user/login',
}
export const goLogin = (email: string, password: string) => {
  return request.post(API.LOGIN, { email, password })
}

這里有人可能會問,request是個啥,其實它是封裝過的一個axios對象,這個一兩句說不清楚,自己先看一下代碼——

import router from '@/router'
import axios from 'axios'
import {globals} from "@/main"
const serverUrl=globals.$config?.serverUrl || 'http://120.27.247.221:8090'
const request = axios.create({
  baseURL: serverUrl,
  timeout: 200000
})
//請求攔截器
request.interceptors.request.use((config: any) => {
 // 可以通過請求頭攜帶公共參數(shù)
  config.headers['content-type'] = 'application/json'
  const token = JSON.parse(localStorage.getItem('user') || '{}')
  config.headers['token'] = token
  return config
})
//相應(yīng)攔截器
request.interceptors.response.use(
  (response: any) => {
    if (response.data.msg === 'NOT_LOGIN') {
      router.push('/home')
    }
    return response.data
  },
  (error: { message: string | undefined }) => {
    //處理http網(wǎng)絡(luò)錯誤
    return Promise.reject(new Error(error.message))
  }
)
//對外暴露axios
export default request

這一部分的信息量也不小,我原理不說,給大家說一下這一段代碼是什么作用

const serverUrl=globals.$config?.serverUrl || 'http://120.27.247.221:8090'

這個是獲取后端接口的地址,現(xiàn)在說太早,等項目部署部分再說哈

const request = axios.create({
  baseURL: serverUrl,
  timeout: 200000
})

后端的同學(xué)可以認(rèn)為這是創(chuàng)建了一個axios類的對象,然后又給他重寫了一下方法,之后我們用request就是用axios,而且是我們自己的axios

//請求攔截器
request.interceptors.request.use((config: any) => {
 // 可以通過請求頭攜帶公共參數(shù)
  config.headers['content-type'] = 'application/json'
  const token = JSON.parse(localStorage.getItem('user') || '{}')
  config.headers['token'] = token
  return config
})
  • 這一段給你們看看詳細(xì)的解釋,我也不知道怎么組織語言了
  • 這行代碼從瀏覽器的 localStorage 中獲取名為 user 的數(shù)據(jù),并嘗試將其解析為 JavaScript 對象。如果 localStorage 中沒有 user,則使用空對象作為默認(rèn)值。
  • 這里假設(shè) user 對象中可能包含一個 token 屬性,通常用于身份驗證。
//相應(yīng)攔截器
request.interceptors.response.use(
  (response: any) => {
    if (response.data.msg === 'NOT_LOGIN') {
      router.push('/home')
    }
    return response.data
  },
  (error: { message: string | undefined }) => {
    //處理http網(wǎng)絡(luò)錯誤
    return Promise.reject(new Error(error.message))
  }
)

這里可以再調(diào)用方法時判斷瀏覽器本地有沒有有效的token,如果沒有就router.push('/home'),就是讓他返回登錄頁面

2.登錄功能的部分html代碼和方法的調(diào)用

 <form class="form1" @submit.prevent="handleLogin" v-show="login&&!register">
              <p class="heading">登錄</p>
              <el-input
                v-model="user.email"
                style="width: 250px; height: 45px"
                placeholder="郵箱"
              />
              <div v-show="!validateEmail(user.email)" class="warning">請輸入有效的郵箱格式!</div>
              <el-input
                v-model="user.password"
                style="width: 250px; height: 45px"
                type="password"
                placeholder="密碼"
                show-password
              />
              <div v-show="!validatePassword(user.password)" class="warning">
                密碼至少8個字符,包含數(shù)字和特殊字符!
              </div>
              <div class="align">
                <span class="function" @click="toFind">找回密碼</span>
                <span class="function" @click="toRegister">注冊賬號</span>
              </div>
              <button class="btn" type="submit" >登錄</button>
        </form>

這里重點看一下登錄的按鈕(最后一行代碼哈),這意味著點擊之后會執(zhí)行提交表單的方法,也就是方法handleLogin()(第一行代碼哈)

下面是handleLogin()方法

const handleLogin = async () => {
  if (validateEmail(user.email) && validatePassword(user.password)) {
    try {
      const response = await goLogin(user.email, user.password)
      console.log('Login successful:', response)
      if (response.data == null) {
        alert('郵箱或密碼錯誤')
      } else {
        localStorage.setItem('user', JSON.stringify(response.data))
        alert('登錄成功')
        router.push('mainArticle')
      }
    } catch (error) {
      console.error('Login failed:', error)
    }
  } else {
    alert('郵箱或密碼格式錯誤')
  }
}

可以看到,調(diào)用的封裝后端登錄接口的方法----goLogin,并且將用戶輸入的email、password傳到了后端,此外,把response.data保存到了本地,也就是把后端傳來的jwt保存到了本地,登錄成功之后就router.push('mainArticle'),即跳轉(zhuǎn)到主頁

至此前后端在登錄功能上的本地聯(lián)調(diào)就此結(jié)束

現(xiàn)在只是寫了登錄接口前后端邏輯,以后可能會把,個人信息管理或者是富文本編輯器的功能再寫出來,也可能不會寫,或許永遠(yuǎn)不會寫,或許明天就寫

七、上線部署

上線部署應(yīng)該是最簡單的一部分,但同時也是最神秘的一部分或者說是最難找資料的一部分,這里我把完整的流程給大家

準(zhǔn)備工作

1.準(zhǔn)備一個云服務(wù)器,我選擇的是阿里云ECS云服務(wù)器

這里給大家留一個小門檻,去搞一臺ECS云服務(wù)器(實際上是本人不想寫這個了)

2.先進(jìn)入你的這個頁面哈,點擊“安全組”

3.然后點擊管理規(guī)則

4.把下面的端口全都放行了,點那個快速添加的按鈕可以放行端口噢

5.接下來就可以遠(yuǎn)程連接你的云服務(wù)器了

首次連接應(yīng)該會讓你設(shè)置密碼啥的,反正很簡單,這里就跳過了哈

6.進(jìn)入云服務(wù)器,在云服務(wù)器上下載一個寶塔面板,去瀏覽器上就可以下載

網(wǎng)址是 寶塔面板下載,免費全能的服務(wù)器運維軟件 (bt.cn)

7.因為我的服務(wù)器是windows所以下載Windows版的

注:當(dāng)時也是windows版的教程很少,我也廢了很大功夫

8.打開之后應(yīng)該是這樣的,可以自己設(shè)置賬號密碼

9.設(shè)置好之后在自己的電腦瀏覽器打開面板地址(是在自己的瀏覽器不是云服務(wù)器中噢)

注:我這里密碼忘了,不讓我登了,大家一定要記好自己的密碼呀

OK,解決了,隨手告訴大家怎么找回密碼吧,下面便是教程,親測有用如何修改Windows面板密碼教程 - Windows面板 - 寶塔面板論壇 (bt.cn)

登入之后是這個界面

10.點擊軟件商店去下載一些需要的東西,這里大家抄作業(yè)就行了

注:如果大家碰到了下載慢的問題,重新啟動面板就可以解決了

11.之后我們來配置一下數(shù)據(jù)庫,添加一個數(shù)據(jù)庫

12.點擊管理,會跳轉(zhuǎn)到新的網(wǎng)址(如果報404等錯誤有兩個原因,1.安全組沒有放行,2.沒有按照我的軟件去安裝)

13.導(dǎo)入你的sql文件

14.秉著教人教到會的原則,我教一下大家如何去導(dǎo)出本地數(shù)據(jù)庫到sql文件

右鍵表格-->導(dǎo)入/導(dǎo)出-->將數(shù)據(jù)導(dǎo)出到文件

15.按照我這個選擇去導(dǎo)出哈,不然容易導(dǎo)出奇奇怪怪的數(shù)據(jù)

16.jdk的配置

寶塔上只能下載jdk1.8或以下,但是我們的版本是jdk17,所以我們要在本地上傳jdk17

點擊打開即可上傳

后端部署

1.我們部署時部署的是項目的jar包,我們可以通過Maven項目的package功能得到j(luò)ar包,點擊package進(jìn)行打包

2.打包完成后我們拿出jar包,可能會生成多個jar包,我們只拿有配置文件的模塊的那個jar包,這里是Server模塊

3.把項目的配置文件也拿出來,這個項目是application-dev.yml

4.將java項目的jdk環(huán)境配置一下(之前上傳的jdk17)

5.自己把jar包和配置文件上傳到云服務(wù)器哈,和上傳jdk的方法一樣

6.改一下項目的配置文件,將數(shù)據(jù)庫的配置該成云服務(wù)器上的數(shù)據(jù)庫,劃紅圈的那一部分哈

7.部署JAVA項目

點擊添加Java項目,按照如下配置即可,注意項目的jar路徑要是你的jar包的路徑,而且配置文件要和jar包的位置同級,端口要是沒有被占用的端口

至此后端就部署完成了!

前端部署

1.首先要改一下你的前端項目跨域配置

這里的目標(biāo)url要是http://+你的云服務(wù)器公網(wǎng)ip+你的后端項目端口

2.之后將前端項目打包

在終端打開輸入指令

npm run build

如果你的項目又語法錯誤就先改正,不然是打包不了的

3.將打包好的文件上傳到云服務(wù)器

就是畫圈的文件“dist”

4.部署PHP項目

點擊添加站點,域名即是你的云服務(wù)器公網(wǎng)ip,根目錄是你上傳“dist”的目錄

這里注意一下dist目錄下不能再有一個dist目錄,如果會報錯的話,最好檢查一下自己的目錄結(jié)構(gòu)是否正確

至此線上部署完成,完結(jié)撒花嘍!

八、結(jié)語

本文介紹了springboot+vue項目的從代碼編寫到上線的全流程,制作不易,如果幫助到大家的話可以高抬貴手給一個贊,感謝

以后有機(jī)會的話,我會給大家將一些其他內(nèi)容,比如大數(shù)據(jù)項目全流程,或者AI編程之類的,后會有期了!

到此這篇關(guān)于springboot+vue項目從第一行代碼到上線部署全流程的文章就介紹到這了,更多相關(guān)springboot vue項目上線部署內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論