开发中常见问题整理

如何解决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的父子路由

路由占位符

问题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-20210129213210316

bo、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-20210217200812505

jwt优势

  • 简洁: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());
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值