特定异常处理
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class) // 指定出现什么异常会被处理
@ResponseBody // 为了能够返回数据
public R error(Exception e) {
e.printStackTrace();
return R.error().message("执行了全局异常处理");
}
// 特定异常处理
@ExceptionHandler(ArithmeticException.class) // 指定出现什么异常会被处理
@ResponseBody // 为了能够返回数据
public R error(ArithmeticException e) {
e.printStackTrace();
return R.error().message("执行了ArithmeticException异常处理");
}
}
自定义异常处理
-
创建自定义异常类继承
RuntimeException
,写异常属性@Data @NoArgsConstructor @AllArgsConstructor public class GuliException extends RuntimeException{ @ApiModelProperty("异常状态码") private Integer code; @ApiModelProperty("异常信息") private String msg; }
-
添加异常处理方法
@ExceptionHandler(GuliException.class) // 指定出现什么异常会被处理 @ResponseBody // 为了能够返回数据 public R error(GuliException e) { e.printStackTrace(); return R.error().code(e.getCode()).message(e.getMsg()); }
-
在需要抛出异常的地方抛出
try { int i = 10/0; } catch(Exception e) { throw new GuliException(20001, "自定义异常"); }
统一日志处理
日志级别
在springboot配置文件中配置
# 设置日志级别, ERROR, WARN, INFO, DEBUG, ALL, 越靠后显示内容越多
logging.level.root=INFO
把日志输出到文件中
使用Logback工具
-
把之前在
properties
文件里面添加的所有日志相关的内容全部删掉# 设置日志级别, ERROR, WARN, INFO, DEBUG, ALL, 越靠后显示内容越多 #logging.level.root=INFO # mybatis日志 #mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
-
resources中创建
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?> <configuration scan="true" scanPeriod="10 seconds"> <!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 --> <!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true --> <!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 --> <!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 --> <contextName>logback</contextName> <!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 --> <property name="log.path" value="D:/guli_1010/edu" /> <!-- 彩色日志 --> <!-- 配置格式变量:CONSOLE_LOG_PATTERN 彩色日志格式 --> <!-- magenta:洋红 --> <!-- boldMagenta:粗红--> <!-- cyan:青色 --> <!-- white:白色 --> <!-- magenta:洋红 --> <property name="CONSOLE_LOG_PATTERN" value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) |%highlight(%-5level) |%blue(%thread) |%blue(%file:%line) |%green(%logger) |%cyan(%msg%n)"/> <!--输出到控制台--> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息--> <!-- 例如:如果此处配置了INFO级别,则后面其他位置即使配置了DEBUG级别的日志,也不会被输出 --> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>INFO</level> </filter> <encoder> <Pattern>${CONSOLE_LOG_PATTERN}</Pattern> <!-- 设置字符集 --> <charset>UTF-8</charset> </encoder> </appender> <!--输出到文件--> <!-- 时间滚动输出 level为 INFO 日志 --> <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在记录的日志文件的路径及文件名 --> <file>${log.path}/log_info.log</file> <!--日志文件输出格式--> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> <charset>UTF-8</charset> </encoder> <!-- 日志记录器的滚动策略,按日期,按大小记录 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- 每天日志归档路径以及格式 --> <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <!--日志文件保留天数--> <maxHistory>15</maxHistory> </rollingPolicy> <!-- 此日志文件只记录info级别的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>INFO</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- 时间滚动输出 level为 WARN 日志 --> <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在记录的日志文件的路径及文件名 --> <file>${log.path}/log_warn.log</file> <!--日志文件输出格式--> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> <charset>UTF-8</charset> <!-- 此处设置字符集 --> </encoder> <!-- 日志记录器的滚动策略,按日期,按大小记录 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <!--日志文件保留天数--> <maxHistory>15</maxHistory> </rollingPolicy> <!-- 此日志文件只记录warn级别的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>warn</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- 时间滚动输出 level为 ERROR 日志 --> <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 正在记录的日志文件的路径及文件名 --> <file>${log.path}/log_error.log</file> <!--日志文件输出格式--> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> <charset>UTF-8</charset> <!-- 此处设置字符集 --> </encoder> <!-- 日志记录器的滚动策略,按日期,按大小记录 --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>100MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> <!--日志文件保留天数--> <maxHistory>15</maxHistory> </rollingPolicy> <!-- 此日志文件只记录ERROR级别的 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> </appender> <!-- <logger>用来设置某一个包或者具体的某一个类的日志打印级别、以及指定<appender>。 <logger>仅有一个name属性, 一个可选的level和一个可选的addtivity属性。 name:用来指定受此logger约束的某一个包或者具体的某一个类。 level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF, 如果未设置此属性,那么当前logger将会继承上级的级别。 --> <!-- 使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作: 第一种把<root level="INFO">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息 第二种就是单独给mapper下目录配置DEBUG模式,代码如下,这样配置sql语句会打印,其他还是正常DEBUG级别: --> <!--开发环境:打印控制台--> <springProfile name="dev"> <!--可以输出项目中的debug日志,包括mybatis的sql日志--> <logger name="com.liuscoding.edu.mapper" level="DEBUG" additivity="false"/> <!-- root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性 level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,默认是DEBUG 可以包含零个或多个appender元素。 --> <root level="INFO"> <appender-ref ref="CONSOLE" /> <appender-ref ref="INFO_FILE" /> <appender-ref ref="WARN_FILE" /> <appender-ref ref="ERROR_FILE" /> </root> </springProfile> <!--生产环境:输出到文件--> <springProfile name="pro"> <root level="INFO"> <appender-ref ref="CONSOLE" /> <appender-ref ref="DEBUG_FILE" /> <appender-ref ref="INFO_FILE" /> <appender-ref ref="ERROR_FILE" /> <appender-ref ref="WARN_FILE" /> </root> </springProfile> </configuration>
将异常信息输出到文件中
-
在异常处理类加上注解
@Slf4j
@ControllerAdvice @Slf4j public class GlobalExceptionHandler {
-
在具体执行异常处理函数里面输出日志
@ExceptionHandler(GuliException.class) // 指定出现什么异常会被处理 @ResponseBody // 为了能够返回数据 public R error(GuliException e) { log.error(e.getMsg()); // 这里是输出日志的 e.printStackTrace(); return R.error().code(e.getCode()).message(e.getMsg()); }
前端技术
VSCode安装下面的插件
创建工作区
前端代码卸载工作区里
- 在本地创建空文件夹
- 使用vscode大概空文件夹
- 选择 文件=>将工作区另存为 把这个工作区保存到刚刚的空文件夹里面
Vue
Vue入门案例
-
创建html页面,vscode 中使用
!
可以快速生成 -
引入vue的js文件,类似于jquery
<script src="vue.min.js"></script>
-
在html页面创建div标签,添加id属性
<div id="app"></div>
-
编写vue代码,固定的结构
<script> // 创建一个vue对象 new Vue({ el: '#app', // 绑定vue作用的范围 data: { // 定义页面中显示的模型数据 message: 'Hello Vue!' } }) </script>
-
使用插值表达式
获取data里面定义的值{{名称}}
抽取代码片段
抽取页面基本结构,方便之后的工程使用
{
"vue htm": {
"scope": "html",
"prefix": "vuehtml",
"body": [
"<!DOCTYPE html>",
"<html lang=\"en\">",
"",
"<head>",
" <meta charset=\"UTF-8\">",
" <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">",
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">",
" <title>Document</title>",
"</head>",
"",
"<body>",
" <div id=\"app\">",
"",
" </div>",
" <script src=\"vue.min.js\"></script>",
" <script>",
" new Vue({",
" el: '#app',",
" data: {",
" $1",
" }",
" })",
" </script>",
"</body>",
"</html>"
]
}
}
axios
-
不是vue里面的一部分,但是经常和vue一起使用,用来实现ajax操作。
-
使用axios应用场景
-
axios的使用
-
创建html页面,引入js文件,包含两个js文件:vue和axios
<script src="vue.min.js"></script> <script src="axios.min.js"></script>
-
编写axios代码
-
构造json文件,用于后面请求数据
-
发送ajax请求文件,得到数据在页面显示
new Vue({ el: '#app', data: { // 定义变量和初始值 userList: [] // 定义变量,空数组 }, created() { // 页面渲染之前执行 // 调用定义的方法 this.getUserList() }, methods: { // 编写具体的方法 // 创建方法,查询所有用户数据 getUserList() { // 使用axios发送ajax请求 // axios.提交方式("请求接口路径").then(箭头函数).catch(箭头函数) axios.get("data.json") .then(response => { // response就是请求后返回的数据 console.log('***'+response) }) // 请求成功执行then方法 .catch(error => { }) // 请求失败执行catch方法 } } })
-
-
new Vue({
el: '#app',
data: { // 定义变量和初始值
userList: [] // 定义变量,空数组
},
created() { // 页面渲染之前执行
// 调用定义的方法
this.getUserList()
},
methods: { // 编写具体的方法
// 创建方法,查询所有用户数据
getUserList() {
// 使用axios发送ajax请求
// axios.提交方式("请求接口路径").then(箭头函数).catch(箭头函数)
axios.get("data.json")
.then(response => { // response就是请求后返回的数据
// console.log(response)
// console.log(response.data.data.items)
this.userList = response.data.data.items
}) // 请求成功执行then方法
.catch(error => {
}) // 请求失败执行catch方法
}
}
})
<!-- 把userList里的数据进行显示 -->
<table border="1">
<tr v-for="(user,index) in userList">
<td>{{index}}</td>
<td>{{user.name}}</td>
<td>{{user.age}}</td>
</tr>
</table>
element-ui
饿了么出品的基于Vue.js的后台组件
https://element.eleme.cn/#/zh-CN/
Node.js
-
什么是Node.js
不需要浏览器,直接使用nodejs运行JavaScript代码 -
模拟服务器效果,比如tomcat
const http = require('http'); http.createServer(function (request, response) { // 发送HTTP头部 // HTTP 状态值200 : OK // 内容类型: text/plain response.writeHead(200, {'Content-Type':'text/plain'}); response.end('Hello Server'); }).listen(8888); console.log('Server running at http://127.0.0.1:8888/');
-
使用nodejs执行JavaScript代码
console.log("hello nodejs")
使用node
命令执行js文件即可。
npm
后端中,maven用来构建项目,管理jar依赖,联网下载依赖
相当于前端的maven,管理前端js依赖,联网下载js依赖,比如jquery
演示npm具体操作
-
npm项目初始化
使用命令npm init
项目初始化之后会生成一个文件package.json
类似于后端的pom.xml
-
npm下载js依赖
使用命令npm install 依赖名称
设置成淘宝的镜像# 配置镜像地址 npm config set registry https://registry.npm.taobao.org # 查看npm配置信息 npm config list
babel
转码器,把es6代码转换成es5代码,提高代码的浏览器兼容性。
安装babel工具
npm install --global babel-cli
创建es6代码
let input = [1, 2, 3]
// 将数组的每个元素 +1
input = input.map(item => item + 1)
console.log(input)
配置.babelrc
是Babel的配置文件,存放在项目的根目录下,用来设置转码规则和插件,基本格式如下
{
"presets": ["es2015"],
"plugins": []
}
安装es2015转码器
npm install --save-dev babel-preset-es2015
使用命令转码
- 根据文件转码
babel 源文件路径 -o 目标文件路径
- 根据文件夹转码
babel 源文件夹 -d 目标文件夹
转换过来的js文件与源文件同名
模块化
是什么
- 开发后端接口的时候,开发controller service mapper,controller注入service,service注入mapper
后端中类与类之间的调用称为后端模块化操作 - 前端模块化,在前端中,js与js之间的调用称为模块化
es5实现模块化
01.js
// 创建方法
const sum = function(a,b){
return parseInt(a) + parseInt(b)
}
const subtract = function(a,b){
return parseInt(a) - parseInt(b)
}
// 设置哪些方法可以被其他js调用
module.exports = {
sum: sum,
subtract: subtract
}
02.js
// 调用01.js方法
const m = require('./01.js')
const res1 = m.sum(1, 2);
const res2 = m.subtract(2, 1);
console.log(res1)
console.log(res2)
es6实现模块化
如果es6的模块化不能在nodejs中运行,则需要使用babel转换成es5之后才能运行
01.js
// 定义方法,设置哪些方法可以被其他js调用
export function getList() {
console.log('获取数据列表');
}
export function save() {
console.log('保存')
}
// 简化: 可以输出多个函数
// 使用这个之后,上面的函数无法输出
export default {
test() {
console.log('test')
},
test2() {
console.log('test2')
},
getList() {
console.log('获取数据列表');
},
save() {
console.log('保存')
}
}
02.js
// 引入01.js,调用01.js的方法
import { getList, save } from "./01.js";
getList()
save()
02.js写法2
import m from './01.js'
m.test();
m.getList();
webpack
前端资源加载/打包工具。可以根据依赖关系将多种js、css、less文件转换成一个静态文件,减少页面请求。
-
安装webpack工具
npm install -g webpack webpack-cli
-
初始化项目
npm init -y
-
新建一个文件夹,创建三个js文件
// common.js exports.info = function (str) { document.write(str) // 浏览器中输出 }
// utils.js exports.add = function (a, b) { return a + b }
// main.js const common = require('./common.js') const utils = require('./utils.js') common.info('hello common' + utils.add(1, 2))
-
创建webpack配置文件,配置打包信息
const path = require("path"); //Node.js内置模块 module.exports = { entry: './src/main.js', //配置入口文件 output: { path: path.resolve(__dirname, './dist'), //输出路径,__dirname:当前文件所在路 filename: 'bundle.js' //输出文件 } }
-
使用命令执行打包工作
webpack # 有黄色警告 webpack --mode=development # 没有警告, 可以设置production或development
打包css
-
创建css文件,写样式内容
body { background-color: red; }
-
在main.js中引入css文件
// 引入css文件 require('./style.css')
-
安装style-loader 和 css-loader
webpack本身只能处理JavaScript模块,如果要处理其他类型的文件,就需要使用loader进行转换npm install --save-dev style-loader css-loader
-
修改webpack.config.js
const path = require("path"); //Node.js内置模块 module.exports = { entry: './src/main.js', //配置入口文件 output: { path: path.resolve(__dirname, './dist'), //输出路径,__dirname:当前文件所在路 filename: 'bundle.js' //输出文件 }, module: { rules: [ { test: /\.css$/, // 打包规则应用到.css结尾的文件上 use: ['style-loader','css-loader'] } ] } }
搭建项目前端页面环境
选取一个模版(框架)进行环境搭建,这里选取vue-admin-template
- 解压压缩文件到工作区
- 通过vscode终端打开解压的文件夹,进行依赖安装
通过配置文件加载依赖,使用命令npm install
,报错的话可以加上--legacy-peer-deps
参数 - 启动下载好的项目
命令npm run dev
前端页面环境说明
-
前端框架入口
-
前端页面环境使用框架(模版),主要基于两种技术实现出来
vue-admin-template模版 = vue + element-ui -
build目录
放项目构件的脚本文件 -
config目录
index.js中把useEslint: true
,值改为false
接口的地址在另外两个js文件中修改,这两个文件分别对应npm run dev
和npm run prod
-
src目录