好用的工具类或配置

2023-11-02

目录

通过数据库表快速生成controller,service,serviceimp,mapper,entity, 

​编辑使用Swagger快速生成文档 

通过MybatisPlus来简单实现分页查询

封装FastJsonRedisSerializer 类

配置redis的序列化

jwt工具类

封装redis类

封装相应体

 将字符串渲染到客户端

跨域配置

图片上传

图片删除

BytyBuffer的调试工具

Excel工具类 

Redisson工具类

okhttp 


通过数据库表快速生成controller,service,serviceimp,mapper,entity, 

import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.util.Collections;

public class FastAuto1GeneratorTest {
    public static void main(String[] args) {
        FastAutoGenerator.create("jdbc:mysql://127.0.0.1:3306/maku_cloud?characterEncoding=utf-8&userSSL=false", "root", "root123")
                .globalConfig(builder -> {
                    builder.author("zxb") // 设置作者
//.enableSwagger() // 开启 swagger 模式
                            .fileOverride() // 覆盖已生成文件
                            .outputDir("C:\\Users\\ThinkPad\\Desktop"); // 指定输出目录
                })
                .packageConfig(builder -> {
                    builder.parent("com.generate") // 设置父包名
                            .moduleName("bfwp-generate") // 设置父包模块名
                            .pathInfo(Collections.singletonMap(OutputFile.mapperXml, "C:\\Users\\ThinkPad\\Desktop"));
// 设置mapperXml生成路径
                })
                .strategyConfig(builder -> {
                    builder.addInclude("account_info","card_info","card_order_info","order_info","recharge_info","rf_common_config","search_record","tag_info","user_info") // 设置需要生成的表名
                            .addTablePrefix("t_", "c_"); // 设置过滤表前缀
                })
                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker
                .execute();
    }
}

使用Swagger快速生成文档 

依赖引入

   <!--引入swagger-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.7.0</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.7.0</version>
        </dependency>

 配置类

import io.swagger.annotations.ApiOperation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/*
 * 
 * 接口文档生成工具
 */
@EnableSwagger2
@Configuration
public class SwaggerConfig {
    @Bean
    public Docket productApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))  //添加ApiOperiation注解的被扫描
                .paths(PathSelectors.any())
                .build();

    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder().title("swagger和springBoot整合").description("swagger的API文档")
                .version("1.0").build();
    }

}

 通过访问http://localhost:端口/api/swagger-ui.html

通过MybatisPlus来简单实现分页查询

写 MybatisPlusConfig配置

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;

@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        // 注册拦截器
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        // 配置分页拦截器
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return mybatisPlusInterceptor;
    }
}

写查询的service

public PageDataVO getData(AccountVO accountVO) {
        // 设置分页参数
        Page<AccountInfo> page = new Page<>(accountVO.getPage(),accountVO.getLimit());
        // 查询分页数据封装到page中
        accountInfoMapper.selectPage(page, new QueryWrapper<AccountInfo>()
                // 查询条件
                .eq(!"".equals(accountVO.getUserId()) && accountVO.getUserId() != null,"user_id",accountVO.getUserId())
                .between(accountVO.getMinPointBalance() != null && accountVO.getMaxPointBalance() != null ,"point_balance",accountVO.getMinPointBalance(),accountVO.getMaxPointBalance())
                .between(accountVO.getMinPiBalance() != null && accountVO.getMaxPiBalance() != null ,"pi_balance",accountVO.getMinPiBalance(),accountVO.getMaxPiBalance())
        );
        // 封装数据
        return new PageDataVO((int)page.getTotal(), page.getRecords());
    }

封装FastJsonRedisSerializer 类

/**
 * Redis使用FastJson序列化
 * 
 * @author sg
 */
public class FastJsonRedisSerializer<T> implements RedisSerializer<T>
{

    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

    private Class<T> clazz;

    static
    {
        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
    }

    public FastJsonRedisSerializer(Class<T> clazz)
    {
        super();
        this.clazz = clazz;
    }

    @Override
    public byte[] serialize(T t) throws SerializationException
    {
        if (t == null)
        {
            return new byte[0];
        }
        return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
    }

    @Override
    public T deserialize(byte[] bytes) throws SerializationException
    {
        if (bytes == null || bytes.length <= 0)
        {
            return null;
        }
        String str = new String(bytes, DEFAULT_CHARSET);

        return JSON.parseObject(str, clazz);
    }


    protected JavaType getJavaType(Class<?> clazz)
    {
        return TypeFactory.defaultInstance().constructType(clazz);
    }
}

配置redis的序列化

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {

    @Bean
    @SuppressWarnings(value = { "unchecked", "rawtypes" })
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory)
    {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);

        FastJsonRedisSerializer serializer = new FastJsonRedisSerializer(Object.class);

        // 使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);

        // Hash的key也采用StringRedisSerializer的序列化方式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(serializer);

        template.afterPropertiesSet();
        return template;
    }
}

jwt工具类

依赖

  <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
  </dependency>

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Date;
import java.util.UUID;

/**
 * JWT工具类
 */
public class JwtUtil {

    //有效期为
    public static final Long JWT_TTL = 60 * 60 *1000L;// 60 * 60 *1000  一个小时
    //设置秘钥明文
    public static final String JWT_KEY = "sangeng";

    public static String getUUID(){
        String token = UUID.randomUUID().toString().replaceAll("-", "");
        return token;
    }
    
    /**
     * 生成jtw
     * @param subject token中要存放的数据(json格式)
     * @return
     */
    public static String createJWT(String subject) {
        JwtBuilder builder = getJwtBuilder(subject, null, getUUID());// 设置过期时间
        return builder.compact();
    }

    /**
     * 生成jtw
     * @param subject token中要存放的数据(json格式)
     * @param ttlMillis token超时时间
     * @return
     */
    public static String createJWT(String subject, Long ttlMillis) {
        JwtBuilder builder = getJwtBuilder(subject, ttlMillis, getUUID());// 设置过期时间
        return builder.compact();
    }

    private static JwtBuilder getJwtBuilder(String subject, Long ttlMillis, String uuid) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        SecretKey secretKey = generalKey();
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        if(ttlMillis==null){
            ttlMillis=JwtUtil.JWT_TTL;
        }
        long expMillis = nowMillis + ttlMillis;
        Date expDate = new Date(expMillis);
        return Jwts.builder()
                .setId(uuid)              //唯一的ID
                .setSubject(subject)   // 主题  可以是JSON数据
                .setIssuer("sg")     // 签发者
                .setIssuedAt(now)      // 签发时间
                .signWith(signatureAlgorithm, secretKey) //使用HS256对称加密算法签名, 第二个参数为秘钥
                .setExpiration(expDate);
    }

    /**
     * 创建token
     * @param id
     * @param subject
     * @param ttlMillis
     * @return
     */
    public static String createJWT(String id, String subject, Long ttlMillis) {
        JwtBuilder builder = getJwtBuilder(subject, ttlMillis, id);// 设置过期时间
        return builder.compact();
    }

    public static void main(String[] args) throws Exception {
        String token = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJjYWM2ZDVhZi1mNjVlLTQ0MDAtYjcxMi0zYWEwOGIyOTIwYjQiLCJzdWIiOiJzZyIsImlzcyI6InNnIiwiaWF0IjoxNjM4MTA2NzEyLCJleHAiOjE2MzgxMTAzMTJ9.JVsSbkP94wuczb4QryQbAke3ysBDIL5ou8fWsbt_ebg";
        Claims claims = parseJWT(token);
        System.out.println(claims);
    }

    /**
     * 生成加密后的秘钥 secretKey
     * @return
     */
    public static SecretKey generalKey() {
        byte[] encodedKey = Base64.getDecoder().decode(JwtUtil.JWT_KEY);
        SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
        return key;
    }
    
    /**
     * 解析
     *
     * @param jwt
     * @return
     * @throws Exception
     */
    public static Claims parseJWT(String jwt) throws Exception {
        SecretKey secretKey = generalKey();
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody();
    }


}

封装redis类

import java.util.*;
import java.util.concurrent.TimeUnit;

@SuppressWarnings(value = { "unchecked", "rawtypes" })
@Component
public class RedisCache
{
    @Autowired
    public RedisTemplate redisTemplate;

    /**
     * 缓存基本的对象,Integer、String、实体类等
     *
     * @param key 缓存的键值
     * @param value 缓存的值
     */
    public <T> void setCacheObject(final String key, final T value)
    {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * 缓存基本的对象,Integer、String、实体类等
     *
     * @param key 缓存的键值
     * @param value 缓存的值
     * @param timeout 时间
     * @param timeUnit 时间颗粒度
     */
    public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit)
    {
        redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
    }

    /**
     * 设置有效时间
     *
     * @param key Redis键
     * @param timeout 超时时间
     * @return true=设置成功;false=设置失败
     */
    public boolean expire(final String key, final long timeout)
    {
        return expire(key, timeout, TimeUnit.SECONDS);
    }

    /**
     * 设置有效时间
     *
     * @param key Redis键
     * @param timeout 超时时间
     * @param unit 时间单位
     * @return true=设置成功;false=设置失败
     */
    public boolean expire(final String key, final long timeout, final TimeUnit unit)
    {
        return redisTemplate.expire(key, timeout, unit);
    }

    /**
     * 获得缓存的基本对象。
     *
     * @param key 缓存键值
     * @return 缓存键值对应的数据
     */
    public <T> T getCacheObject(final String key)
    {
        ValueOperations<String, T> operation = redisTemplate.opsForValue();
        return operation.get(key);
    }

    /**
     * 删除单个对象
     *
     * @param key
     */
    public boolean deleteObject(final String key)
    {
        return redisTemplate.delete(key);
    }

    /**
     * 删除集合对象
     *
     * @param collection 多个对象
     * @return
     */
    public long deleteObject(final Collection collection)
    {
        return redisTemplate.delete(collection);
    }

    /**
     * 缓存List数据
     *
     * @param key 缓存的键值
     * @param dataList 待缓存的List数据
     * @return 缓存的对象
     */
    public <T> long setCacheList(final String key, final List<T> dataList)
    {
        Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
        return count == null ? 0 : count;
    }

    /**
     * 获得缓存的list对象
     *
     * @param key 缓存的键值
     * @return 缓存键值对应的数据
     */
    public <T> List<T> getCacheList(final String key)
    {
        return redisTemplate.opsForList().range(key, 0, -1);
    }

    /**
     * 缓存Set
     *
     * @param key 缓存键值
     * @param dataSet 缓存的数据
     * @return 缓存数据的对象
     */
    public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet)
    {
        BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
        Iterator<T> it = dataSet.iterator();
        while (it.hasNext())
        {
            setOperation.add(it.next());
        }
        return setOperation;
    }

    /**
     * 获得缓存的set
     *
     * @param key
     * @return
     */
    public <T> Set<T> getCacheSet(final String key)
    {
        return redisTemplate.opsForSet().members(key);
    }

    /**
     * 缓存Map
     *
     * @param key
     * @param dataMap
     */
    public <T> void setCacheMap(final String key, final Map<String, T> dataMap)
    {
        if (dataMap != null) {
            redisTemplate.opsForHash().putAll(key, dataMap);
        }
    }

    /**
     * 获得缓存的Map
     *
     * @param key
     * @return
     */
    public <T> Map<String, T> getCacheMap(final String key)
    {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * 往Hash中存入数据
     *
     * @param key Redis键
     * @param hKey Hash键
     * @param value 值
     */
    public <T> void setCacheMapValue(final String key, final String hKey, final T value)
    {
        redisTemplate.opsForHash().put(key, hKey, value);
    }

    /**
     * 获取Hash中的数据
     *
     * @param key Redis键
     * @param hKey Hash键
     * @return Hash中的对象
     */
    public <T> T getCacheMapValue(final String key, final String hKey)
    {
        HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
        return opsForHash.get(key, hKey);
    }

    /**
     * 删除Hash中的数据
     * 
     * @param key
     * @param hkey
     */
    public void delCacheMapValue(final String key, final String hkey)
    {
        HashOperations hashOperations = redisTemplate.opsForHash();
        hashOperations.delete(key, hkey);
    }

    /**
     * 获取多个Hash中的数据
     *
     * @param key Redis键
     * @param hKeys Hash键集合
     * @return Hash对象集合
     */
    public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys)
    {
        return redisTemplate.opsForHash().multiGet(key, hKeys);
    }

    /**
     * 获得缓存的基本对象列表
     *
     * @param pattern 字符串前缀
     * @return 对象列表
     */
    public Collection<String> keys(final String pattern)
    {
        return redisTemplate.keys(pattern);
    }
}

封装相应体


import com.fasterxml.jackson.annotation.JsonInclude;

/**
 * @Author
 */
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
public class ResponseResult<T> {
    /**
     * 状态码
     */
    private Integer code;
    /**
     * 提示信息,如果有错误时,前端可以获取该字段进行提示
     */
    private String msg;
    /**
     * 查询到的结果数据,
     */
    private T data;
}

 将字符串渲染到客户端

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class WebUtils
{
    /**
     * 将字符串渲染到客户端
     * 
     * @param response 渲染对象
     * @param string 待渲染的字符串
     * @return null
     */
    public static String renderString(HttpServletResponse response, String string) {
        try
        {
            response.setStatus(200);
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            response.getWriter().print(string);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return null;
    }
}

跨域配置

@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
      // 设置允许跨域的路径
        registry.addMapping("/**")
                // 设置允许跨域请求的域名
                .allowedOriginPatterns("*")
                // 是否允许cookie
                .allowCredentials(true)
                // 设置允许的请求方式
                .allowedMethods("GET", "POST", "DELETE", "PUT")
                // 设置允许的header属性
                .allowedHeaders("*")
                // 跨域允许时间
                .maxAge(3600);
    }
}

controller层

 @PostMapping("addProduct")
    @ApiOperation("新增商品信息")
    public ResponseVO addProduct(@RequestParam("files") MultipartFile[] file,RfAddonShopProduct rfAddonShopProduct){
        try {
            boolean flag = rfAddonShopProductService.addProduct(file,rfAddonShopProduct);
            if (!flag){
                throw new Exception();
            }
            return ResponseVO.getSuccessResponseVo("新增商品信息成功");
        }catch (Exception e){
            throw new BusinessException("新增商品数据失败,请联系后台人员");
        }

    }

 serive层

@Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addProduct(MultipartFile[] file, RfAddonShopProduct rfAddonShopProduct) {
        String string = FileUtil.uploadFileBatchReturnString(file);
        rfAddonShopProduct.setCovers(string);
        rfAddonShopProduct.setProductId(StringUtil.generateShortId());
        int result = rfAddonShopProductMapper.insert(rfAddonShopProduct);
        return result > 0;
    }

图片上传

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;


/**
 * @author: 
 * @ClassName FileUploadUtil
 * @Description 文件上传工具类
 * @date 2023/7/19 17:59
 * @Version 1.0
 */
public class FileUploadUtil {


    /**
     * 文件上传
     * @param multipartFile
     * @return 文件路径+文件名
     */
    public static String uploadFile(MultipartFile multipartFile) {
        if (multipartFile.isEmpty()) {
            throw new BusinessException("文件不能为空") ;
        }

        String fileName = multipartFile.getOriginalFilename();

        if ("".equals(fileName)) {
            return "文件名不能为空";
        }
        System.out.println("文件名: " + fileName);
        String postStr = fileName.substring(fileName.lastIndexOf("."));
        String preStr = StringUtil.generateShortId();
        fileName = preStr +  postStr;
        File readPath = new File(Constants.UPLOAD_DIR);
        if (!readPath.isDirectory()) {
            readPath.mkdirs();
        }
        System.out.println("保存路径: " + readPath);

        InputStream is = null;
        FileOutputStream os = null;
        try {
            is = multipartFile.getInputStream();
            os = new FileOutputStream(new File(readPath, fileName));

            int len = 0;
            byte[] bytes = new byte[1024];
            while ((len = is.read(bytes)) != -1) {
                os.write(bytes, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return readPath+File.separator+fileName;
    }
}

图片删除

 /**
     *删除文件
     * @param fileName 这是图片的路径
     * @return
     */
    public static boolean deleteFile(String fileName){
        File file = new File(fileName);
        //判断文件存不存在
        if(!file.exists()){
            System.out.println("删除文件失败:"+fileName+"不存在!");
            return false;
        }else{
            //判断这是不是一个文件,ps:有可能是文件夹
            if(file.isFile()){
                return file.delete();
            }
        }
        return false;
    }

BytyBuffer的调试工具

public class ByteBufferUtil {
    private static final char[] BYTE2CHAR = new char[256];
    private static final char[] HEXDUMP_TABLE = new char[256 * 4];
    private static final String[] HEXPADDING = new String[16];
    private static final String[] HEXDUMP_ROWPREFIXES = new String[65536 >>> 4];
    private static final String[] BYTE2HEX = new String[256];
    private static final String[] BYTEPADDING = new String[16];

    static {
        final char[] DIGITS = "0123456789abcdef".toCharArray();
        for (int i = 0; i < 256; i++) {
            HEXDUMP_TABLE[i << 1] = DIGITS[i >>> 4 & 0x0F];
            HEXDUMP_TABLE[(i << 1) + 1] = DIGITS[i & 0x0F];
        }

        int i;

        // Generate the lookup table for hex dump paddings
        for (i = 0; i < HEXPADDING.length; i++) {
            int padding = HEXPADDING.length - i;
            StringBuilder buf = new StringBuilder(padding * 3);
            for (int j = 0; j < padding; j++) {
                buf.append("   ");
            }
            HEXPADDING[i] = buf.toString();
        }

        // Generate the lookup table for the start-offset header in each row (up to 64KiB).
        for (i = 0; i < HEXDUMP_ROWPREFIXES.length; i++) {
            StringBuilder buf = new StringBuilder(12);
            buf.append(NEWLINE);
            buf.append(Long.toHexString(i << 4 & 0xFFFFFFFFL | 0x100000000L));
            buf.setCharAt(buf.length() - 9, '|');
            buf.append('|');
            HEXDUMP_ROWPREFIXES[i] = buf.toString();
        }

        // Generate the lookup table for byte-to-hex-dump conversion
        for (i = 0; i < BYTE2HEX.length; i++) {
            BYTE2HEX[i] = ' ' + StringUtil.byteToHexStringPadded(i);
        }

        // Generate the lookup table for byte dump paddings
        for (i = 0; i < BYTEPADDING.length; i++) {
            int padding = BYTEPADDING.length - i;
            StringBuilder buf = new StringBuilder(padding);
            for (int j = 0; j < padding; j++) {
                buf.append(' ');
            }
            BYTEPADDING[i] = buf.toString();
        }

        // Generate the lookup table for byte-to-char conversion
        for (i = 0; i < BYTE2CHAR.length; i++) {
            if (i <= 0x1f || i >= 0x7f) {
                BYTE2CHAR[i] = '.';
            } else {
                BYTE2CHAR[i] = (char) i;
            }
        }
    }

    /**
     * 打印所有内容
     * @param buffer
     */
    public static void debugAll(ByteBuffer buffer) {
        int oldlimit = buffer.limit();
        buffer.limit(buffer.capacity());
        StringBuilder origin = new StringBuilder(256);
        appendPrettyHexDump(origin, buffer, 0, buffer.capacity());
        System.out.println("+--------+-------------------- all ------------------------+----------------+");
        System.out.printf("position: [%d], limit: [%d]\n", buffer.position(), oldlimit);
        System.out.println(origin);
        buffer.limit(oldlimit);
    }

    /**
     * 打印可读取内容
     * @param buffer
     */
    public static void debugRead(ByteBuffer buffer) {
        StringBuilder builder = new StringBuilder(256);
        appendPrettyHexDump(builder, buffer, buffer.position(), buffer.limit() - buffer.position());
        System.out.println("+--------+-------------------- read -----------------------+----------------+");
        System.out.printf("position: [%d], limit: [%d]\n", buffer.position(), buffer.limit());
        System.out.println(builder);
    }

    private static void appendPrettyHexDump(StringBuilder dump, ByteBuffer buf, int offset, int length) {
        if (isOutOfBounds(offset, length, buf.capacity())) {
            throw new IndexOutOfBoundsException(
                    "expected: " + "0 <= offset(" + offset + ") <= offset + length(" + length
                            + ") <= " + "buf.capacity(" + buf.capacity() + ')');
        }
        if (length == 0) {
            return;
        }
        dump.append(
                "         +-------------------------------------------------+" +
                        NEWLINE + "         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |" +
                        NEWLINE + "+--------+-------------------------------------------------+----------------+");

        final int startIndex = offset;
        final int fullRows = length >>> 4;
        final int remainder = length & 0xF;

        // Dump the rows which have 16 bytes.
        for (int row = 0; row < fullRows; row++) {
            int rowStartIndex = (row << 4) + startIndex;

            // Per-row prefix.
            appendHexDumpRowPrefix(dump, row, rowStartIndex);

            // Hex dump
            int rowEndIndex = rowStartIndex + 16;
            for (int j = rowStartIndex; j < rowEndIndex; j++) {
                dump.append(BYTE2HEX[getUnsignedByte(buf, j)]);
            }
            dump.append(" |");

            // ASCII dump
            for (int j = rowStartIndex; j < rowEndIndex; j++) {
                dump.append(BYTE2CHAR[getUnsignedByte(buf, j)]);
            }
            dump.append('|');
        }

        // Dump the last row which has less than 16 bytes.
        if (remainder != 0) {
            int rowStartIndex = (fullRows << 4) + startIndex;
            appendHexDumpRowPrefix(dump, fullRows, rowStartIndex);

            // Hex dump
            int rowEndIndex = rowStartIndex + remainder;
            for (int j = rowStartIndex; j < rowEndIndex; j++) {
                dump.append(BYTE2HEX[getUnsignedByte(buf, j)]);
            }
            dump.append(HEXPADDING[remainder]);
            dump.append(" |");

            // Ascii dump
            for (int j = rowStartIndex; j < rowEndIndex; j++) {
                dump.append(BYTE2CHAR[getUnsignedByte(buf, j)]);
            }
            dump.append(BYTEPADDING[remainder]);
            dump.append('|');
        }

        dump.append(NEWLINE +
                "+--------+-------------------------------------------------+----------------+");
    }

    private static void appendHexDumpRowPrefix(StringBuilder dump, int row, int rowStartIndex) {
        if (row < HEXDUMP_ROWPREFIXES.length) {
            dump.append(HEXDUMP_ROWPREFIXES[row]);
        } else {
            dump.append(NEWLINE);
            dump.append(Long.toHexString(rowStartIndex & 0xFFFFFFFFL | 0x100000000L));
            dump.setCharAt(dump.length() - 9, '|');
            dump.append('|');
        }
    }

    public static short getUnsignedByte(ByteBuffer buffer, int index) {
        return (short) (buffer.get(index) & 0xFF);
    }
}

Excel工具类 

需要导入依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.2.6</version>
</dependency>

 工具类

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.support.ExcelTypeEnum;
import org.apache.poi.ss.formula.functions.T;
import java.util.LinkedList;
import java.util.List;
 
/**
 * @author wzx
 */
public class ExcelUtil {
 
 
    /**
     * 封装Excel中的数据到指定的实体类中
     * @param typeClass 指定的实体类的字节码类别
     * @param readPath Excel的文件路径
     * @return 指定的实体类对象的集合(每个对象代表每一条数据)
     */
    public static List<T> getDataFromExcel(Class<T> typeClass , String readPath){
        List<T> list = new LinkedList<>();
        EasyExcel.read(readPath)
                .head(typeClass)
                .sheet()
                .registerReadListener(new AnalysisEventListener<T>() {
 
                    @Override
                    public void invoke(T excelData, AnalysisContext analysisContext) {
                        list.add(excelData);
                    }
 
                    @Override
                    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
                        System.out.println("数据读取完毕");
                    }
                }).doRead();
        return list;
    }
 
    /**
     * 将封装好的数据写入Excel中
     * @param list 写入的数据集合
     * @param writePath 写入的Excel文件的路径
     * @param sheet excel表中生成的sheet表名
     * @param excelType 插入的excel的类别,有xls、xlsx两种
     */
    public static <T> void saveDataToExcel(List<T> list, String writePath, String sheet, ExcelTypeEnum excelType, Class<T> clazz) {
        // 写入Excel文件
        EasyExcel.write(writePath)
                .head(clazz)
                .excelType(excelType)
                .sheet(sheet)
                .doWrite(list);
    }
}

Redisson工具类

引入依赖

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.13.6</version>
</dependency>

配置redisson的配置类

@Configuration

public class RedisConfig {
    @Bean
    public RedissonClient redissonClient() {
        // 配置类
        Config config = new Config();
        // 添加redis地址,这里添加了单点的地址,也可以使用config.useClusterServers()添加集群地址 

        config.useSingleServer().setAddress("redis://192.168.150.101:6379").setPassowrd("123321");
        // 创建客户端
        return Redisson.create(config);
    }

}

使用

@Resource
private RedissonClient redissonClient;



@Test
void testRedisson() throws InterruptedException {

    // 获取锁(可重入),指定锁的名称
    RLock lock = redissonClient.getLock("anyLock"); 

    // 尝试获取锁,参数分别是:获取锁的最大等待时间(期间会重试),锁自动释放时间,时间单位

    boolean isLock = lock.tryLock(1, 10, TimeUnit.SECONDS);
    // 判断释放获取成功
    if(isLock){

        try {

            System.out.println("执行业务");

        }finally {

            // 释放锁
            lock.unlock();

        }

    }

}

调用配置类的时候,我们可以选择该redisson的服务对象是单体服务器还是集群,单体的服务方法为.useSingleServer(),集群的服务方法为useClusterServers()

okhttp 

依赖

<dependency>
   <groupId>com.squareup.okhttp3</groupId>
   <artifactId>okhttp</artifactId>
   version>4.10.0-RC1</version>
</dependency>

使用

 OkHttpClient client = new OkHttpClient();
                    Request request = new Request.Builder()
                    .url("https://api.minepi.com/v2/me")
                    .addHeader("Authorization", "Bearer " + loginDTOTmp.getAccessToken())
                    .build();
            try (Response response = client.newCall(request).execute()) {
                if (!response.isSuccessful()) {
                    return null;
                }
                String string = response.body().string();
                // 响应体
                JSONObject jsonObject1 = JSON.parseObject(string);

                if (!jsonObject1.getString("username").equals(userName)) {
                    return null;
                }

                 
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

好用的工具类或配置 的相关文章

  • 如何解析比 Java 中 NumberFormat 更严格的数字?

    我正在验证表单中的用户输入 我解析输入NumberFormat http docs oracle com javase 7 docs api java text NumberFormat html 但它是邪恶的 几乎允许任何事情 有没有办法
  • UiBinder 中的 gwt 按钮

    我需要创建一个按钮 所以它是一个带有图像的按钮 gwt with UiBinder 但我不确定如何进行 这是我的ui xml code
  • 在 Eclipse 中导航 Java 调用堆栈

    在调试器中像GDB http sources redhat com gdb 当您在断点处停止时 您可以轻松地向上移动调用堆栈并检查相关的源和堆栈帧数据 在 Eclipse 中如何做到这一点 In the 调试视角 http www ibm
  • Hibernate HQL 查询:如何将集合设置为查询的命名参数?

    给定以下 HQL 查询 FROM Foo WHERE Id id AND Bar IN barList I set id使用查询对象的setInteger 方法 我想设置 barList用一个List对象 但查看 Hibernate 文档和
  • 用dagger 2查看依赖注入

    我有一个自定义视图扩展TextView 我应该在哪里调用我的组件来注入视图 component inject customTextView 因此 我发现我需要在自定义视图的构造函数中添加注入 在所有视图中 或者使一个调用另一个 Exampl
  • 用 Java 捕获扬声器输出

    使用Java可以捕获扬声器输出吗 此输出不是由我的程序生成的 而是由其他正在运行的应用程序生成的 这可以用 Java 完成还是我需要求助于 C C 我有一个基于 Java 的应用程序 使用过的爪哇声音 https stackoverflow
  • 摆动刷新周期

    我试图了解何时使用重新验证 重绘 打包 令人惊讶的是 我没有找到详细的底层文档 请随意链接 到目前为止我已经明白这都是 RepaintManager 的责任 油漆 重新油漆指的是脏 干净的东西 pack validate revalidat
  • 在 jFrame 中启用右键单击

    嘿 我正在寻找如何使用 NetBeans 在 jFrame 中启用 仅且仅 右键单击并显示弹出菜单 使用我的代码 private void formMouseClicked java awt event MouseEvent evt pop
  • Hibernate3:自引用对象

    需要一些帮助来了解如何执行此操作 我将在文件系统上运行递归 查找 并且希望将信息保留在单个数据库表中 具有自引用的层次结构 这是我想要填充的数据库表结构 目录对象表 id int NOT NULL name varchar 255 NOT
  • 根据结果​​重试方法(而不是异常)

    我有一个具有以下签名的方法 public Optional
  • 如何在 apache poi 中找到包含图片的单元格

    我尝试在 xls 文档中循环图像 我写下一个代码 HSSFPatriarch patriarch sheet getDrawingPatriarch if patriarch null Loop through the objects fo
  • 为什么 Libgdx 的 Table 不接受缩放操作?

    我在 libgdx 库中使用 scene2d 在游戏中创建一些 UI 我使用了一个表格 我想在用户触摸时采取一些缩放操作以使按钮触摸有意义 当我使用任何其他 Actor 类型 例如 Group 并为其提供缩放操作时 它可以工作 但不能工作表
  • Java字符串中的字符数[重复]

    这个问题在这里已经有答案了 可能的重复 Java 使用unicode上划线显示平方根时字符串的长度 https stackoverflow com questions 7704426 java length of string when u
  • Spring @Configuration如何缓存对bean的引用

    使用基于 Java 的配置时 Spring 如何防止再次调用 bar 我想知道编译时注释处理或通过代理方法 Configuration public class AppConfig Bean public Foo foo return ne
  • Hive NVL 不适用于列的日期类型 - NullpointerException

    我正在使用 HDFS 上的 MapR Hive 发行版并面临以下问题 如果表的列类型是 日期 类型 则NVL https cwiki apache org confluence display Hive LanguageManual UDF
  • bean 中的 Spring JavaConfig 属性未设置?

    我正在考虑将 Spring JavaConfig 与一些属性文件一起使用 但 bean 中的属性未设置 bean 中的属性未设置 这是我的网络配置 Configuration EnableWebMvc PropertySource valu
  • 在 Java Web 应用程序中获取 DataSource 资源

    我的 context xml 文件中有以下资源标记
  • Ant 类路径和 junit.jar

    我有一个 build xml 它允许我运行 junit 测试 这是相关部分
  • 如何使用 JRE 部署 JavaFX 11 桌面应用程序

    我有一个 JavaFX JDK 8 桌面业务应用程序 它使用 Java Web Start 进行部署 用户安装了 Java 8 只需访问 URL 我的 AWS Linux 服务器上的公共 URL 即可下载 启动应用程序 使用 Web Sta
  • 如何获取 EC2 实例的 CloudWatch 指标数据

    我想获取我的 EC2 实例的 Cloudmetrics 数据 以便我可以使用这些数据绘制图表并将其显示在我的 Android 设备上 我怎么做 有相同的示例程序或教程吗 提前致谢 这就是我正在做的 private static void f

随机推荐

  • 腾讯QQ Web Service 接口

    导读 腾讯QQ在线状态 WEB 服务 Endpoint http www webxml com cn webservices qqOnlineWebService asmx Disco http www webxml com cn webs
  • 在家就可以做的三个冷门副业,时间自由,零基础也可轻松上手

    大多数人感到困惑的原因本质上是他们没有计划和设定自己的职业目标 从现在开始保持自律 学会认真完成每一件小事 一步一步地完成它 你可以一起解决你的困惑 今天和大家分享 蝶衣王 VIP栏目发布的三个小项目可以在家里做 一 抄书 简单到有手 就是
  • java学习笔记(面试必备)

    1 java的四大特性 抽象 继承 封装 多态 抽象的概念 这里我先补充一下对象的概念 在java中世界万物皆对象 对象就是客观存在的事物 比如一个人 一支笔 而抽象就是将对象的某些细节和特征抽取出来 用程序代码表示 抽取出来的东西一般我们
  • 【计算机网络】因特网的组成

    从因特网的工作方式上看 可以划分为两大部分 1 边缘部分 由所有连接在因特网上的主机组成 这部分是用户直接使用的 用来进行通信 传送数据 音频或视频 和资源共享 2 核心部分 由大量网络和连接这些网络的路由器组成 这部分是为边缘部分提供服务
  • MySQL left join 和 left outer join 区别

    先说结论 left join 和 left outer join 的结果是一致的 我不知道各位大神是怎么测试的 网上面就说两个不一样 我A B表都是有重复数据的 为啥结果是一样的 表A 表B 左连接 SELECT ta tb Result
  • c++之 vector 容器

    1 vector存放内置数据类型 特点 是一种单端数组 可以动态扩展 动态扩展 不是在原有空间后边续接新的空间 而是寻找更大的内存 将原数据拷贝到新的空间 然后释放原空间 include
  • 利用git 将本地项目上传到github上

    利用git 将本地项目上传到github上 在github上创建仓库后 也链接了ssh 在本地项目的文件夹下git bash here然后 git init 项目初始化 git add 将项目加入本地暂存区 git commit m 项目注
  • Hive SQL语法报错 及相应解决方法

    Hive SQL语法与经常用的mysql语法具有一定差异性 按照写mysql的习惯写出的sql经常报错 且报错很难看出问题原因 因此在此记录出现问题的现象和解决方式 Error Error while compiling statement
  • String类中重写Object中的equals方法源码解析

    一 Object类中的equals方法 public boolean equals Object obj return this obj 由上面的代码可以看出 Object类中的equals方法比较的是地址 注意 对于引用类型比较的是地址
  • 如何使用webmagic发送post请求,并解析传回的JSON

    以浙江法院公开网的送达公告数据为例 http www zjsfgkw cn TrialProcess NoticeSDList 1 分析页面 看到参数有3个 分别是cbfy pageno和pagesize 传回来的数据是以json形式存在
  • 解决哈希(HASH)冲突的主要方法

    虽然我们不希望发生冲突 但实际上发生冲突的可能性仍是存在的 当关键字值域远大于哈希表的长度 而且事先并不知道关键字的具体取值时 冲突就难免会发 生 另外 当关键字的实际取值大于哈希表的长度时 而且表中已装满了记录 如果插入一个新记录 不仅发
  • vue router连续点击多次路由报错根本原因和解决方法

    原因 vue router 升级到 3 1 x 后 重复点击导航时 控制台出现报错 vue router v3 1 后 回调形式改成 promise api 了 返回的是 promise 如果没有捕获到错误 控制台始终会出现警告 解决方法
  • windows 11部署wsl环境

    部署WSL2环境 Ubuntu Centos有巨坑 建议不要安装 docker等使用会出问题 一 安装基础服务 首先需要先安装WSL WIN11直接打开powershell或者cmd输入 wsl install install 命令执行以下
  • AndroidStudio Grade 7.0 Maven搭建

    在组件化项目架构中每个组件管理我们一般使用分仓库管理 每个组件分别打包成aar包引入项目依赖 老版本 gradle 我们一般使用 maven 插件来上传aar包 而 Gradle 6 x 版本更新了上传插件为 maven publish 低
  • 仿二手车之家下拉列表

    效果展示 基础知识 认识 ViewDragHelper 类 和我们上次在这篇文章 仿QQ6 0主页面侧滑效果 第二种实现方法 中所讲的 GestureDetector 类一样 ViewDragHelper类也是系统给我们提供的 一种处理用户
  • PHP之伪协议

    前言 伪协议是什么 PHP伪协议事实上就是支持的协议与封装协议 ctf中的文件包含 文件读取的绕过 正则的绕过等等会需要用到 那伪协议有哪些 file data gopher php 等等 下面会讲 PHP伪协议 file 协议 本地文件传
  • 基于NodeJS的14款Web框架

    在几年的时间里 Node js逐渐发展成一个成熟的开发平台 吸引了许多开发者 有许多大型高流量网站都采用Node js进行开发 像PayPal 此外 开发人员还可以使用它来开发一些快速移动Web框架 下面就介绍14款基于Node js的We
  • 一些简单的C#语句的高级写法

    在C 的开发中 我们常常使用Debug Log来输出我们需要的信息 但是使用这个语句同时也会浪费一些内存 例如 我设计一个游戏角色的名称 血量 等级以及经验 string strName 游戏主角 int Hp 100 int Level
  • IC后端实现训练营实战项目案例 _ se

    IC后端实现训练营实战项目案例 setup violation高达50ns 文章右侧广告为官方硬广告 与吾爱IC社区无关 用户勿点 点击进去后出现任何损失与社区无关 一转眼一年就过去了 今年你过的还好吗 有没有遇到生命中的贵人呢 如果有 请
  • 好用的工具类或配置

    目录 通过数据库表快速生成controller service serviceimp mapper entity 编辑使用Swagger快速生成文档 通过MybatisPlus来简单实现分页查询 封装FastJsonRedisSeriali