创建一个vue工程:
cmd: vue create 项目名
npm run serve:访问vue工程
在终端安装路由: yarn add vue-router@4
创建一个路由文件夹,在文件夹下创建一个index.js文件:
//导入用来创建路由和确认路由模式的两个方法
import { createRouter,createWebHistory } from "vue-router";
/**
* 定义路由信息
*/
const routes=[];
//创建路由实例并传递routes配置
//我们在这里使用的是html5的路由模式,url中不带有#,部署项目的时候需要注意
const router=createRouter({
history:createWebHistory(),
routes,
})
//全局的路由守卫
router.beforeEach((to,from)=>{
console.log(to);
console.log(from);
return true;
})
//将路由实例暴露
export default router
在main.js文件下全局安装(挂载)路由组件
import { createApp } from 'vue'
import App from './App.vue'
import router from '@/router'
let app=createApp(App);
app.use(router).mount('#app')
终端安装响应式数据:yarn add vuex
创建响应式数据目录store
在store文件夹下创建modules,在modules下创建user.js
在store文件夹下创建actions.js文件,用来实现异步操作的响应式数据
getters.js通过计算可以得到的一些数据
mutations.js基本的函数,无法实现异步操作
index.js主实例,创建vuex的实例
import {createStore} from "vuex"
import user from '@/store/modules/user'
import actions from '@/store/actions'
import mutations from '@/store/mutations'
const store=createStore({
modules:{
user
},
actions,
mutations,
});
export default store
然后需要去main.js中引入,全局安装vuex组件
import { createApp } from 'vue'
import App from './App.vue'
import router from '@/router'
import store from '@/store'
let app=createApp(App);
//全局安装(挂载)路由组件
//全局安装了VUEX组件
app.use(router).use(store).mount('#app')
引入axios,前后端需要发送请求:
创建一个api文件夹,所有与后端交互的都需要放置在api文件夹下
创建一个index.js文件:
import axios from 'axios'
//创建axios实例
const request=axios.create({
//axios中请求配置有baseURL选项,表示URL的公共部分
baseURL:'http://localhost:8088',
//超时时间:毫秒
timeout:10000,
//设置请求头Content-Type,规定前后端的交互使用json
headers:{'Content-Type':'application/json;charset=utf-8'},
});
export default request
创建一个user.js(使用get请求,参数是params,使用post请求,参数是data):
import request from '@/api'
//查询用户列表
export function listUser(query){
return request({
url:"/user",
method:"get",
params:query
});
}
//新增用户
export function addUser(data){
return request({
url:"user",
method:"post",
data:data
});
}
进入主页面APP.VUE里,创建钩子函数测试:
将listUser解构出来:
import { listUser } from '@/api/user';
创建一个钩子函数:
mounted(){
listUser().then(res=>{
console.log(res);
})
}
启动服务:yarn serve
搭建终端:yarn add element-plus
在main.js中挂载ElementPlus:
import { createApp } from 'vue'
import App from './App.vue'
import router from '@/router'
import store from '@/store'
import ElementPlus from 'element-plus'
//引入elementplus中的css样式
import 'element-plus/dist/index.css'
let app=createApp(App);
//全局安装(挂载)路由组件
//全局安装了VUEX组件
//全局安装了ElementPlus组件
app.use(router).use(store).use(ElementPlus).mount('#app')
基于Vue3,面向设计师和开发师的组件库:
https://element-plus.gitee.io/zh-CN/component/button.html
后端工程的创建:修改打包方式
<packaging>war</packaging>
前后端的交互:
前后端交互会出现跨越性问题,需要添加一个注解:CrossOrigin(这种解决跨域问题的方式比较冒险)
vu自带一种代理,这种代理是可以解决跨域问题的。
在vue.config.js中配置一台代理主机:
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
lintOnSave:false,
//配置一台代理主机
devServer:{
port:80,
proxy:"http://localhost:8088/"
}
})
在api文件夹下的index.js修改url: baseURL:'http://localhost:80/ssm_back',
注意:这里的80是代理主机的端口号
需要将前后端界面路径对应起来。
案例:登录
创建一个登录界面:
<template>
<h1>用户登录</h1>
<el-row :gutter="20">
<el-col :span="6"><div class="grid-content ep-bg-purple"/></el-col>
<el-col :span="12">
<el-form :model="form" label-width="120px">
<el-form-item label="用户名">
<el-input v-model="user.username"/>
</el-form-item>
<el-form-item label="密码">
<el-input v-model="user.password" type="password"/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="login">登录</el-button>
</el-form-item>
</el-form>
</el-col>
<el-col :span="6"><div class="grid-content ep-bg-purple"/></el-col>
</el-row>
</template>
<script>
import {ElMessage,ElMessageBox} from 'element-plus'
import axios from 'axios'
export default{
name:"login",
data(){
return{
user:{
username:"",
password:""
}
}
},
methods:{
login(){
//使用axios技术提交数据
axios.post("http://localhost:8088/ssm1_war/user/login",{
"username":this.user.username,
"password":this.user.password
}).then(function(res){
console.log(res.data);
})
}
}
}
</script>
在assets目录下创建一个文件夹style用来配置css样式
/*给当前网页进行一些初始化配置*/
html,
body{
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#app{
height: 100%;
}
当打开一个页面需要去处理一些请求响应,需要使用mounted钩子函数
打开一个页面,就要跳转到路由路径
mounted(){
this.$router.push({
name:"login"
})
}
权限管理:
RBAC权限系统管理
RBAC模型:
Role-Based-Access-Control:谁是什么角色,有什么权限
分成3个基本部分:
用户
角色
权限
User(用户):每个用户都有唯一的UUID,赋予不同的角色
Role(角色):不同的角色有不同的权限
Permission(权限):访问权限
用户-角色:映射关系
角色-权限:映射关系
举例:
admin--管理员
创建用户
冻结用户
修改个人信息
查看个人简介
张三----普通用户
修改个人信息
查看个人简介
导入jedis依赖
<!-- 导入jedis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.0.1</version>
</dependency>
在application.xml中配置jedispool
<!-- 配置jedispool-->
<bean id="jedispool" class="redis.clients.jedis.JedisPool">
<constructor-arg name="host" value="127.0.0.1"/>
<constructor-arg name="port" value="6379"/>
<property name="minIdle" value="20"/>
<property name="maxIdle" value="30"/>
<property name="maxTotal" value="100"/>
</bean>
minIdle:最小的存活数 maxIdle:最大存活数 maxTotal:总数
所有的局部数据变量用基本数据类型
整合redis:
如何使用jedisPool?
在redis里取放东西:
创建一个core包:
创建一个CustomObjectMapper.java类:
package com.jsoft.core;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
public class CustomObjectMapper extends ObjectMapper {
public CustomObjectMapper() {
super();
//去掉默认的时间戳格式
configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
//设置为东八区
setTimeZone(TimeZone.getTimeZone("GMT+8"));
//设置日期转换yyyy-MM-dd HH:mm:ss
setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
// 设置输入:禁止把POJO中值为null的字段映射到json字符串中
configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
// 空值不序列化
setSerializationInclusion(JsonInclude.Include.NON_NULL);
// 反序列化时,属性不存在的兼容处理
getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
// 序列化枚举是以toString()来输出,默认false,即默认以name()来输出
configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, true);
}
}
在core包下创建RedisTemplate类:
package com.jsoft.core;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.exceptions.JedisException;
import javax.annotation.Resource;
@Component
@Slf4j
public class RedisTemplate {
@Resource
private JedisPool jedisPool;
@Resource
private CustomObjectMapper customObjectMapper;
/**
* 向redis中保存字符串类型的数据
* @param key redis中的key值
* @param value redis中的value值
* @param expire
* @return
*/
public String set(String key, String value,long expire){
Jedis jedis=jedisPool.getResource();
String result=null;
//设置key,value的时候同时设置过期时间的方法:setex
try {
result=jedis.setex(key,expire,value);
} catch (JedisException e) {
log.error("redis execution error",e);
jedisPool.returnResource(jedis);//将连接归还
}finally {
jedisPool.returnResource(jedis);
}
return result;
}
/**
* 根据给定的key值去redis查询对应的value
* @param key
* @return
*/
public String get(String key){
Jedis jedis=jedisPool.getResource();
String result=null;
try {
result=jedis.get(key);
}catch (JedisException e) {
log.error("redis execution error",e);
jedisPool.returnResource(jedis);//将连接归还
}finally {
jedisPool.returnResource(jedis);
}
return result;
}
/**
* 将对象以序列化的方式存在与redis中,实际上就是以json格式保存到redis
* @param key
* @param value
* @param expire
* @return
*/
public String setObject(String key, Object value,long expire){
//获取连接
Jedis jedis=jedisPool.getResource();
String result=null;
try{
//序列化的方法
String jsonValue = customObjectMapper.writeValueAsString(value);
if(expire<=0){
result=jedis.set(key,jsonValue);
}else{
jedis.setex(key,expire,jsonValue);
}
}catch (JedisException | JsonProcessingException e) {
log.error("redis execution error",e);
jedisPool.returnResource(jedis);//将连接归还
}finally {
jedisPool.returnResource(jedis);
}
return result;
}
//获取redis,TypeReference是Mybatis提供的类型依赖器,根据类型封装对象
public <T> T getObject(String key, TypeReference<T> typeReference){
//获取连接
Jedis jedis=jedisPool.getResource();
T t=null;
try{
String result= jedis.get(key);
t = customObjectMapper.readValue(result, typeReference);
}catch (JedisException | JsonProcessingException e) {
log.error("redis execution error",e);
jedisPool.returnResource(jedis);//将连接归还
}finally {
jedisPool.returnResource(jedis);
}
return t;
}
}
测试:
package com.jsoft.controller;
import com.fasterxml.jackson.core.type.TypeReference;
import com.jsoft.core.RedisTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
@RestController
@Slf4j
public class TestController {
@Resource
private RedisTemplate redisTemplate;
@GetMapping("test")
public String test(){
redisTemplate.setObject("map", Arrays.asList("aaa","bbb","ccc"),1000000000L);
List<String> map = redisTemplate.getObject("map", new TypeReference<List<String>>() {
});
log.info("******************");
log.info(map.toString());
return "hello ssm";
}
}
UUID:token令牌。
引入依赖JSR303,可以用来限制实体类中的一些属性:
<!-- 导入JSR303-->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.7.Final</version>
</dependency>
@NotNull
@Size(min=5,max=15,message="用户名的长度应该在5-15之间")
private String nickName;
使用@Validated注解绑定JSR303
public ResponseEntity<LoginUser> login(@RequestBody @Validated YdyhUser ydyhUser, BindingResult bingingResult) {
//处理不合法的数据
LoginUser loginUser=UserService.login(ydyhUser);
}
导入UserAgent依赖,可以获取到浏览器版本信息以及操作系统的相关信息
<!-- 导入UserAgent:可以获取到浏览器和用户的一些信息-->
<dependency>
<groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
<version>1.21</version>
</dependency>
想获取当前的请求对象:
//获取request对象
HttpServletRequest request=
((ServletRequestAttributes)(Objects.requireNonNull(RequestContextHolder.getRequestAttributes()))).getRequest();
根据网络IP地址查端口号:
//测试使用java来发送HTTP请求
public static void main(String[] args) {
RestTemplate restTemplate=new RestTemplate();
ResponseEntity<String> forEntity = restTemplate
.getForEntity("https://whois.pconline.com.cn/ipJson.jsp?ip=111.111.111.111&json=true",String.class);
System.out.println(forEntity.getBody());
}