普通视图

发现新文章,点击刷新页面。
昨天以前点滴日记

最基本的RedisUtils(CRUD)

作者 点滴
2022年7月29日 19:38
package com.ddkjt.utils;

import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * Redis工具类
 */

@Component
@Slf4j
@AllArgsConstructor
public class RedisUtils {

    private final RedisTemplate<String, Object> redisTemplate;

    /**
     * 存放object
     *
     * @param key     键
     * @param value   值
     * @param timeout 过期时间
     */
    public void set(String key, Object value, Long timeout) {
        try {
            redisTemplate.opsForValue().set(key, toJson(value));
            if (timeout != null) {
                redisTemplate.expire(key, timeout, TimeUnit.SECONDS);
            }
        } catch (Exception e) {
            log.error(String.valueOf(e));
        }
    }

    public void set(String key, Object value) {
        set(key, value, null);
    }

    /**
     * 删除
     *
     * @param key 键
     * @return 返回boolean
     */
    public Boolean delKey(String key) {
        return redisTemplate.delete(key);
    }

    /**
     * 查询
     *
     * @param key 键
     * @return 返回Object
     */
    public Object get(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    /**
     * 判断 key是否存在
     *
     * @param key 键
     * @return true 存在 false不存在
     */
    public Boolean hasKey(String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * Object转成JSON数据
     *
     * @param object 接收值
     * @return 返回值
     */
    private String toJson(Object object) {
        if (object instanceof Integer || object instanceof Long || object instanceof Float || object instanceof Double
                || object instanceof Boolean || object instanceof String) {
            return String.valueOf(object);
        }
        return JSON.toJSONString(object);
    }

}

我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=345vh24dw86cw

Java如何不用“return”返回数据

作者 点滴
2022年7月29日 19:32

今天遇到了这样一个问题:拦截器中true为成功拦截,false为拦截失败那么怎么给前台用户提示配拦截呢?方法如下:

private void returnJson(HttpServletResponse response, String json) {
    response.setCharacterEncoding("UTF-8");
    response.setContentType("text/html; charset=utf-8");
    try (PrintWriter writer = response.getWriter()) {
        writer.print(json);
    } catch (IOException e) {
        log.error(e.getMessage());
    }
}

好水

递归实现无限极菜单

作者 点滴
2022年7月29日 19:26
public List<Types> buildTree(List<Types> list) {
    //父级(总的)
    List<Types> typesList = new ArrayList<>();
    list.forEach(t -> {
        if (t.getParentId() == null || t.getParentId() == 0) {
            typesList.add(nodeTree(t, list));
        }
    });
    return typesList;
}
//types 父级的对象
public Types nodeTree(Types types, List<Types> list) {
    List<Types> typesList = new ArrayList<>();
    list.forEach(t -> {
        if (t.getParentId() != null && types.getId().equals(t.getParentId())) {
            typesList.add(nodeTree(t, list));
        }
    });
    types.setChildren(typesList);
    return types;
}

SkyWalking-链路追踪

作者 点滴
2022年7月14日 14:23

一、下载

官网:Downloads | Apache SkyWalking

网盘:百度网盘 (若依的) 提取码:vneh

二、配置

<mark>解压下载的压缩包</mark>

更改一些端口(可以不改)

  • 面板端口:

webapp下的webapp.yml,默认8080

server:
  port: 8080
  • 接收前端请求的端口

webapp下的webapp.yml,默认12800

collector:
  path: /graphql
  ribbon:
    ReadTimeout: 10000
    listOfServers: 127.0.0.1:12800
  • 收集监控数据的端口

config下的application.yml,默认11800

gRPCPort: ${SW_CORE_GRPC_PORT:11800}

在idea中配置SkyWalking

1.点击编辑配置

2.配置环境

  1.  -javaagent: skywalking-agent.jar路径
  2.  -Dskywalking.agent.service_name=服务名称
  3.  -Dskywalking.collector.backend_service=skywalking收集器服务的地址,默认端口11800

-javaagent:D:\Program\service\apache-skywalking-apm-bin\agent\skywalking-agent.jar
-Dskywalking.agent.service_name=demo
-Dskywalking.collector.backend_service=localhost:11800

数据持久化—mysql数据库配置

1.打开config下的application.yml

2.找到 selector: ${SW_STORAGE:h2}

3.替换为 selector: ${SW_STORAGE:mysql}

4.找到 mysql ,修改配置mysql,改为自己的配置即可

mysql:
    properties:
      jdbcUrl: ${SW_JDBC_URL:"jdbc:mysql://localhost:3306/swtest?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false"}
      dataSource.user: ${SW_DATA_SOURCE_USER:root}
      dataSource.password: ${SW_DATA_SOURCE_PASSWORD:root}
      dataSource.cachePrepStmts: ${SW_DATA_SOURCE_CACHE_PREP_STMTS:true}
      dataSource.prepStmtCacheSize: ${SW_DATA_SOURCE_PREP_STMT_CACHE_SQL_SIZE:250}
      dataSource.prepStmtCacheSqlLimit: ${SW_DATA_SOURCE_PREP_STMT_CACHE_SQL_LIMIT:2048}
      dataSource.useServerPrepStmts: ${SW_DATA_SOURCE_USE_SERVER_PREP_STMTS:true}
    metadataQueryMaxSize: ${SW_STORAGE_MYSQL_QUERY_MAX_SIZE:5000}
    maxSizeOfArrayColumn: ${SW_STORAGE_MAX_SIZE_OF_ARRAY_COLUMN:20}
    numOfSearchableValuesPerTag: ${SW_STORAGE_NUM_OF_SEARCHABLE_VALUES_PER_TAG:2}

5.将mysql架包加入到oap-libs文件夹下(注意版本)

6.新建swtest数据库

三、启动

点击bin下的startup.bat即可启动

查看日志:logs/日志文件

可能遇到的报错: Specified key was too long; max key length is 767 bytes

解决办法:执行sql SET GLOBAL INNODB_LARGE_PREFIX = ON;

如果没有什么报错的话访问 http://localhost:8080 即可

Jenkins

作者 点滴
2022年7月7日 17:20

Jenkins

一、安装Jenkins

官网:[https://www.jenkins.io/]()

去官网下载后上传到:/usr/Jenkins文件夹中

放开1231端口

执行命令:

nohup java -jar /usr/Jenkins/jenkins.war --ajp13Port=-1 --httpPort=1231 &

访问地址:主机ip:1231

注意:选择自定义安装插件,安装Git就可以了,其它的暂时没必要

根据提示完成初始化配置

二、使用Jenkins

1.下载插件:

系统管理——》插件管理——》可选插件

常用插件:Git、Maven、Localization: Chinese(中文插件)

2.配置插件:

系统管理——》全局工具设置

配置JDK:

配置Maven:

3.新建文件

在usr/local/dev/新建文件夹,来存放打包好的项目,这里用demo来演示

在demo下新建文件:

run-jenkins.sh:

APP_NAME=demo.jar

usage() {
    echo "Usage: sh 执行脚本.sh [start|stop|restart|status]"
    exit 1
}

is_exist(){
 pid=`ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}' `
  if [ -z "${pid}" ]; then
   return 1
  else
    return 0
  fi
}

start(){
  is_exist
  if [ $? -eq "0" ]; then
    echo "${APP_NAME} is already running. pid=${pid} ."
  else
    nohup java -jar /usr/local/dev/demo/$APP_NAME >demo.log &
    echo "App is runing success!"
  fi
}

stop(){
  is_exist
  if [ $? -eq "0" ]; then
    kill -9 $pid
  else
    echo "${APP_NAME} is not running"
  fi
}

status(){
  is_exist
  if [ $? -eq "0" ]; then
    echo "${APP_NAME} is running. Pid is ${pid}"
  else
    echo "${APP_NAME} is NOT running."
  fi
}

restart(){
  stop
  start
}

case "$1" in
  "start")
    start
    ;;
  "stop")
    stop
    ;;
  "status")
    status
    ;;
  "restart")
    restart
    ;;
  *)
    usage
    ;;
esac

注意:还要建一个demo.jar、old,避免找不到文件/文件夹

4.新建任务:

输入任务名称,选择“构建一个Maven项目”,点击确定。

找到下面的源码管理,选择Git,输入Git地址、选择Git账号,没用则添加

找到建造,输入pom.xml文件路径

找到发布步骤,选择“仅在构建成功时运行”,点击“添加构建步骤”,选择“执行shell”

复制以下命令:

备注:/root/.jenkins/workspace/demo是默认从Git上拉下来的源码路径;

/usr/local/dev/demo/old是备份的文件路径

sh /usr/local/dev/demo/run-jenkins.sh stop
cp /usr/local/dev/demo/demo.jar /usr/local/dev/demo/old/demo_$(date +%Y-%m-%d-%H-%M-%S).jar
rm -f /usr/local/dev/demo/demo.jar
cp /root/.jenkins/workspace/demo/target/demo.jar /usr/local/dev/demo/

如果只备份上一次的打包下来的文件则先清空/old下的文件:

sh /usr/local/dev/demo/run-jenkins.sh stop
rm -rf /www/wwwroot/training/old/*
cp /usr/local/dev/demo/demo.jar /usr/local/dev/demo/old/demo_$(date +%Y-%m-%d-%H-%M-%S).jar
rm -f /usr/local/dev/demo/demo.jar
cp /root/.jenkins/workspace/demo/target/demo.jar /usr/local/dev/demo/

再次添加构建后步骤,选择“执行shell”,复制以下命令:

cd /usr/local/dev/demo/
sh /usr/local/dev/demo/run-jenkins.sh stop
sh /usr/local/dev/demo/run-jenkins.sh status
OLD_BUILD_ID=$BUILD_ID
echo $OLD_BUILD_ID
BUILD_ID=DONTKILLME
sh /usr/local/dev/demo/run-jenkins.sh restart
BUILD_ID=$OLD_BUILD_ID
echo $BUILD_ID

点击保存即可

5.运行

点击后面小三角或名称后面小三角下的立即构建都可以

查看日志:

点击名称

点击左下角要查看的记录

点击“控制台输出”即可查看日志

自定义Maven

1、上传maven到/usr/etc/maven
2、打开系统管理——》全局工具配置——》Maven
3、点击新增Maven
4、给maven取一个名字,取消勾选自动安装,填写maven的路径(/usr/etc/maven/)
5、打开/usr/etc/maven/conf/setting.xml文件
6、找到<localRepository>标签,更改存储库路径/usr/etc/maven/MavenRepository

近况-2022年3月27日

作者 点滴
2022年3月27日 09:13

前言

最近发生了太多太多的事情,一直没有更新

工作

  没错我“毕业”了,3.24开启了我的板砖之旅。工作是之前的教员@穆雄雄老师推荐的,公司还不错,对新人很照顾,总之在公司认识熟悉的人还是不错的。

搬家

  今天就从宿舍搬到合租房中了,房子是公司老板之前的一个学生给找的,价格很合适550元/月,面积不到20㎡,除了空调其它的都有,以我现在的经济情况也没得挑了,就先暂时住下了。

在学校的一些事

  忘记什么时间了,学校举行了第二次模拟面试,问的都是SSM(spring spring mvc mybatis)中的知识,面试老师是一位女教员,问的问题太犀利了。。。
  从3月起山东疫情又严重了,我们学校也直接封校了,周六周天只能9:00到12:00可以出去,这让早晨本就起不来的我们雪上加霜。

服务器和域名

  .com域名续费价格是70元/年,现在想想还是.cn的性价比高,可惜我又不舍得换,毕竟网站在首页已经有排名了。服务器就比较棘手了,还有一次以优惠价格续费的机会,这次我直接续费了一年,下次续费完就要考虑用阿里云了。

干货!SSM实现登录和退出

作者 点滴
2022年1月25日 13:21

前言

  作为主修Java的我竟然没有发布过一篇有关Java的文章,这究竟是道德的沦丧还是人性的扭曲!额,其实是我太菜了,怕被喷……

  事情是这样的,为了系统的安全,配置了一个拦截器来拦截未登录或session过期的用户,结果把登录页和静态资源也给拦截了,为解决这个问题,配置了mvc:resources和mvc:exclude-mapping后问题仍然存在,于是我就对判断是否拦截下手了。

部分代码

UserController.java:

package com.ddkjt.controller;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.ddkjt.po.User;
import com.ddkjt.service.UserService;

@Controller("userController")
@RequestMapping("/")
public class UserController {
    
    @Resource(name="userService")
    private UserService userService;

    public UserService getUserService() {
        return userService;
    }

    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    
    //登录
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String login() {
        return "login";
    }
    
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String login(User u,Model model,HttpServletResponse response,HttpServletRequest request) {
        User user = userService.login(u);
        //判断用户是否存在
        if(user != null){
            request.getSession().setAttribute("user", user);
            //判断用户是否点击了登录保留一周
            if(request.getParameter("login_time") == "on"){
                request.getSession().setMaxInactiveInterval(7*24*60*60);
            }else{
                request.getSession().setMaxInactiveInterval(2*60*60);
            }
            return "redirect:index";
        }else{
            model.addAttribute("msg","账号和密码不匹配,请重新输入");
            return "login";
        }
    }
    
    //退出登录
    @RequestMapping("/logout")
    public String logout(HttpSession session) {
        session.invalidate();
        return "redirect:login";
    }
    
}

SecurityInterceptor.java:

package com.ddkjt.tool;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class SecurityInterceptor implements HandlerInterceptor{

    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {
        
    }

    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception {
        
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/";
        //判断session是否存在、是否是login页面,访问路径是否包含static
        if(request.getSession().getAttribute("user") == null && !request.getRequestURL().toString().equals(basePath+"login") && !request.getRequestURL().toString().contains("static")) {
            response.sendRedirect(request.getContextPath()+"/login");
            return false;
        }
        return true;
    }

}

spring_mvc.xml:

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/**"/>
        <bean class="com.ddkjt.tool.SecurityInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

login.jsp:

<form class="layui-form" method="post" action="./login">
      <div class="layui-form-item">
              <input type="text" name="user_name" placeholder="账号" class="layui-input">
        </div>
        <div class="layui-form-item">
              <input type="password" name="user_pwd" placeholder="密码" class="layui-input">
        </div>
        <div class="layui-form-item">
              <input type="checkbox" name="login_time" title="登录保留一周" checked>
        </div>
        <div class="layui-form-item">
            <input type="submit" class="layui-btn layui-btn-normal layui-btn-fluid" value="登录" />
        </div>
</form>
<script src="static/layui/layui.js" charset="utf-8"></script>
<script src="static/pear/pear.js"></script>
<script type="text/javascript">
    layui.use(['toast','jquery'],function() {
        var $ = layui.jquery;
        var toast = layui.toast;
        if('${msg}' != ''){
            toast.error({title: '错误信息',message: '${msg}',position: 'topCenter'});
        }
        $(".layui-btn").click(function(){
            if($('input[name="user_name"]').val() == '' || $('input[name="user_pwd"]').val() == ''){
                toast.error({title: '错误信息',message: '账号和密码不能为空,请输入',position: 'topCenter'});
                return false;
            }
        });
    });
</script>

结语

本来是用的Ajax提交登录,但返回的结果乱码,就懒得解决了。

给网站“挂”上灯笼

作者 点滴
2022年1月18日 19:58

春节将至,年味渐浓。给自己的网站“挂”个灯笼,增加几分年味。

代码部分

html:

<div class="deng-box">
    <div class="deng">
        <div class="xian"></div>
        <div class="deng-a">
            <div class="deng-b">
                <div class="deng-t">节</div>
            </div>
        </div>
        <div class="shui shui-a">
            <div class="shui-c"></div>
            <div class="shui-b"></div>
        </div>
    </div>
</div>
<div class="deng-box1">
    <div class="deng">
        <div class="xian"></div>
        <div class="deng-a">
            <div class="deng-b">
                <div class="deng-t">节</div>
            </div>
        </div>
        <div class="shui shui-a">
            <div class="shui-c"></div>
            <div class="shui-b"></div>
        </div>
    </div>
</div>

css:

.deng-box {
    position: fixed;
    top: -40px;
    right: 50px;
    z-index: 999;
}
.deng-box1 {
    position: fixed;
    top: -30px;
    right: 120px;
    z-index: 999;
}
.deng-box1 .deng {
    position: relative;
    width: 120px;
    height: 90px;
    margin: 50px;
    background: #d8000f;
    background: rgba(216, 0, 15, 0.8);
    border-radius: 50% 50%;
    -webkit-transform-origin: 50% -100px;
    -webkit-animation: swing 5s infinite ease-in-out;
    box-shadow: -5px 5px 30px 4px rgba(252, 144, 61, 1);
}
.deng {
    position: relative;
    width: 120px;
    height: 90px;
    margin: 50px;
    background: #d8000f;
    background: rgba(216, 0, 15, 0.8);
    border-radius: 50% 50%;
    -webkit-transform-origin: 50% -100px;
    -webkit-animation: swing 3s infinite ease-in-out;
    box-shadow: -5px 5px 50px 4px rgba(250, 108, 0, 1);
}
.deng-a {
    width: 100px;
    height: 90px;
    background: #d8000f;
    background: rgba(216, 0, 15, 0.1);
    margin: 12px 8px 8px 10px;
    border-radius: 50% 50%;
    border: 2px solid #dc8f03;
}
.deng-b {
    width: 45px;
    height: 90px;
    background: #d8000f;
    background: rgba(216, 0, 15, 0.1);
    margin: -4px 8px 8px 26px;
    border-radius: 50% 50%;
    border: 2px solid #dc8f03;
}
.xian {
    position: absolute;
    top: -20px;
    left: 60px;
    width: 2px;
    height: 20px;
    background: #dc8f03;
}
.shui-a {
    position: relative;
    width: 5px;
    height: 20px;
    margin: -5px 0 0 59px;
    -webkit-animation: swing 4s infinite ease-in-out;
    -webkit-transform-origin: 50% -45px;
    background: #ffa500;
    border-radius: 0 0 5px 5px;
}
.shui-b {
    position: absolute;
    top: 14px;
    left: -2px;
    width: 10px;
    height: 10px;
    background: #dc8f03;
    border-radius: 50%;
}
.shui-c {
    position: absolute;
    top: 18px;
    left: -2px;
    width: 10px;
    height: 35px;
    background: #ffa500;
    border-radius: 0 0 0 5px;
}
.deng:before {
    position: absolute;
    top: -7px;
    left: 29px;
    height: 12px;
    width: 60px;
    content: " ";
    display: block;
    z-index: 999;
    border-radius: 5px 5px 0 0;
    border: solid 1px #dc8f03;
    background: #ffa500;
    background: linear-gradient(to right, #dc8f03, #ffa500, #dc8f03, #ffa500, #dc8f03);
}
.deng:after {
    position: absolute;
    bottom: -7px;
    left: 10px;
    height: 12px;
    width: 60px;
    content: " ";
    display: block;
    margin-left: 20px;
    border-radius: 0 0 5px 5px;
    border: solid 1px #dc8f03;
    background: #ffa500;
    background: linear-gradient(to right, #dc8f03, #ffa500, #dc8f03, #ffa500, #dc8f03);
}
.deng-t {
    font-family: 华文行楷, Arial, Lucida Grande, Tahoma, sans-serif;
    font-size: 3.2rem;
    color: #dc8f03;
    font-weight: bold;
    line-height: 85px;
    text-align: center;
}
.night .deng-t, .night .deng-box, .night .deng-box1 {
    background: transparent !important;
}
@-moz-keyframes swing {
    0% {
        -moz-transform: rotate(-10deg)
    }
    50% {
        -moz-transform: rotate(10deg)
    }
    100% {
        -moz-transform: rotate(-10deg)
    }
}
@-webkit-keyframes swing {
    0% {
        -webkit-transform: rotate(-10deg)
    }
    50% {
        -webkit-transform: rotate(10deg)
    }
    100% {
        -webkit-transform: rotate(-10deg)
    }
}
.deng-box,.deng-box1{
    pointer-events:none;
}

简单方式

如果觉得太麻烦或是编程小白,也没关系,复制以下代码粘贴到任意位置就可以了

<script type="text/javascript" src="https://api.ddkjt.com/api/lantern.js"></script>

PHP实现一言 / 随机一句功能

作者 点滴
2022年1月17日 13:03

使用PHP编写简单的一言(点滴api一言调用实现方法)

准备工作

  1. 打开PHP开发工具,新建php文件、data.dat两个文件
  2. 打开data.dat,编写要随机显示处理的文本,一条一行

代码部分

<?php
$filename = 'data.dat';
header('Content-type: text/html; charset=utf-8');
if(!file_exists($filename)) {
    die($filename . ' 数据文件不存在');
}
$data = file_get_contents($filename);
$data = explode(PHP_EOL, $data);
$result = $data[array_rand($data)];
$result = str_replace(array("\r","\n","\r\n"), '', $result);
if($result==""){//防止获取到空值
    echo 'document.write("'."糟糕没有数据,请重新刷新一下".'");';//使用js进行调用
}else{
    echo 'document.write("'.($result).'");';//使用js进行调用
}

使用js调用

<script src="http://你的网址.com/xx.php"></script>

演示效果

↑↑↑ 刷新页面看效果

水文结束

❌
❌