一个非常非常非常简单的SpringBoot小项目by hazy

base:这个我用来入门SpringBoot的一个小项目,只注重如何把功能做出来并在这个过程练习一下使用SpringBoot

网站具体的功能是:代码分享。分享者将分享的代码和口令填入网站中进行分享,被分享者可以使用口令或是网址进行代码的查看,功能基本和Ubuntu Paste(https://paste.ubuntu.com/)这个网站一致。

使用的技术栈有:SpringBoot、Redis、Mysql

步骤一:搭建SpringBoot项目

此步骤只需按照图片搭建或是自行搭建即可
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

文件结构大致如下图。创建一个baseController类,测试SpringBoot是否正常工作

在这里插入图片描述

@RestController
@RequestMapping("")
public class baseController {
    @RequestMapping("hello")
    public String hello(){
        return "hello";
    }
}

在这里插入图片描述

步骤二:整合Redis

首先安装一个Redis,并启动服务、测试

接下来进行SpringBoot和Redis的整合

<!-- pom.xml -->
        <!--jedis依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <!--<artifactId>spring-boot-starter-redis</artifactId>-->
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>

在com.hazy.codeshare下新建一个config包,并新建一个RedisConfig类,作为redis的配置类

@Configuration
@PropertySource("classpath:redis.properties")
public class RedisConfig {
    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Value("${spring.redis.timeout}")
    private int timeout;

    @Value("${spring.redis.jedis.pool.max-idle}")
    private int maxIdle;

    @Value("${spring.redis.jedis.pool.max-wait}")
    private long maxWaitMillis;

//    @Value("${spring.redis.password}")

    private String password;

    @Value("${spring.redis.block-when-exhausted}")
    private boolean  blockWhenExhausted;

    @Bean
    public JedisPool redisPoolFactory()  throws Exception{
//        log.info("JedisPool注入成功!!");
//        log.info("redis地址:" + host + ":" + port);
        System.out.println("JedisPool注入成功!!");
        System.out.println("redis地址:" + host + ":" + port);
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
        // 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true
        jedisPoolConfig.setBlockWhenExhausted(blockWhenExhausted);
        // 是否启用pool的jmx管理功能, 默认true
        jedisPoolConfig.setJmxEnabled(true);
        JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password);
        return jedisPool;
    }
}

与此同时,要写一个Redis的配置文件:在resources目录下新建一个redis.properties,写入基本的redis配置

#redis配置开始
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=localhost
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
# spring.redis.password=123456
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=1024
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=10000
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=200
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=10000
#redis配置结束
spring.redis.block-when-exhausted=true

接下来,可以进行一次测试,启动项目,如果控制台出现redis注入成功就说明redis已经注册成为一个Bean(但不意味着已经可以正常使用)

为了后续方便使用,在com.hazy.codeshare新建一个utils包,并新建一个RedisUtil类(为了方便使用,已经把日志去掉改为控制台输出)这里只有最基本的字符串的set、get和exist功能,可以作为参考

package com.hazy.codeshare.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

@Component
public class RedisUtil {
    @Autowired
    private JedisPool jedisPool;

    /**
     * 返还到连接池
     *
     * @param jedisPool
     * @param jedis
     */
    public static void returnResource(JedisPool jedisPool, Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }

    public String set(String key, String value,int indexdb) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.select(indexdb);
            return jedis.set(key, value);
        } catch (Exception e) {
            System.out.println(e.getMessage());
//            log.error(e.getMessage());
            return "0";
        } finally {
            returnResource(jedisPool, jedis);
        }
    }
    /**
     * <p>
     * 通过key获取储存在redis中的value
     * </p>
     * <p>
     * 并释放连接
     * </p>
     *
     * @param key
     * @param indexdb 选择redis库 0-15
     * @return 成功返回value 失败返回null
     */
    public String get(String key,int indexdb) {
        Jedis jedis = null;
        String value = null;
        try {
            jedis = jedisPool.getResource();
            jedis.select(indexdb);
            value = jedis.get(key);
//            log.info(value);
        } catch (Exception e) {
            System.out.println(e.getMessage());
//            log.error(e.getMessage());
        } finally {
            returnResource(jedisPool, jedis);
        }
        return value;
    }

    /**
     * 通过key判断redis中是否有该key
     * 并释放连接
     * @param key
     * @param indexdb 选择redis库 0-15
     * @return 成功返回value 失败返回null
     */
    public boolean exists(String key,int indexdb) {
        Jedis jedis = null;
        boolean exist = false;
        try {
            jedis = jedisPool.getResource();
            jedis.select(indexdb);
            exist = jedis.exists(key);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            returnResource(jedisPool, jedis);
        }
        return exist;
    }
}

步骤三:编写前端界面(建议直接复制使用或是自己根据后续的路由去编写)
在这里插入图片描述

在resources的static目录下新建一个index.html(可以直接被映射)代码如下:

其中,bootstrap最好下载一个,但不是必须。jquery是必须的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/bootstrap/css/bootstrap.min.css">
    <script type="text/javascript" src="/bootstrap/js/jquery3.5.js"></script>
    <script type="text/javascript" src="/bootstrap/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="/css/index.css">
    <script type="text/javascript" src="/js/index.js"></script>
</head>
<body>
<div class=".container">
    <div class="row">
    <div class="col-md-4 col-md-offset-4">
        <div class="main-form well">
            <div class="form-group">
                <label>口令</label>
                <input class="form-control" type="text" name="shareKey" id="shareKey"/>
                <span id="shareKey-help" class="help-block"></span>
            </div>
            <div class="form-group">
                <label>请输入代码</label>
                <textarea class="form-control" rows="20" name="codeContext" id="codeContext"></textarea>
                <span id="codeContext-help" class="help-block"></span>
            </div>
            <div class="form-group">
                <input id="submit-btn" class="btn btn-primary" type="button" value="分享/查询"/>
            </div>

            <div class="form-group">
                选择分享时长:<select class="form-control" id="shareDuration">
                    <option>临时</option>
                    <option>永久</option>
                </select>
            </div>
        </div>
    </div>
    </div>
</div>
</body>
</html>

index.js代码如下:

$(function () {
    if(window.location.search != "") {
        shareKey = window.location.search.substring(1);
        $.get({
            url:"/code-share/" + shareKey,
            success:function (codeContext_return) {
                clearMsg();
                if(codeContext_return.code == 200) {
                    $("#shareKey-help").text(codeContext_return.msg);
                    $("#shareKey").parent("div").addClass("has-success");
                    $("#shareKey").val(shareKey);
                    $("#codeContext").val(codeContext_return.body.shareKey);
                }
                else {
                    $("#shareKey").parent("div").addClass("has-error");
                    $("#shareKey-help").text(codeContext_return.msg);
                }

            }
        });
    }

    function clearMsg() {
        $("#shareKey").parent("div").removeClass("has-error has-success");
        $("#shareKey-help").empty();
        $("#codeContext").parent("div").removeClass("has-error has-success");
        $("#codeContext-help").empty();
    }

    //提交按钮的功能:判断口令是否为空;判断代码是否为空
    $("#submit-btn").click(function () {
        clearMsg();

        var shareKey = $("#shareKey").val();
        if(shareKey == "") {
            $("#shareKey").parent("div").addClass("has-error");
            $("#shareKey").next("span").text("口令不能为空");
        }
        var codeContext = $("#codeContext").val();
        if($("#shareDuration").val() == "临时")
            var shareDuration = "temp";
        else
            var shareDuration = "permanent";
        if(codeContext == "") {
            $.get({
                url:"/code-share/" + shareKey,
                success:function (codeContext_return) {
                    clearMsg();
                    if(codeContext_return.code == 200) {
                        $("#shareKey-help").text(codeContext_return.msg);
                        $("#shareKey").parent("div").addClass("has-success");
                        $("#codeContext").val(codeContext_return.body.shareKey);
                    }
                    else {
                        $("#shareKey").parent("div").addClass("has-error");
                        $("#shareKey-help").text(codeContext_return.msg);
                    }

                }
            });
        }
        else {
            $.post({
                url:"/code-share/" + shareKey,
                data:{codeContext:codeContext, shareDuration:shareDuration},
                success:function (result) {
                    if(result.code == 200)
                        $("#codeContext-help").text("存储完毕!请把口令或者把 " + window.location.host + "/?" + result.body.shareKey + " 复制给您的好友~");
                    else
                        $("#shareKey-help").text(result.msg);
                }
            });
        }
    });

    //ajax检查口令是否存在
    $("#shareKey").change(function () {
        clearMsg();
        if($(this).val() == "") return ;
        $.get({
            url:'/check-code-exist/' + $("#shareKey").val(),
            success:function (result) {
               if(result.code == 400) {
                   $("#shareKey").parent("div").addClass("has-error");
                   $("#shareKey-help").text(result.msg);
               }
               else {
                   $("#shareKey").parent("div").addClass("has-success");
               }
            }
        });

    });
});

写完之后可以进行测试是否能正常访问index页面,各种功能是否能正常使用

步骤四:为了返回信息的统一,创建一个返回信息类

在pojo包下新建一个Msg类

package com.hazy.codeshare.pojo;

import java.util.HashMap;
import java.util.Map;

/**
 * @version 1.0
 * @Author yd
 * @Date 2020/11/19 21:10
 * @TODO function
 */
public class Msg {
    private Msg(){};

    private Msg(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }
	//信息的代码:200成功 400失败
    private int code;
    //返回信息的提示
    private String msg;
    //返回的信息
    private Map<String, Object> body = null;

    //成功返回代码200
    public static Msg success(String msg) {
        return new Msg(200, msg);
    }
    //失败返回代码400
    public static Msg fail(String msg) {
        return new Msg(400, msg);
    }

    //可链式添加
    public Msg add(String key, Object value) {
        if(body == null) {
            body = new HashMap<>();
        }
        body.put(key, value);
        return this;
    }

    //以下是一系列get、set、tostring方法
}

步骤五:整合mybatis

首先把application.properties删掉,换成application.yml,并写入以下配置

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/codeshare?useUnicode=true&characterEncoding=UTF-8
    username: root
    password: 换成你的密码
    driver-class-name: com.mysql.jdbc.Driver
mybatis:
  type-aliases-package: com.hazy.codeshare.dao
  configuration:
    map-underscore-to-camel-case: true

并引入依赖:

 <!--    整合mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency> <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>

此时,需要在mysql中新建库、表
在这里插入图片描述

与此对应,需要有一个pojo类:CodeShare

package com.hazy.codeshare.pojo;

import java.sql.Date;

public class CodeShare {
    private int id;
    private String shareKey;
    private String filePath;
    private String codeContext;
    private Date shareTime;

    public CodeShare() {
    }

    public CodeShare(String shareKey, String filePath) {
        this.shareKey = shareKey;
        this.filePath = filePath;
    }

  //一系列get、set、tostring方法
}

和操作数据库的mapper:com.hazy.codeshare.dao.CodeMapper

public interface CodeMapper {
    public CodeShare selectByShareKey(String shareKey);
    public int insert(CodeShare codeShare);
    public int deleteByShareKey(String shareKey);
}

在dao包下写一个Mapper.XML 文件,与CodeMapper同名

<?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.hazy.codeshare.dao.CodeMapper">

    <resultMap id="CodeShareResultMap" type="com.hazy.codeshare.pojo.CodeShare" >
        <id column="id" property="id" jdbcType="INTEGER" />
        <result column="share_key" property="shareKey" jdbcType="VARCHAR" />
        <result column="file_path" property="filePath" jdbcType="VARCHAR" />
        <result column="share_time" property="shareTime" jdbcType="VARCHAR" />
    </resultMap>

    <select id="selectByShareKey" resultType="com.hazy.codeshare.pojo.CodeShare" resultMap="CodeShareResultMap">
        select `id`, `share_key`, `file_path`, `share_time` from code where share_key = #{shareKey}
    </select>

    <insert id="insert" parameterType="com.hazy.codeshare.pojo.CodeShare">
        insert into code(`share_key`, `file_path`, `share_time`) values(#{shareKey}, #{filePath}, CURDATE())
    </insert>

    <delete id="deleteByShareKey" >
        delete from code where `share_key` = #{shareKey}
    </delete>

</mapper>

并且!在你的主运行程序Application上增加一个注解:

@SpringBootApplication
@MapperScan("com.hazy.codeshare.dao")//增加此注解
public class CodeshareApplication {

    public static void main(String[] args) {
        SpringApplication.run(CodeshareApplication.class, args);
    }
}

步骤六:编写controller

package com.hazy.codeshare.controller;

import com.hazy.codeshare.dao.CodeMapper;
import com.hazy.codeshare.pojo.CodeShare;
import com.hazy.codeshare.pojo.Msg;
import com.hazy.codeshare.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.*;

@RestController
@RequestMapping("")
public class baseController {
	//注入redis工具类
    @Autowired
    private RedisUtil redisUtil;
	
	//注入mapper
    @Autowired
    private CodeMapper codeMapper;

	//当请求为get时说明是查询请求
    @GetMapping("/code-share/{shareKey}")
    public Msg getCodeContext(@PathVariable("shareKey") String shareKey){
        String codeContext = redisUtil.get(shareKey, 0);
        if(codeContext != null)
            return Msg.success("查询成功!").add("shareKey", codeContext);
        else {
            String src = "./file/" + shareKey + ".txt";
            File file = new File(src);
            if(!file.exists()) return Msg.fail("该口令不存在");
            FileReader fileReader;
            BufferedReader br = null;
            try {
                fileReader = new FileReader(file);
                br = new BufferedReader(fileReader);
                StringBuilder sb = new StringBuilder();
                String temp;
                while ((temp = br.readLine()) != null) {
                    // 拼接换行符
                    sb.append(temp + "\n");
                }
                String js = sb.toString();
                redisUtil.set(shareKey, js, 0);
                return Msg.success("查询成功!").add("shareKey", js);
            }catch (Exception e) {
                System.out.println(e.getMessage());
            } finally {
                if(br != null)
                    try {
                        br.close();
                    }catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
            }
            return Msg.fail("该口令不存在");
        }


    }
	//当请求为post时说明是上传请求
    @PostMapping("/code-share/{shareKey}")
    public Msg storeCodeContext(@PathVariable("shareKey") String shareKey, @RequestParam("codeContext") String codeContext, @RequestParam("shareDuration")String shareDuration) {
        if("".equals(shareKey))
            return Msg.fail("口令为空!");
        if("".equals(codeContext))
            return Msg.fail("代码为空!");
        if(redisUtil.get(shareKey,0) != null)
            return Msg.fail("口令已被使用!");
        try {
            redisUtil.set(shareKey, codeContext, 0);
            if("permanent".equals(shareDuration)) {
                String filePath = "./file/";
                File file = new File(filePath);
                if(!file.exists()) {
                    file.mkdirs();
                }
                filePath = filePath + shareKey + ".txt";
                BufferedWriter bw = new BufferedWriter(new FileWriter(filePath));
                bw.write(codeContext);
                bw.close();
                codeMapper.insert(new CodeShare(shareKey, filePath));
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return Msg.fail("代码存入失败!");
        }
        return Msg.success("保存成功,请分享给您的朋友~").add("shareKey", shareKey);
    }
	//检查code是否已被占用
    @GetMapping("/check-code-exist/{shareKey}")
    public Msg checkCodeExist(@PathVariable("shareKey") String shareKey){
        if("".equals(shareKey))
            return Msg.fail("shareKey为空");
        boolean exist = redisUtil.exists(shareKey, 0);
        if(exist)
            return Msg.fail("shareKey已经存在!").add("shareKey", redisUtil.get(shareKey, 0));
        else
            return Msg.success("shareKey可以使用!");
    }
}

测试!完毕!

看到这里,其实你可以依照这个需求,自己写一个相似的网站。因为本人的水平非常差,只是刚看了点SpringBoot的皮毛,想着练习一下,才给自己想了一个需求。如果对你有帮助,那就再好不过。如果没有帮助,可以试着抛开我的代码自己写一个类似的网站!

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值