如何解决idea报==java.sql.SQLException: Access denied for user ‘‘@‘localhost‘ (using password: NO)==
应该是将data-去掉
#设置数据库连接信息
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/hah
spring.datasource.username=root
spring.datasource.password=123456
自定义的myBatis的规则
@Bean
public ConfigurationCustomizer configurationCustomizer(){
return new ConfigurationCustomizer() {
@Override
public void customize(Configuration configuration) {
configuration.setMapUnderscoreToCamelCase(true);//开启驼峰命名规则
}
};
}
//批量扫描所有的mapperScan
@MapperScan(value = "com.mfei.mapper")//
配置版mybatis
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mfei.mapper.ContentsMapper">//重点注意:这儿以点分割
<!-- public ContentsDomain getContByCid(Integer id);
public void insertCont(ContentsDomain contentsDomain);-->
<select id="getContByCid" resultType="com.mfei.pojo.model.ContentsDomain">//重点注意:这儿以点分隔
select * from t_contents where cid=#{cid}
</select>
<insert id="insertCont">
insert into t_contents(title,isTop) values (#{title},#{isTop})
</insert>
</mapper>
整合jpa
基本配置
jpa:
hibernate:
#更新或者创建数据表的结构
ddl-auto: update
#控制台显示sql
show-sql: true
@id
@table
@Entity
缓存
@CacheEvict 缓存清除,一般用在删除数据
brforeInvocation = false:缓存的清除是否在方法之前执行
默认代表缓存清除操作实在方法执行之后执行的;如果出现异常就不会清除
RabbitMQ
ElasticSearch
redis
1、安装redis:使用docker(以虚拟机CentsOS系统,linux基础为例)
2、引用redis的start
3、基本配置
//1.储存token
//2.储存身份验证正确
//3.缓存页面显示的数据
@Autowired
StringRedisTemplate stringRedisTemplate;//操作k-v字符串的
@Autowired
RedisTemplate redisTemplate;//操作k-v都是对象的
stringRedisTemplate.opsForValue()[String(字符串)]
stringRedisTemplate.opsForList()[List(列表)]
stringRedisTemplate.opsForSet()[Set(集合)]
stringRedisTemplate.opsForHash()[Hash(散列)]
stringRedisTemplate.opsForZSet()[ZSet(有序集合)]
问题整理:
token的创造,延期,用户解析?
储存在cookie和session位置,及其优缺点?
Restful API规范
1.协议;
2.域名;
3.版本;
4.路径;
5.get|put|post|del..;
6.过滤信息;
7.状态码;
数据对象
DTO;数据传输对象,接受前端
BO;业务对象
VO;视图对象,对DTO进行拓展
PO=POJO;持久层对象,对数据库进行一一映射
跨越问题(浏览器同源策略的保护措施)
前端解决:
后端解决:
越权
数据库持久层;
安全登录权限security
统一返回格式JSON的封装
//简单的分装
public class JsonResult<T> {
private T data;
private String code;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
private String msg;
/**
* 若没有数据返回,默认状态码为 0,提示信息为“操作成功!”
*/
public JsonResult() {
this.code = "0";
this.msg = "操作成功!";
}
/**
* 若没有数据返回,可以人为指定状态码和提示信息
* @param code
* @param msg
*/
public JsonResult(String code, String msg) {
this.code = code;
this.msg = msg;
}
/**
* 有数据返回时,状态码为 0,默认提示信息为“操作成功!”
* @param data
*/
public JsonResult(T data) {
this.data = data;
this.code = "0";
this.msg = "操作成功!";
}
/**
* 有数据返回,状态码为 0,人为指定提示信息
* @param data
* @param msg
*/
public JsonResult(T data, String msg) {
this.data = data;
this.code = "0";
this.msg = msg;
}
}
/**
*比较复杂的封装
*/
package com.xiaobai.realtimesystem.realtimeserver.utils;
/**
* @author xiaobai
* @version 1.0
* @date 2019/5/22 16:43
* @email baijinfeng1202@gmail.com
* @address www.rbx1213.top
* @describe 用于实现接口返回规范的类 所有接口返回值都由该类封装
*/
@SuppressWarnings("ALL")
public class AppResponse<T> {
/**
* 返回值代码 由Status类定义
* @see Status
*/
private int code;
/**
* 返回的附加提示信息
*/
private String msg;
/**
* 返回的数据 若没有则为空
*/
private T data;
/**
* 无参构造必须有
*/
private AppResponse(){ }
/**
* 全参构造方法
* @param code 状态码
* @param msg 附加提示信息
* @param data 数据
*/
private AppResponse(int code,String msg,T data){
this.code = code;
this.msg = msg;
this.data = data;
}
//=============================start of get/set 集合========================
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
//=============================end of get/set 集合========================
/**
* 成功消息的返回
* +2 重载方法
* @return
*/
public static AppResponse success(){
return builder().code(Status.OK).build();
}
/**
* 成功消息的返回
* +2 重载方法
* @param msg 附加提示消息
* @return
*/
public static AppResponse success(String msg){
return builder().code(Status.OK).msg(msg).build();
}
/**
* 成功消息的返回
* +2 重载方法
* @param msg 附加提示消息
* @param data 需要返回的数据
* @param <T>
* @return
*/
public static <T> AppResponse success(String msg,T data){
return builder().code(Status.OK).msg(msg).data(data).build();
}
/**
* 出错消息提示 该方法要求必须返回错误消息
* @param msg 错误消息
* @return
*/
public static AppResponse error(String msg){
return builder().code(Status.ERR).msg(msg).build();
}
/**
* 产生异常提示 必须返回异常消息
* @param msg 异常消息
* @return
*/
public static AppResponse exception(String msg){
return builder().code(Status.EXCEPTION).msg(msg).build();
}
/**
* 未找到的提示消息返回
* @return
*/
public static AppResponse notFound(){
return builder().code(Status.NOTFOND).build();
}
/**
* 构建一个AppResponseBuilder 对象
* @param <T>
* @return
*/
public static <T> AppResponseBuilder builder(){
return new AppResponseBuilder();
}
/**
* 内部类 用来解决static 不能使用泛型的问题
* @param <T>
*/
private static class AppResponseBuilder<T>{
/**
* 返回值代码 由Status类定义
* @see Status
*/
private int code;
/**
* 返回的附加提示信息
*/
private String msg;
/**
* 返回的数据 若没有则为空
*/
private T data;
/**
* 构建一个AppResponse 对象
* @return
*/
public AppResponse build() {
return new AppResponse<T>(this.code, this.msg, this.data);
}
/**
* 链式调用 设置状态码
* @param status 状态 参考Status
* @return
*/
public AppResponseBuilder code(Status status) {
this.code = status.value;
return this;
}
/**
* 链式调用 设置提示信息
* @param msg 提示信息
* @return
*/
public AppResponseBuilder msg(String msg) {
this.msg = msg;
return this;
}
/**
* 链式调用 设置返回数据
* @param data 返回数据
* @return
*/
public AppResponseBuilder data(T data) {
this.data = data;
return this;
}
}
@Override
public String toString() {
return "AppResponse{" +
"code=" + code +
", msg='" + msg + '\'' +
", data=" + data +
'}';
}
}
前后端分离的跨域问题
image-20210118155716495同源策略
解决方法:
https://blog.csdn.net/qq_37651267/article/details/93367870
Springboot 跨域配置无效,接口访问报错解决方法
https://blog.csdn.net/xch_yang/article/details/111768039
entry和tdo、do之间的相互转化
一些插件的使用
npm清除缓存
npm修改缓存位置
element-ui按需引入报错
https://blog.csdn.net/qq_36145755/article/details/107377663
vue的父子路由
路由占位符<router-view></router-view>
问题1:mybatis配置版驼峰命名法的映射
数据库连接超时:“The last packet successfully received from the server was xxx milliseconds ago”
修改数据库连接配置
在数据库连接上,加“&autoReconnect=true&failOverReadOnly=false”配置
更多方法参考https://www.cnblogs.com/jpfss/p/7206912.html
URL路径特殊符号报跨域错误
query和params的区别
https://blog.csdn.net/mf_717714/article/details/81945218
image-20210129210528941 image-20210129213210316bo、dto、vo
POJO
全称为:Plain Ordinary Java Object,即简单普通的java对象。一般用在数据层映射到数据库表的类,类的属性与表字段一一对应。
PO
全称为:Persistant Object,即持久化对象。可以理解为数据库中的一条数据即一个BO对象,也可以理解为POJO经过持久化后的对象。
DTO
全称为:Data Transfer Object,即数据传输对象。一般用于向数据层外围提供仅需的数据,如查询一个表有50个字段,界面或服务只需要用到其中的某些字段,DTO就包装出去的对象。可用于隐藏数据层字段定义,也可以提高系统性能,减少不必要字段的传输损耗。
DAO
全称为:Data Access Object,即数据访问对象。就是一般所说的DAO层,用于连接数据库与外层之间的桥梁,并且持久化数据层对象。
BO
全称为:Business Object,即业务对象。一般用在业务层,当业务比较复杂,用到比较多的业务对象时,可用BO类组合封装所有的对象一并传递。
VO
全称为:Value Object,有的也称为View Object,即值对象或页面对象。一般用于web层向view层封装并提供需要展现的数据。
springSecurity
“认证”、“授权”
授权
http.authorizeRequests()
//放行。。。页面,不需要认证
.antMatchers("/").permitAll()
//其他请求需要认证才能访问,必须登录
.anyRequest().authenticated();
JWT
JSON Web Token
jwt的格式可分为3部分
1、Header中一般包括两部分信息
{
"alg": "RS256",
"typ": "JWT"
}
- alg:声明加密的算法
- typ:声明类型
2、playload(负载)
不在playload中放敏感数据信息
- 标准声明
- 公共声明
- 私有声明
标准声明包括:(不强制)
iss?: string; // JWT的签发者
sub?: string; // JWT所面向的用户
aud?: string; // 接收JWT的一方
exp?: number; // JWT的过期时间
nbf?: number; // 在xxx日期之间,该JWT都是可用的
iat?: number; // 该JWT签发的时间
jti?: number; //JWT的唯一身份标识
3、signature(签证)
加密算法(header (base64加密后)+payload (base64加密后)+secret(加盐))
生成jwt = 三部分用.
拼接后的完整字符串
jwt的功能流程
image-20210217200812505jwt优势
- 简洁:Header、playload、signature三部分生成,数据量小
- playload上包含用户信息,避免多次查询数据库
token的获取
1、首先在maven引入
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.10.3</version>
</dependency>
2、在测试类中生成token
@Test
void contextLoads() {
HashMap<String,Object> map = new HashMap<>();
Calendar instance = Calendar.getInstance();
instance.add(Calendar.SECOND,20);
String tooken = JWT.create().withHeader(map)
.withClaim("username","xiaoming")
.withClaim("userId",12)//注意这儿存的时候是int类型
.withExpiresAt(instance.getTime())
.sign(Algorithm.HMAC256("!@wqer@#%ERT"));
System.out.println(tooken);//eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MTM1NzEzMTEsInVzZXJJZCI6MjEsInVzZXJuYW1lIjoieGlhb21pbmcifQ.dtvLyuACByalZlk6Mr7lXtuxBRbTOs5ToLnQHTJIClM
}
3、解析
@Test
public void test(){
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("!@wqer@#%ERT")).build();
DecodedJWT verify = jwtVerifier.verify("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MTM1NzIxODcsInVzZXJJZCI6MjEsInVzZXJuYW1lIjoieGlhb21pbmcifQ.2BQ3RbUTAQfPOaKTaNS_Sfjsv1JJmmDL2Ci9SQ3r2XA");
System.out.println(verify.getClaim("userId").asString());//这儿为null
System.out.println(verify.getClaim("userId").asInt());//12
System.out.println(verify.getClaim("username").asString());
}
网友评论