commit
a865ed59c2
42 changed files with 2981 additions and 0 deletions
@ -0,0 +1,42 @@ |
|||||
|
package com.qs.cost; |
||||
|
|
||||
|
import org.springframework.boot.SpringApplication; |
||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||
|
import org.springframework.boot.builder.SpringApplicationBuilder; |
||||
|
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; |
||||
|
import org.springframework.scheduling.annotation.EnableScheduling; |
||||
|
import org.springframework.transaction.annotation.EnableTransactionManagement; |
||||
|
|
||||
|
import javax.annotation.PostConstruct; |
||||
|
import javax.servlet.ServletContext; |
||||
|
import javax.servlet.ServletException; |
||||
|
import java.util.TimeZone; |
||||
|
|
||||
|
/** |
||||
|
* @author USER |
||||
|
*/ |
||||
|
@EnableScheduling |
||||
|
@EnableTransactionManagement |
||||
|
@SpringBootApplication |
||||
|
public class Application extends SpringBootServletInitializer { |
||||
|
|
||||
|
public static void main(String[] args) { |
||||
|
SpringApplication.run(Application.class,args); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onStartup(ServletContext servletContext) throws ServletException { |
||||
|
super.onStartup(servletContext); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { |
||||
|
return builder.sources(Application.class); |
||||
|
} |
||||
|
|
||||
|
@PostConstruct |
||||
|
void started() { |
||||
|
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai")); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,19 @@ |
|||||
|
package com.qs.cost.common.conf; |
||||
|
|
||||
|
import org.springframework.cache.annotation.EnableCaching; |
||||
|
import org.springframework.cache.concurrent.ConcurrentMapCacheManager; |
||||
|
import org.springframework.context.annotation.Bean; |
||||
|
import org.springframework.context.annotation.Configuration; |
||||
|
|
||||
|
@EnableCaching |
||||
|
@Configuration |
||||
|
public class CacheConfig { |
||||
|
|
||||
|
@Bean |
||||
|
public ConcurrentMapCacheManager cacheManager() { |
||||
|
ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager(); |
||||
|
//cacheManager.setStoreByValue(true); //true表示缓存一份副本,否则缓存引用
|
||||
|
return cacheManager; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,28 @@ |
|||||
|
package com.qs.cost.common.conf; |
||||
|
|
||||
|
import com.fasterxml.jackson.annotation.JsonInclude; |
||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; |
||||
|
import org.springframework.context.annotation.Bean; |
||||
|
import org.springframework.context.annotation.Configuration; |
||||
|
import org.springframework.context.annotation.Primary; |
||||
|
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; |
||||
|
|
||||
|
/** |
||||
|
* @Author: YenHex |
||||
|
* @Date: 2021/3/11 |
||||
|
* @Version: 1.0 |
||||
|
**/ |
||||
|
@Slf4j |
||||
|
@Configuration |
||||
|
public class JacksonConfig { |
||||
|
@Bean |
||||
|
@Primary |
||||
|
@ConditionalOnMissingBean(ObjectMapper.class) |
||||
|
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) { |
||||
|
ObjectMapper objectMapper = builder.createXmlMapper(false).build(); |
||||
|
objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS); |
||||
|
return objectMapper; |
||||
|
} |
||||
|
} |
@ -0,0 +1,27 @@ |
|||||
|
package com.qs.cost.common.conf; |
||||
|
|
||||
|
import lombok.Getter; |
||||
|
import lombok.Setter; |
||||
|
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* @author YenHex |
||||
|
* @since 2022/7/7 |
||||
|
*/ |
||||
|
|
||||
|
@Getter |
||||
|
@Setter |
||||
|
@Component |
||||
|
@ConfigurationProperties(prefix = "server") |
||||
|
public class MainServerProperties { |
||||
|
|
||||
|
private String host; |
||||
|
|
||||
|
private String book; |
||||
|
|
||||
|
private String year; |
||||
|
|
||||
|
private String u8url; |
||||
|
|
||||
|
} |
@ -0,0 +1,40 @@ |
|||||
|
package com.qs.cost.common.conf; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; |
||||
|
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.mybatis.spring.annotation.MapperScan; |
||||
|
import org.springframework.context.annotation.Bean; |
||||
|
import org.springframework.context.annotation.Configuration; |
||||
|
import org.springframework.transaction.annotation.EnableTransactionManagement; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* @Author: YenHex |
||||
|
* @Date: 2021/3/4 |
||||
|
* @Version: 1.0 |
||||
|
**/ |
||||
|
@Slf4j |
||||
|
@Configuration |
||||
|
@EnableTransactionManagement |
||||
|
@MapperScan({ |
||||
|
"com.qs.cost.module.mapper", |
||||
|
}) |
||||
|
public class MyBatisConfig { |
||||
|
|
||||
|
|
||||
|
@Bean |
||||
|
public MybatisPlusInterceptor mybatisPlusInterceptor() { |
||||
|
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); |
||||
|
// 添加防止全表更新与删除拦截器
|
||||
|
interceptor.addInnerInterceptor(blockAttackInnerInterceptor()); |
||||
|
return interceptor; |
||||
|
} |
||||
|
|
||||
|
public BlockAttackInnerInterceptor blockAttackInnerInterceptor(){ |
||||
|
BlockAttackInnerInterceptor blockAttackInnerInterceptor=new BlockAttackInnerInterceptor(); |
||||
|
return blockAttackInnerInterceptor; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,47 @@ |
|||||
|
package com.qs.cost.common.conf; |
||||
|
|
||||
|
import lombok.AllArgsConstructor; |
||||
|
import org.springframework.context.annotation.Bean; |
||||
|
import org.springframework.context.annotation.Configuration; |
||||
|
import org.springframework.web.cors.CorsConfiguration; |
||||
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource; |
||||
|
import org.springframework.web.filter.CorsFilter; |
||||
|
import org.springframework.web.multipart.MultipartResolver; |
||||
|
import org.springframework.web.multipart.commons.CommonsMultipartResolver; |
||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
||||
|
|
||||
|
/** |
||||
|
* @author YenHex |
||||
|
* @since 2022/2/24 |
||||
|
*/ |
||||
|
@AllArgsConstructor |
||||
|
@Configuration(proxyBeanMethods = false) |
||||
|
public class SpringMvcConfig implements WebMvcConfigurer { |
||||
|
|
||||
|
|
||||
|
@Bean |
||||
|
public CorsFilter corsFilter() { |
||||
|
final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource(); |
||||
|
final CorsConfiguration corsConfiguration = new CorsConfiguration(); |
||||
|
/*是否允许请求带有验证信息*/ |
||||
|
corsConfiguration.setAllowCredentials(false); |
||||
|
/*允许访问的客户端域名*/ |
||||
|
corsConfiguration.addAllowedOrigin("*"); |
||||
|
/*允许服务端访问的客户端请求头*/ |
||||
|
corsConfiguration.addAllowedHeader("*"); |
||||
|
/*允许访问的方法名,GET POST等*/ |
||||
|
corsConfiguration.addAllowedMethod("*"); |
||||
|
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration); |
||||
|
return new CorsFilter(urlBasedCorsConfigurationSource); |
||||
|
} |
||||
|
|
||||
|
//@Bean
|
||||
|
public MultipartResolver multipartResolver(){ |
||||
|
CommonsMultipartResolver resolver = new CommonsMultipartResolver(); |
||||
|
resolver.setMaxInMemorySize(5120); |
||||
|
resolver.setMaxInMemorySize(300 * 1024 * 1024); |
||||
|
resolver.setDefaultEncoding("UTF-8"); |
||||
|
return resolver; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,50 @@ |
|||||
|
package com.qs.cost.common.consts; |
||||
|
|
||||
|
/** |
||||
|
* ERP API地址 |
||||
|
* @Author: YenHex |
||||
|
* @Date: 2021/3/12 |
||||
|
* @Version: 1.0 |
||||
|
**/ |
||||
|
public class ApiUrlConst { |
||||
|
|
||||
|
public static final String lzyunli = "lzyunli"; |
||||
|
|
||||
|
public static final String U8API = "/Service/13Service.asmx/U8API"; |
||||
|
|
||||
|
/** |
||||
|
* 删除专业发票 |
||||
|
*/ |
||||
|
public static final String GET_ORDER = "https://sc.gdjiajin.com/index.php/getOrder"; |
||||
|
|
||||
|
/** |
||||
|
* 删除普通发票 |
||||
|
*/ |
||||
|
public static final String UPD_ORDER = "https://sc.gdjiajin.com/index.php/upOrder"; |
||||
|
|
||||
|
/** |
||||
|
* 添加销售订单 |
||||
|
*/ |
||||
|
public static final String U8_ADD_XSDD = "XSDDAdd"; |
||||
|
|
||||
|
/** |
||||
|
* 添加销售报价单 |
||||
|
*/ |
||||
|
public static final String U8_ADD_XSBJ = "XSBJDAdd"; |
||||
|
|
||||
|
/** |
||||
|
* 添加专业发票 |
||||
|
*/ |
||||
|
public static final String U8_ADD_ZYFP = "ZYFPAdd"; |
||||
|
|
||||
|
/** |
||||
|
* 添加普通发票 |
||||
|
*/ |
||||
|
public static final String U8_ADD_PTFP = "PTFPAdd"; |
||||
|
|
||||
|
/** |
||||
|
* 获取销售订单编码 |
||||
|
*/ |
||||
|
public static final String U8_GET_XSDD_CODE = "GETXSDDCODE"; |
||||
|
|
||||
|
} |
@ -0,0 +1,17 @@ |
|||||
|
package com.qs.cost.common.dto; |
||||
|
|
||||
|
import lombok.AllArgsConstructor; |
||||
|
import lombok.Getter; |
||||
|
import lombok.Setter; |
||||
|
|
||||
|
/** |
||||
|
* @author YenHex |
||||
|
* @since 2022/2/25 |
||||
|
*/ |
||||
|
@Getter |
||||
|
@Setter |
||||
|
@AllArgsConstructor |
||||
|
public class BeanParams{ |
||||
|
private String json; |
||||
|
private String keyId; |
||||
|
} |
@ -0,0 +1,30 @@ |
|||||
|
package com.qs.cost.common.dto; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
/** |
||||
|
* 对请求结果统一封装 |
||||
|
* @author YenHex |
||||
|
* @since 2022/2/25 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class HttpResult { |
||||
|
|
||||
|
public HttpResult(Integer code,String message){ |
||||
|
this.message = message; |
||||
|
this.code = code; |
||||
|
} |
||||
|
|
||||
|
public HttpResult(Integer code,String message,String data){ |
||||
|
this.data = data; |
||||
|
this.message = message; |
||||
|
this.code = code; |
||||
|
} |
||||
|
|
||||
|
private String message; |
||||
|
|
||||
|
private Integer code; |
||||
|
|
||||
|
private String data; |
||||
|
|
||||
|
} |
@ -0,0 +1,45 @@ |
|||||
|
package com.qs.cost.common.dto; |
||||
|
|
||||
|
import lombok.Getter; |
||||
|
import lombok.Setter; |
||||
|
|
||||
|
import java.util.Date; |
||||
|
import java.util.List; |
||||
|
|
||||
|
@Getter |
||||
|
@Setter |
||||
|
public class PageVo<T>{ |
||||
|
|
||||
|
/** |
||||
|
* 页幅 |
||||
|
*/ |
||||
|
private Integer pageSize; |
||||
|
|
||||
|
/** |
||||
|
* 页眉 |
||||
|
*/ |
||||
|
private Integer pageNum; |
||||
|
|
||||
|
/** |
||||
|
* 总数据数 |
||||
|
*/ |
||||
|
private Integer total; |
||||
|
|
||||
|
/** |
||||
|
* 总页数 |
||||
|
*/ |
||||
|
private Integer totalPage; |
||||
|
|
||||
|
/** |
||||
|
* 数据列表 |
||||
|
*/ |
||||
|
private List<T> list; |
||||
|
|
||||
|
public void initPageNum(Integer total,Integer pageSize,Integer pageNum){ |
||||
|
this.pageNum = pageNum; |
||||
|
this.pageSize = pageSize; |
||||
|
if(pageSize==null||pageSize==0){ return; } |
||||
|
this.totalPage = total%pageSize==0?total/pageSize:(total/pageSize+1); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,105 @@ |
|||||
|
package com.qs.cost.common.dto; |
||||
|
|
||||
|
import lombok.Getter; |
||||
|
import lombok.Setter; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* 统一返回封装 |
||||
|
* 1.替代旧版的ViewResult |
||||
|
* 2.支持SmartDoc |
||||
|
* @author JcYen |
||||
|
* @date 2021/4/22 |
||||
|
* @version 2.0 |
||||
|
*/ |
||||
|
@Getter |
||||
|
@Setter |
||||
|
public class R<T>{ |
||||
|
|
||||
|
public R( int status, String message) { |
||||
|
this.status = status; |
||||
|
this.message = message; |
||||
|
} |
||||
|
|
||||
|
public R( int status, String message, T data) { |
||||
|
this.status = status; |
||||
|
this.message = message; |
||||
|
this.data = data; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 状态码 |
||||
|
*/ |
||||
|
private Integer status; |
||||
|
|
||||
|
/** |
||||
|
* 信息 |
||||
|
*/ |
||||
|
private String message; |
||||
|
|
||||
|
/** |
||||
|
* 数据 |
||||
|
*/ |
||||
|
private T data; |
||||
|
|
||||
|
public static final int SUCCESS_STATUS = 200; |
||||
|
public static final int LOGOUT_STATUS = 401; |
||||
|
public static final int FORBIDDEN_STATUS = 403; |
||||
|
public static final int NOT_FOUND_STATUS = 434; |
||||
|
public static final int FAILED_STATUS = 500; |
||||
|
|
||||
|
public static final String SUCCESS_TIPS = "操作成功"; |
||||
|
public static final String FAILED_TIPS = "操作失败"; |
||||
|
public static final String LOGOUT_TIPS = "登录无效"; |
||||
|
public static final String FORBIDDEN_TIPS = "无权限访问"; |
||||
|
public static final String NOT_FOUND_TIPS = "数据不存在或被移除"; |
||||
|
|
||||
|
public static R ok() { |
||||
|
return new R(SUCCESS_STATUS,SUCCESS_TIPS,null); |
||||
|
} |
||||
|
|
||||
|
public static R ok(String msg) { |
||||
|
return new R<>(SUCCESS_STATUS,msg,null); |
||||
|
} |
||||
|
|
||||
|
public static <TYPE> R<TYPE> ok(TYPE data) { |
||||
|
return new R<>(SUCCESS_STATUS,SUCCESS_TIPS,data); |
||||
|
} |
||||
|
|
||||
|
public static <TYPE> R<TYPE> ok(TYPE data,String message) { |
||||
|
return new R<>(SUCCESS_STATUS,message,data); |
||||
|
} |
||||
|
|
||||
|
public static R isTrue(Boolean bool){ |
||||
|
if(bool==null|| !bool){ |
||||
|
return error(); |
||||
|
} |
||||
|
return ok(); |
||||
|
} |
||||
|
|
||||
|
public R isTrue(Boolean bool, String message){ |
||||
|
if(bool==null|| !bool){ |
||||
|
return error(message); |
||||
|
} |
||||
|
return ok(null,message); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public static <TYPE> R<TYPE> isNotNull(TYPE object){ |
||||
|
if(object==null){ |
||||
|
return error(); |
||||
|
} |
||||
|
return ok(object,SUCCESS_TIPS); |
||||
|
} |
||||
|
|
||||
|
public static R error(String message) { |
||||
|
return new R<>(FAILED_STATUS,message,null); |
||||
|
} |
||||
|
|
||||
|
public static R error() { |
||||
|
return new R<>(FAILED_STATUS,FAILED_TIPS,null); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,51 @@ |
|||||
|
package com.qs.cost.common.dto.u8; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.annotation.IdType; |
||||
|
import com.baomidou.mybatisplus.annotation.TableId; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
|
||||
|
/** |
||||
|
* 请求记录历史 实体类 |
||||
|
* @author YenHex |
||||
|
* @since 2022-02-28 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class U8CallbackVo implements Serializable { |
||||
|
|
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
/** id */ |
||||
|
@TableId(type = IdType.INPUT) |
||||
|
private String id; |
||||
|
|
||||
|
/** 账套、租户 */ |
||||
|
private String tenant; |
||||
|
|
||||
|
/** 客户端IP */ |
||||
|
private String clientHost; |
||||
|
|
||||
|
/** 接口名称 */ |
||||
|
private String apiCmd; |
||||
|
|
||||
|
/** 接口数据主键 */ |
||||
|
private String apiPk; |
||||
|
|
||||
|
/** 接口年份 */ |
||||
|
private String apiYear; |
||||
|
|
||||
|
/** 接口keyId */ |
||||
|
private String apiKeyId; |
||||
|
|
||||
|
/** 请求参数 */ |
||||
|
private String reqParams; |
||||
|
|
||||
|
|
||||
|
/** 数据返回结果 */ |
||||
|
private String respContext; |
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
||||
|
|
@ -0,0 +1,74 @@ |
|||||
|
package com.qs.cost.common.dto.u8; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
import javax.validation.constraints.Max; |
||||
|
import javax.validation.constraints.Min; |
||||
|
import javax.validation.constraints.NotNull; |
||||
|
|
||||
|
/** |
||||
|
* @author YenHex |
||||
|
* @since 2022/2/25 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class U8RequestBo { |
||||
|
|
||||
|
/** |
||||
|
* 业务主键ID |
||||
|
* <p>用于记录,便于维护查询</p> |
||||
|
* <p>实例:订单号,订单id</p> |
||||
|
*/ |
||||
|
private String pk; |
||||
|
|
||||
|
/** |
||||
|
* U8业务请求命令 |
||||
|
*/ |
||||
|
@NotNull |
||||
|
private String cmd; |
||||
|
|
||||
|
/** |
||||
|
* 年度 |
||||
|
*/ |
||||
|
@NotNull(message = "年度不能为空") |
||||
|
private String year; |
||||
|
|
||||
|
/** |
||||
|
* 账套 |
||||
|
*/ |
||||
|
@NotNull(message = "账套不能为空") |
||||
|
private String book; |
||||
|
|
||||
|
/** |
||||
|
* 请求json字符串 |
||||
|
*/ |
||||
|
@NotNull(message = "请求json字符串不能为空") |
||||
|
private String jsonBody; |
||||
|
|
||||
|
/** |
||||
|
* 暂无意义 |
||||
|
*/ |
||||
|
private String keyId; |
||||
|
|
||||
|
/** |
||||
|
* 设置失败重连次数 |
||||
|
*/ |
||||
|
@Max(value = 10,message = "重连次数不能超过10次") |
||||
|
@Min(value = 1,message = "重连次数不能少于1次") |
||||
|
private Integer settingRetryTimes; |
||||
|
|
||||
|
/** |
||||
|
* 是否回调(0-否;1-是) |
||||
|
*/ |
||||
|
private String callbackState; |
||||
|
|
||||
|
/** |
||||
|
* 回调地址(callbackState=1时,不能为空) |
||||
|
*/ |
||||
|
private String callbackHost; |
||||
|
|
||||
|
/** |
||||
|
* 立马运行(默认false) |
||||
|
*/ |
||||
|
private Boolean immediatelyRun; |
||||
|
|
||||
|
} |
@ -0,0 +1,32 @@ |
|||||
|
package com.qs.cost.common.enums; |
||||
|
|
||||
|
import lombok.AllArgsConstructor; |
||||
|
import lombok.Getter; |
||||
|
|
||||
|
/** |
||||
|
* 请求状态码 |
||||
|
* @author YenHex |
||||
|
* @since 2022/2/28 |
||||
|
*/ |
||||
|
@Getter |
||||
|
@AllArgsConstructor |
||||
|
public enum HttpCode { |
||||
|
|
||||
|
/** 基本参数 */ |
||||
|
SUCCESS(200,"操作成功"), |
||||
|
ERROR(200,"操作失败"), |
||||
|
ERROR_CALLBACK_URL_EMPTY(200,"回调地址为空"), |
||||
|
|
||||
|
/** 资源权限相关 */ |
||||
|
FORBIDDEN_403(403,"无权访问"), |
||||
|
FORBIDDEN_403_1(403,"账套未注册,无权访问"), |
||||
|
FORBIDDEN_403_2(403,"IP地址未注册,无权访问"), |
||||
|
|
||||
|
FORBIDDEN_404(404,"资源不存在或被移除"), |
||||
|
|
||||
|
; |
||||
|
|
||||
|
Integer code; |
||||
|
String msg; |
||||
|
|
||||
|
} |
@ -0,0 +1,17 @@ |
|||||
|
package com.qs.cost.common.framework.exception; |
||||
|
|
||||
|
/** |
||||
|
* @author JcYen |
||||
|
* @Date 2020/6/11 |
||||
|
* @Version 1.0 |
||||
|
*/ |
||||
|
public abstract class BaseException extends RuntimeException { |
||||
|
|
||||
|
public BaseException(String message){ |
||||
|
super(message); |
||||
|
} |
||||
|
|
||||
|
public abstract int getCode(); |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,27 @@ |
|||||
|
package com.qs.cost.common.framework.exception; |
||||
|
|
||||
|
import lombok.Getter; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
|
||||
|
/** |
||||
|
* @author JcYen |
||||
|
* @Date 2020/6/11 |
||||
|
* @Version 1.0 |
||||
|
*/ |
||||
|
public class BusinessException extends BaseException implements Serializable { |
||||
|
|
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
private Integer status; |
||||
|
|
||||
|
public BusinessException(String message,Integer status) { |
||||
|
super(message); |
||||
|
this.status = status; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int getCode() { |
||||
|
return status; |
||||
|
} |
||||
|
} |
@ -0,0 +1,90 @@ |
|||||
|
package com.qs.cost.common.framework.exception; |
||||
|
|
||||
|
import com.qs.cost.common.dto.R; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.beans.ConversionNotSupportedException; |
||||
|
import org.springframework.beans.TypeMismatchException; |
||||
|
import org.springframework.http.converter.HttpMessageNotReadableException; |
||||
|
import org.springframework.http.converter.HttpMessageNotWritableException; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
import org.springframework.validation.BindException; |
||||
|
import org.springframework.validation.ObjectError; |
||||
|
import org.springframework.web.HttpMediaTypeNotAcceptableException; |
||||
|
import org.springframework.web.HttpMediaTypeNotSupportedException; |
||||
|
import org.springframework.web.HttpRequestMethodNotSupportedException; |
||||
|
import org.springframework.web.bind.MethodArgumentNotValidException; |
||||
|
import org.springframework.web.bind.MissingPathVariableException; |
||||
|
import org.springframework.web.bind.MissingServletRequestParameterException; |
||||
|
import org.springframework.web.bind.ServletRequestBindingException; |
||||
|
import org.springframework.web.bind.annotation.ControllerAdvice; |
||||
|
import org.springframework.web.bind.annotation.ExceptionHandler; |
||||
|
import org.springframework.web.bind.annotation.ResponseBody; |
||||
|
import org.springframework.web.context.request.async.AsyncRequestTimeoutException; |
||||
|
import org.springframework.web.multipart.support.MissingServletRequestPartException; |
||||
|
import org.springframework.web.servlet.NoHandlerFoundException; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
/** |
||||
|
* @Author JcYen |
||||
|
* @Date 2019/6/7 |
||||
|
* @Version 1.0 |
||||
|
*/ |
||||
|
@Slf4j |
||||
|
@Component |
||||
|
@ControllerAdvice |
||||
|
public class UnifiedExceptionHandler { |
||||
|
|
||||
|
@ExceptionHandler(value = BindException.class) |
||||
|
@ResponseBody |
||||
|
public R handleBindException(BindException e) { |
||||
|
log.warn("参数绑定异常", e); |
||||
|
return R.error(); |
||||
|
} |
||||
|
|
||||
|
@ExceptionHandler(value = BusinessException.class) |
||||
|
@ResponseBody |
||||
|
public R handleBindException(BusinessException e) { |
||||
|
return new R(e.getCode(),e.getMessage()); |
||||
|
} |
||||
|
|
||||
|
@ExceptionHandler(MethodArgumentNotValidException.class) |
||||
|
@ResponseBody |
||||
|
public R handleValidException(MethodArgumentNotValidException e) { |
||||
|
StringBuilder sb = new StringBuilder(); |
||||
|
List<ObjectError> allErrors = e.getBindingResult().getAllErrors(); |
||||
|
String message = allErrors.stream().map(s -> s.getDefaultMessage()).collect(Collectors.joining(";")); |
||||
|
log.warn("参数校验异常:{}",message); |
||||
|
return R.error(); |
||||
|
} |
||||
|
|
||||
|
@ExceptionHandler({ |
||||
|
NoHandlerFoundException.class, |
||||
|
HttpRequestMethodNotSupportedException.class, |
||||
|
HttpMediaTypeNotSupportedException.class, |
||||
|
MissingPathVariableException.class, |
||||
|
MissingServletRequestParameterException.class, |
||||
|
TypeMismatchException.class, |
||||
|
HttpMessageNotReadableException.class, |
||||
|
HttpMessageNotWritableException.class, |
||||
|
HttpMediaTypeNotAcceptableException.class, |
||||
|
ServletRequestBindingException.class, |
||||
|
ConversionNotSupportedException.class, |
||||
|
MissingServletRequestPartException.class, |
||||
|
AsyncRequestTimeoutException.class |
||||
|
}) |
||||
|
@ResponseBody |
||||
|
public R handleServletException(Exception e) { |
||||
|
log.error("Servlet异常\n异常类型:{}\n异常信息:{}\n异常体:",e.getClass().getSimpleName(),e.getMessage(),e); |
||||
|
return R.error(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@ExceptionHandler(value = Exception.class) |
||||
|
@ResponseBody |
||||
|
public R handleException(Exception e) { |
||||
|
log.error("Servlet异常\n异常类型:{}\n异常信息:{}\n异常体:",e.getClass().getSimpleName(),e.getMessage(),e); |
||||
|
return R.error(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,31 @@ |
|||||
|
package com.qs.cost.common.framework.interceptor; |
||||
|
|
||||
|
|
||||
|
import javax.servlet.http.HttpServletRequest; |
||||
|
import javax.servlet.http.HttpServletResponse; |
||||
|
|
||||
|
import org.springframework.web.servlet.HandlerInterceptor; |
||||
|
|
||||
|
import java.io.IOException; |
||||
|
import java.io.PrintWriter; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* @author JcYen |
||||
|
* @Date 2020/6/11 |
||||
|
* @Version 1.0 |
||||
|
*/ |
||||
|
public class ForbiddenInterceptor implements HandlerInterceptor { |
||||
|
|
||||
|
@Override |
||||
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { |
||||
|
try { |
||||
|
PrintWriter printWriter = response.getWriter(); |
||||
|
printWriter.println("{\"status\":403,\"message\":\"403 forbidden\"}"); |
||||
|
} catch (IOException e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,21 @@ |
|||||
|
package com.qs.cost.common.framework.mvc; |
||||
|
|
||||
|
import io.undertow.server.DefaultByteBufferPool; |
||||
|
import io.undertow.websockets.jsr.WebSocketDeploymentInfo; |
||||
|
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; |
||||
|
import org.springframework.boot.web.server.WebServerFactoryCustomizer; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
@Component |
||||
|
public class CustomizationBean implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> { |
||||
|
|
||||
|
@Override |
||||
|
public void customize(UndertowServletWebServerFactory factory) { |
||||
|
factory.addDeploymentInfoCustomizers(deploymentInfo -> { |
||||
|
WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo(); |
||||
|
webSocketDeploymentInfo.setBuffers(new DefaultByteBufferPool(false, 1024)); |
||||
|
deploymentInfo.addServletContextAttribute("io.undertow.websockets.jsr.WebSocketDeploymentInfo", webSocketDeploymentInfo); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,161 @@ |
|||||
|
package com.qs.cost.common.framework.mvc; |
||||
|
|
||||
|
import com.qs.cost.common.utils.DateUtil; |
||||
|
import com.qs.cost.common.utils.ServletUtil; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.core.annotation.Order; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
import org.springframework.util.StringUtils; |
||||
|
|
||||
|
import javax.servlet.*; |
||||
|
import javax.servlet.annotation.WebFilter; |
||||
|
import javax.servlet.http.HttpServletRequest; |
||||
|
import javax.servlet.http.HttpServletRequestWrapper; |
||||
|
import java.io.BufferedReader; |
||||
|
import java.io.ByteArrayInputStream; |
||||
|
import java.io.IOException; |
||||
|
import java.io.InputStreamReader; |
||||
|
import java.nio.charset.StandardCharsets; |
||||
|
|
||||
|
/** |
||||
|
* HttpServletRequest 过滤器 |
||||
|
* 解决: request.getInputStream()只能读取一次的问题 |
||||
|
* 目标: 流可重复读 |
||||
|
* @Author YenHex |
||||
|
* @Date 2021/4/9 |
||||
|
* @Version: 1.0 |
||||
|
**/ |
||||
|
@Slf4j |
||||
|
@Component |
||||
|
@WebFilter(filterName = "HttpServletRequestFilter", urlPatterns = "/") |
||||
|
@Order(10000) |
||||
|
public class HttpServletRequestFilter implements Filter{ |
||||
|
|
||||
|
|
||||
|
@Override |
||||
|
public void init(FilterConfig filterConfig) throws ServletException { |
||||
|
|
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { |
||||
|
RequestWrapper requestWrapper = null; |
||||
|
if(servletRequest instanceof HttpServletRequest) { |
||||
|
requestWrapper = new RequestWrapper((HttpServletRequest) servletRequest); |
||||
|
} |
||||
|
//servletResponse.setContentType("allowedOriginPatterns");
|
||||
|
long startTime = System.currentTimeMillis(); |
||||
|
//获取请求中的流如何,将取出来的字符串,再次转换成流,然后把它放入到新request对象中
|
||||
|
// 在chain.doFiler方法中传递新的request对象
|
||||
|
if(null == requestWrapper) { |
||||
|
filterChain.doFilter(servletRequest, servletResponse); |
||||
|
} else { |
||||
|
filterChain.doFilter(requestWrapper, servletResponse); |
||||
|
} |
||||
|
long endTime = System.currentTimeMillis(); |
||||
|
double diffTime = DateUtil.printRunTime(startTime,endTime); |
||||
|
assert servletRequest instanceof HttpServletRequest; |
||||
|
HttpServletRequest request = (HttpServletRequest)servletRequest; |
||||
|
//String tenant = request.getHeader("tenant");
|
||||
|
//String authorization = request.getHeader("Authorization");
|
||||
|
String url = request.getRequestURL().toString(); |
||||
|
String method = request.getMethod(); |
||||
|
String queryStr = request.getQueryString(); |
||||
|
String ip = request.getRemoteHost(); |
||||
|
//HttpSession session = request.getSession();
|
||||
|
//session.removeAttribute("JSESSIONID");
|
||||
|
//String sessionId = session.getId();
|
||||
|
String reqBody = ""; |
||||
|
if (ServletUtil.isJsonRequest(request)) { |
||||
|
reqBody = requestWrapper.getBody(); |
||||
|
} |
||||
|
//String host = request.getRemoteHost();
|
||||
|
//String servletPath = request.getServletPath();
|
||||
|
StringBuffer buffer = new StringBuffer("["+method+"] "+url + " IP: "+ip); |
||||
|
if(!StringUtils.isEmpty(queryStr)){ |
||||
|
buffer.append("\n参数: "+queryStr); |
||||
|
} |
||||
|
if(!StringUtils.isEmpty(reqBody)){ |
||||
|
buffer.append("\n请求体: "+reqBody); |
||||
|
} |
||||
|
buffer.append("\n耗时: "+diffTime+"秒"); |
||||
|
if(diffTime>4){ |
||||
|
log.warn("访问速度:{}秒,接口:{},参数:{},请求体:{}",diffTime,"["+method+"] "+url,queryStr,reqBody); |
||||
|
} |
||||
|
//buffer.append("\n耗时: "+diffTime+"秒 Session:"+sessionId);
|
||||
|
System.out.println(buffer.toString()); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void destroy() { |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/*** |
||||
|
* HttpServletRequest 包装器 |
||||
|
* 解决: request.getInputStream()只能读取一次的问题 |
||||
|
* 目标: 流可重复读 |
||||
|
*/ |
||||
|
public class RequestWrapper extends HttpServletRequestWrapper { |
||||
|
|
||||
|
/** |
||||
|
* 请求体 |
||||
|
*/ |
||||
|
private String mBody; |
||||
|
|
||||
|
public RequestWrapper(HttpServletRequest request) { |
||||
|
super(request); |
||||
|
mBody = getBody(request); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取请求体 |
||||
|
* @param request 请求 |
||||
|
* @return 请求体 |
||||
|
*/ |
||||
|
private String getBody(HttpServletRequest request) { |
||||
|
return ServletUtil.getBodyString(request); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取请求体 |
||||
|
* @return 请求体 |
||||
|
*/ |
||||
|
public String getBody() { |
||||
|
return mBody; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public BufferedReader getReader() throws IOException { |
||||
|
return new BufferedReader(new InputStreamReader(getInputStream())); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public ServletInputStream getInputStream() throws IOException { |
||||
|
// 创建字节数组输入流
|
||||
|
final ByteArrayInputStream bais = new ByteArrayInputStream(mBody.getBytes(StandardCharsets.UTF_8)); |
||||
|
|
||||
|
return new ServletInputStream() { |
||||
|
@Override |
||||
|
public boolean isFinished() { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public boolean isReady() { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void setReadListener(ReadListener readListener) { |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public int read() throws IOException { |
||||
|
return bais.read(); |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,20 @@ |
|||||
|
package com.qs.cost.common.utils; |
||||
|
|
||||
|
import com.qs.cost.common.enums.HttpCode; |
||||
|
import com.qs.cost.common.framework.exception.BusinessException; |
||||
|
|
||||
|
/** |
||||
|
* @author YenHex |
||||
|
* @since 2022/2/25 |
||||
|
*/ |
||||
|
public class Assert { |
||||
|
|
||||
|
public static void throwEx(Integer code,String msg){ |
||||
|
throw new BusinessException(msg, code); |
||||
|
} |
||||
|
|
||||
|
public static void throwEx(HttpCode httpCode){ |
||||
|
throw new BusinessException(httpCode.getMsg(),httpCode.getCode()); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,93 @@ |
|||||
|
package com.qs.cost.common.utils; |
||||
|
|
||||
|
import org.springframework.cglib.beans.BeanCopier; |
||||
|
|
||||
|
import java.io.*; |
||||
|
import java.util.Collection; |
||||
|
import java.util.Map; |
||||
|
import java.util.concurrent.ConcurrentHashMap; |
||||
|
|
||||
|
/** |
||||
|
* 取代BeanUtils.CP |
||||
|
* @Author JcYen |
||||
|
* @Date 2019/6/3 |
||||
|
* @Version 1.0 |
||||
|
*/ |
||||
|
public class BeanCopierUtil { |
||||
|
|
||||
|
private static final Map<String, BeanCopier> BEAN_COPIERS = new ConcurrentHashMap<String, BeanCopier>(); |
||||
|
|
||||
|
private static String genKey(Class<?> source, Class<?> target) { |
||||
|
return source.getName() + target.getName(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* target字段值,会被source字段值覆盖(包括null) |
||||
|
* @param source |
||||
|
* @param target |
||||
|
*/ |
||||
|
public static <T> T copy(Object source, T target) { |
||||
|
String key = genKey(source.getClass(), target.getClass()); |
||||
|
BeanCopier copier; |
||||
|
if (!BEAN_COPIERS.containsKey(key)) { |
||||
|
copier = BeanCopier.create(source.getClass(), target.getClass(), false); |
||||
|
BEAN_COPIERS.put(key, copier); |
||||
|
} else { |
||||
|
copier = BEAN_COPIERS.get(key); |
||||
|
} |
||||
|
copier.copy(source, target, null); |
||||
|
return target; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 采用对象的序列化完成对象的深克隆 |
||||
|
* @param obj 待克隆的对象 |
||||
|
* @return |
||||
|
*/ |
||||
|
@SuppressWarnings("unchecked") |
||||
|
public static <T extends Serializable> T cloneObject(T obj) { |
||||
|
T cloneObj = null; |
||||
|
try { |
||||
|
// 写入字节流
|
||||
|
ByteArrayOutputStream out = new ByteArrayOutputStream(); |
||||
|
ObjectOutputStream obs = new ObjectOutputStream(out); |
||||
|
obs.writeObject(obj); |
||||
|
obs.close(); |
||||
|
|
||||
|
// 分配内存,写入原始对象,生成新对象
|
||||
|
ByteArrayInputStream ios = new ByteArrayInputStream(out.toByteArray()); |
||||
|
ObjectInputStream ois = new ObjectInputStream(ios); |
||||
|
// 返回生成的新对象
|
||||
|
cloneObj = (T) ois.readObject(); |
||||
|
ois.close(); |
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
return cloneObj; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 利用序列化完成集合的深克隆 |
||||
|
* |
||||
|
* @param collection 待克隆的集合 |
||||
|
* @return |
||||
|
* @throws ClassNotFoundException |
||||
|
* @throws IOException |
||||
|
*/ |
||||
|
@SuppressWarnings("unchecked") |
||||
|
public static <T> Collection<T> cloneCollection(Collection<T> collection) throws ClassNotFoundException, IOException{ |
||||
|
ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); |
||||
|
ObjectOutputStream out = new ObjectOutputStream(byteOut); |
||||
|
out.writeObject(collection); |
||||
|
out.close(); |
||||
|
|
||||
|
ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray()); |
||||
|
ObjectInputStream in = new ObjectInputStream(byteIn); |
||||
|
Collection<T> dest = (Collection<T>) in.readObject(); |
||||
|
in.close(); |
||||
|
|
||||
|
return dest; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,131 @@ |
|||||
|
package com.qs.cost.common.utils; |
||||
|
|
||||
|
import java.util.*; |
||||
|
|
||||
|
/** |
||||
|
* 常用数据工具类 |
||||
|
* |
||||
|
* @Author JcYen |
||||
|
* @Date 2019/5/23 |
||||
|
* @Version 1.0 |
||||
|
*/ |
||||
|
public class CollectionUtil { |
||||
|
|
||||
|
private CollectionUtil() { |
||||
|
super(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 判断一个集合是否为空 |
||||
|
*/ |
||||
|
public static <T> boolean isEmpty(Collection<T> col) { |
||||
|
if (col == null || col.isEmpty()) { |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
public static <T> List<T> setToList(Set<T> colSet){ |
||||
|
if (colSet == null || colSet.isEmpty()){ |
||||
|
return new ArrayList<>(); |
||||
|
} |
||||
|
List<T> rs = new ArrayList<>(colSet); |
||||
|
return rs; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 判断一个集合是否不为空 |
||||
|
*/ |
||||
|
public static <T> boolean isNotEmpty(Collection<T> col) { |
||||
|
return !isEmpty(col); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 判断Map是否为空 |
||||
|
*/ |
||||
|
public static <K, V> boolean isEmpty(Map<K, V> map) { |
||||
|
if (map == null || map.isEmpty()) { |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 判断Map是否不为空为空 |
||||
|
*/ |
||||
|
public static <K, V> boolean isNotEmpty(Map<K, V> map) { |
||||
|
return !isEmpty(map); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 去除list中的重复数据 |
||||
|
*/ |
||||
|
public static <T> List<T> removeRepeat(List<T> list) { |
||||
|
if (isEmpty(list)) { |
||||
|
return list; |
||||
|
} |
||||
|
List<T> result = new ArrayList<T>(); |
||||
|
for (T e : list) { |
||||
|
if (!result.contains(e)) { |
||||
|
result.add(e); |
||||
|
} |
||||
|
} |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
public static boolean hasNull(Object... objects){ |
||||
|
for (int i = 0; i < objects.length; i++) { |
||||
|
if(objects[i]==null){return true;} |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
public static boolean hasNotNull(Object... objects){ |
||||
|
for (int i = 0; i < objects.length; i++) { |
||||
|
if(objects[i]!=null){return true;} |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将集合转换为String数组 |
||||
|
*/ |
||||
|
public static <T> String[] toArray(List<T> list) { |
||||
|
if (isEmpty(list)) { |
||||
|
return null; |
||||
|
} |
||||
|
String[] result = new String[list.size()]; |
||||
|
for (int i = 0; i < list.size(); i++) { |
||||
|
result[i] = String.valueOf(list.get(i)); |
||||
|
} |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将list拆分成多给指定的大小的list |
||||
|
*/ |
||||
|
public static <T> List<List<T>> createList(List<T> target, int size) { |
||||
|
List<List<T>> listArr = new ArrayList<>(); |
||||
|
//获取被拆分的数组个数
|
||||
|
int arrSize = target.size()%size==0?target.size()/size:target.size()/size+1; |
||||
|
for(int i=0;i<arrSize;i++) { |
||||
|
List<T> sub = new ArrayList<T>(); |
||||
|
//把指定索引数据放入到list中
|
||||
|
for(int j=i*size;j<=size*(i+1)-1;j++) { |
||||
|
if(j<=target.size()-1) { |
||||
|
sub.add(target.get(j)); |
||||
|
} |
||||
|
} |
||||
|
listArr.add(sub); |
||||
|
} |
||||
|
return listArr; |
||||
|
} |
||||
|
|
||||
|
public static <T> T selectFirst(List<T> list){ |
||||
|
if(isNotEmpty(list)){ |
||||
|
return list.get(0); |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,194 @@ |
|||||
|
package com.qs.cost.common.utils; |
||||
|
|
||||
|
import java.text.ParseException; |
||||
|
import java.text.SimpleDateFormat; |
||||
|
import java.time.LocalDateTime; |
||||
|
import java.time.ZoneId; |
||||
|
import java.time.ZonedDateTime; |
||||
|
import java.util.Calendar; |
||||
|
import java.util.Date; |
||||
|
|
||||
|
/** |
||||
|
* 日期工具类 |
||||
|
* Created by macro on 2019/1/29. |
||||
|
*/ |
||||
|
public class DateUtil { |
||||
|
|
||||
|
public static final String FORMAT_SIMPLE_DATE_OF_YEAR_NUM = "MMdd"; |
||||
|
public static final String FORMAT_SIMPLE_DATE_OF_YEAR = "MM-dd"; |
||||
|
public static final String FORMAT_DATE_OF_YEAR = "MM-dd HH:mm:ss"; |
||||
|
public static final String FORMAT_DATE = "yyyy-MM-dd HH:mm:ss"; |
||||
|
public static final String FORMAT_SIMPLE_DATE_NUM = "yyyyMMdd"; |
||||
|
public static final String FORMAT_DATE_NUM = "yyyyMMddHHmmss"; |
||||
|
public static final String FORMAT_CRON = "ss mm HH dd MM ?"; |
||||
|
|
||||
|
public static final String FORMAT_SIMPLE_DATE_ZH = "yyyy年MM月dd日"; |
||||
|
public static final String FORMAT_DATE_ZH = "yyyy年MM月dd日 HH时mm分ss秒"; |
||||
|
|
||||
|
|
||||
|
public static final String FORMAT_SIMPLE_DATE = "yyyy-MM-dd"; |
||||
|
public static final String FORMAT_SIMPLE_DATE2 = "yyyy/MM/dd"; |
||||
|
public static final String FORMAT_SIMPLE_MONTH = "yyyy-MM"; |
||||
|
public static final String FORMAT_SIMPLE_YEAR = "yyyy"; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* LocalDateTime转为日期 |
||||
|
* |
||||
|
* @param localDateTime LocalDateTime |
||||
|
* @return 日期 |
||||
|
*/ |
||||
|
public static Date localDateTimeToDate(final LocalDateTime localDateTime) { |
||||
|
if (null == localDateTime) { |
||||
|
return null; |
||||
|
} |
||||
|
final ZoneId zoneId = ZoneId.systemDefault(); |
||||
|
final ZonedDateTime zdt = localDateTime.atZone(zoneId); |
||||
|
final Date date = Date.from(zdt.toInstant()); |
||||
|
return date; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 转换格式 |
||||
|
* @param dateStr |
||||
|
* @param format |
||||
|
* @return |
||||
|
*/ |
||||
|
public static Date getDateByFormatStr(String dateStr,String format){ |
||||
|
if(dateStr==null||format==null){return null;} |
||||
|
SimpleDateFormat sdf = new SimpleDateFormat(format); |
||||
|
Date date = null; |
||||
|
try { |
||||
|
date = sdf.parse(dateStr); |
||||
|
} catch (ParseException e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
return date; |
||||
|
} |
||||
|
|
||||
|
public static Double getDiffSecond(long beganTime, long endTime){ |
||||
|
return (double)(endTime - beganTime) / 1000.0D; |
||||
|
} |
||||
|
|
||||
|
/** 格式化日期字符串*/ |
||||
|
public static String formatDate(Date date,String format){ |
||||
|
SimpleDateFormat sdf = new SimpleDateFormat(format); |
||||
|
if(date!=null){ |
||||
|
return sdf.format(date); |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
public static Date format(Date date,String format){ |
||||
|
String dateString = formatDate(date, format); |
||||
|
SimpleDateFormat sdf = new SimpleDateFormat(format); |
||||
|
try { |
||||
|
if(dateString!=null){ |
||||
|
return sdf.parse(dateString); |
||||
|
} |
||||
|
} catch (ParseException e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public static double printRunTime(long beganTime, long endTime) { |
||||
|
return (double)(endTime - beganTime) / 1000.0D; |
||||
|
} |
||||
|
|
||||
|
/** 获取一天的起始时间*/ |
||||
|
public static Date getBeginDateOfDay(Date date){ |
||||
|
Calendar calendar = Calendar.getInstance(); |
||||
|
calendar.setTime(date); |
||||
|
int day = calendar.get(Calendar.DATE); |
||||
|
calendar.set(Calendar.DATE,day-1); |
||||
|
calendar.set(Calendar.HOUR_OF_DAY,23); |
||||
|
calendar.set(Calendar.MINUTE,59); |
||||
|
calendar.set(Calendar.SECOND,59); |
||||
|
calendar.set(Calendar.MILLISECOND,99); |
||||
|
/*calendar.set(Calendar.HOUR_OF_DAY,0); |
||||
|
calendar.set(Calendar.MINUTE,0); |
||||
|
calendar.set(Calendar.SECOND,0); |
||||
|
calendar.set(Calendar.MILLISECOND,0);*/ |
||||
|
return calendar.getTime(); |
||||
|
} |
||||
|
|
||||
|
/** 获取一天的结束时间(23:59:59)*/ |
||||
|
public static Date getEndDateOfDay(Date date){ |
||||
|
Calendar calendar = Calendar.getInstance(); |
||||
|
calendar.setTime(date); |
||||
|
int day = calendar.get(Calendar.DATE); |
||||
|
calendar.set(Calendar.DATE,day+1); |
||||
|
calendar.set(Calendar.HOUR_OF_DAY,0); |
||||
|
calendar.set(Calendar.MINUTE,0); |
||||
|
calendar.set(Calendar.SECOND,0); |
||||
|
calendar.set(Calendar.MILLISECOND,0); |
||||
|
/*calendar.set(Calendar.HOUR_OF_DAY,23); |
||||
|
calendar.set(Calendar.MINUTE,59); |
||||
|
calendar.set(Calendar.SECOND,59); |
||||
|
calendar.set(Calendar.MILLISECOND,999);*/ |
||||
|
return calendar.getTime(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取未来某时间 |
||||
|
* @param date |
||||
|
* @param somedate |
||||
|
* @param calendarTimeSpan |
||||
|
*/ |
||||
|
public static Date getAfterSomedate(Date date,int somedate,int calendarTimeSpan){ |
||||
|
final Calendar calendar = Calendar.getInstance(); |
||||
|
calendar.setTime(date); |
||||
|
calendar.add(calendarTimeSpan,somedate); |
||||
|
return calendar.getTime(); |
||||
|
} |
||||
|
|
||||
|
/** 获取传入日期在某时间第一天 */ |
||||
|
public static Date getFirstDay(Date date,int calendarTimeSpan) { |
||||
|
Calendar cal = Calendar.getInstance(); |
||||
|
cal.setTime(date); |
||||
|
int last = cal.getActualMinimum(calendarTimeSpan); |
||||
|
cal.set(calendarTimeSpan, last); |
||||
|
return cal.getTime(); |
||||
|
} |
||||
|
|
||||
|
/** 获取传入日期在某时间最后一天 */ |
||||
|
public static Date getLastDay(Date date,int calendarTimeSpan) { |
||||
|
Calendar cal = Calendar.getInstance(); |
||||
|
cal.setTime(date); |
||||
|
int last = cal.getActualMaximum(calendarTimeSpan); |
||||
|
cal.set(calendarTimeSpan, last); |
||||
|
return cal.getTime(); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 计算时差 |
||||
|
* @param smallDate |
||||
|
* @param bigDate |
||||
|
* @param unit 0天 1时 2分 3秒 |
||||
|
* @return |
||||
|
*/ |
||||
|
public static Long diffTime(Date smallDate,Date bigDate,int unit){ |
||||
|
long nd = 1000*24*60*60;//一天的毫秒数
|
||||
|
long nh = 1000*60*60;//一小时的毫秒数
|
||||
|
long nm = 1000*60;//一分钟的毫秒数
|
||||
|
long ns = 1000;//一秒钟的毫秒数
|
||||
|
|
||||
|
long t1 = smallDate.getTime(); |
||||
|
long t2 = bigDate.getTime(); |
||||
|
long diff = t2 - t1; |
||||
|
if(unit==0){ |
||||
|
return diff/nd; |
||||
|
}else if (unit==1){ |
||||
|
return diff%nd/nh; |
||||
|
}else if(unit==2){ |
||||
|
return diff%nd%nh/nm; |
||||
|
}else if(unit==3){ |
||||
|
return diff%nd%nh%nm/ns; |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,479 @@ |
|||||
|
package com.qs.cost.common.utils; |
||||
|
|
||||
|
import lombok.Getter; |
||||
|
import lombok.Setter; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.apache.http.HttpEntity; |
||||
|
import org.apache.http.HttpResponse; |
||||
|
import org.apache.http.HttpStatus; |
||||
|
import org.apache.http.NameValuePair; |
||||
|
import org.apache.http.client.ClientProtocolException; |
||||
|
import org.apache.http.client.config.RequestConfig; |
||||
|
import org.apache.http.client.entity.UrlEncodedFormEntity; |
||||
|
import org.apache.http.client.methods.CloseableHttpResponse; |
||||
|
import org.apache.http.client.methods.HttpGet; |
||||
|
import org.apache.http.client.methods.HttpPost; |
||||
|
import org.apache.http.client.methods.HttpRequestBase; |
||||
|
import org.apache.http.client.utils.URIBuilder; |
||||
|
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; |
||||
|
import org.apache.http.entity.StringEntity; |
||||
|
import org.apache.http.impl.client.CloseableHttpClient; |
||||
|
import org.apache.http.impl.client.HttpClientBuilder; |
||||
|
import org.apache.http.impl.client.HttpClients; |
||||
|
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; |
||||
|
import org.apache.http.message.BasicNameValuePair; |
||||
|
import org.apache.http.protocol.HTTP; |
||||
|
import org.apache.http.ssl.SSLContextBuilder; |
||||
|
import org.apache.http.ssl.TrustStrategy; |
||||
|
import org.apache.http.util.EntityUtils; |
||||
|
|
||||
|
import javax.net.ssl.SSLContext; |
||||
|
import java.io.*; |
||||
|
import java.net.URISyntaxException; |
||||
|
import java.nio.charset.Charset; |
||||
|
import java.security.cert.CertificateException; |
||||
|
import java.security.cert.X509Certificate; |
||||
|
import java.util.*; |
||||
|
|
||||
|
/** |
||||
|
* Created by JcYen on 2019/5/13 |
||||
|
* |
||||
|
* @Version v1.0 |
||||
|
**/ |
||||
|
@Slf4j |
||||
|
public class HttpService { |
||||
|
|
||||
|
private static PoolingHttpClientConnectionManager cm; |
||||
|
private static RequestConfig requestConfig; |
||||
|
private static String UTF_8 = "UTF-8"; |
||||
|
|
||||
|
private static void init() { |
||||
|
Integer poolSize = 10; |
||||
|
Integer connSize = 5; |
||||
|
Integer socketTimeout = 200; |
||||
|
Integer reqTimeout = 200; |
||||
|
Integer connTimeout = 200; |
||||
|
if (cm == null) { |
||||
|
cm = new PoolingHttpClientConnectionManager(); |
||||
|
cm.setMaxTotal(poolSize);// 整个连接池最大连接数
|
||||
|
cm.setDefaultMaxPerRoute(connSize);// 每路由最大连接数,默认值是2
|
||||
|
requestConfig = RequestConfig.custom() // 建立构造器
|
||||
|
.setConnectTimeout(connTimeout*1000)// 设置连接超时
|
||||
|
.setConnectionRequestTimeout(reqTimeout*1000)// 设置从连接池获取连接实例的超时
|
||||
|
.setSocketTimeout(socketTimeout*1000)// 设置读取超时
|
||||
|
.build();// 在提交请求之前 测试连接是否可用
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* 通过连接池获取HttpClient */ |
||||
|
private static CloseableHttpClient getHttpClient() { |
||||
|
init(); |
||||
|
return HttpClients.custom().setConnectionManager(cm).setDefaultRequestConfig(requestConfig).build(); |
||||
|
} |
||||
|
|
||||
|
/* get的URL请求 */ |
||||
|
public static String httpGetRequest(String url) { |
||||
|
HttpGet httpGet = new HttpGet(url); |
||||
|
return getResult(httpGet); |
||||
|
} |
||||
|
|
||||
|
public static InputStream httpGetStream(String url) { |
||||
|
HttpGet httpGet = new HttpGet(url); |
||||
|
CloseableHttpClient httpClient = getHttpClient(); |
||||
|
try { |
||||
|
CloseableHttpResponse response = httpClient.execute(httpGet); |
||||
|
HttpEntity entity = response.getEntity(); |
||||
|
if (entity != null) { |
||||
|
return entity.getContent(); |
||||
|
} |
||||
|
} catch (IOException e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
/* get的URL的参数map请求 */ |
||||
|
public static String httpGetRequest(String url, Map<String, Object> params) throws URISyntaxException { |
||||
|
URIBuilder ub = new URIBuilder(); |
||||
|
ub.setPath(url); |
||||
|
ArrayList<NameValuePair> pairs = covertParams2NVPS(params); |
||||
|
ub.setParameters(pairs); |
||||
|
HttpGet httpGet = new HttpGet(ub.build()); |
||||
|
return getResult(httpGet); |
||||
|
} |
||||
|
|
||||
|
/* get的URL参数map,头map参数 */ |
||||
|
public static String httpGetRequest(String url, Map<String, Object> headers, Map<String, Object> params) |
||||
|
throws URISyntaxException { |
||||
|
URIBuilder ub = new URIBuilder(); |
||||
|
ub.setPath(url); |
||||
|
ArrayList<NameValuePair> pairs = covertParams2NVPS(params); |
||||
|
ub.setParameters(pairs); |
||||
|
HttpGet httpGet = new HttpGet(ub.build()); |
||||
|
for (Map.Entry<String, Object> param : headers.entrySet()) { |
||||
|
httpGet.addHeader(param.getKey(), String.valueOf(param.getValue())); |
||||
|
} |
||||
|
return getResult(httpGet); |
||||
|
} |
||||
|
|
||||
|
/* post的URL请求 */ |
||||
|
public static String httpPostRequest(String url) { |
||||
|
HttpPost httpPost = new HttpPost(url); |
||||
|
return getResult(httpPost); |
||||
|
} |
||||
|
|
||||
|
/* post的URL的参数map请求 */ |
||||
|
public static String httpPostRequest(String url, Map<String, Object> params) throws UnsupportedEncodingException { |
||||
|
HttpPost httpPost = new HttpPost(url); |
||||
|
ArrayList<NameValuePair> pairs = covertParams2NVPS(params); |
||||
|
httpPost.setEntity(new UrlEncodedFormEntity(pairs, UTF_8)); |
||||
|
log.debug("httpPostRequest -> URL:",httpPost.getURI().getPath()); |
||||
|
return getResult(httpPost); |
||||
|
} |
||||
|
/* post的URL的参数map请求 */ |
||||
|
public static HttpResult httpPostRequestWithResult(String url, Map<String, Object> params) { |
||||
|
HttpPost httpPost = new HttpPost(url); |
||||
|
ArrayList<NameValuePair> pairs = covertParams2NVPS(params); |
||||
|
try { |
||||
|
httpPost.setEntity(new UrlEncodedFormEntity(pairs, UTF_8)); |
||||
|
} catch (UnsupportedEncodingException e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
log.debug("httpPostRequest -> URL:",httpPost.getURI().getPath()); |
||||
|
return getHttpResult(httpPost); |
||||
|
} |
||||
|
|
||||
|
/* post的URL的参数map请求map头 */ |
||||
|
public static String httpPostRequest(String url, Map<String, Object> headers, Map<String, Object> params) |
||||
|
throws UnsupportedEncodingException { |
||||
|
HttpPost httpPost = new HttpPost(url); |
||||
|
for (Map.Entry<String, Object> param : headers.entrySet()) { |
||||
|
httpPost.addHeader(param.getKey(), String.valueOf(param.getValue())); |
||||
|
} |
||||
|
ArrayList<NameValuePair> pairs = covertParams2NVPS(params); |
||||
|
httpPost.setEntity(new UrlEncodedFormEntity(pairs, UTF_8)); |
||||
|
return getResult(httpPost); |
||||
|
} |
||||
|
|
||||
|
/* post的URL的参数map请求map头及body信息 */ |
||||
|
@SuppressWarnings({ "rawtypes", "unchecked" }) |
||||
|
public static String postMap(String url, Map<String, String> headerMap, Map<String, String> contentMap) { |
||||
|
String result = null; |
||||
|
CloseableHttpClient httpClient = HttpClients.createDefault(); |
||||
|
HttpPost post = new HttpPost(url); |
||||
|
List<NameValuePair> content = new ArrayList<NameValuePair>(); |
||||
|
Iterator iterator = contentMap.entrySet().iterator(); // 将content生成entity
|
||||
|
while (iterator.hasNext()) { |
||||
|
Map.Entry<String, String> elem = (Map.Entry<String, String>) iterator.next(); |
||||
|
content.add(new BasicNameValuePair(elem.getKey(), elem.getValue())); |
||||
|
} |
||||
|
CloseableHttpResponse response = null; |
||||
|
try { |
||||
|
Iterator headerIterator = headerMap.entrySet().iterator(); // 循环增加header
|
||||
|
while (headerIterator.hasNext()) { |
||||
|
Map.Entry<String, String> elem = (Map.Entry<String, String>) headerIterator.next(); |
||||
|
post.addHeader(elem.getKey(), elem.getValue()); |
||||
|
} |
||||
|
if (content.size() > 0) { |
||||
|
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(content, "UTF-8"); |
||||
|
post.setEntity(entity); |
||||
|
} |
||||
|
response = httpClient.execute(post); // 发送请求并接收返回数据
|
||||
|
if (response != null && response.getStatusLine().getStatusCode() == 200) { |
||||
|
HttpEntity entity = response.getEntity(); // 获取response的body部分
|
||||
|
result = EntityUtils.toString(entity); // 读取reponse的body部分并转化成字符串
|
||||
|
} |
||||
|
return result; |
||||
|
} catch (UnsupportedEncodingException e) { |
||||
|
e.printStackTrace(); |
||||
|
} catch (ClientProtocolException e) { |
||||
|
e.printStackTrace(); |
||||
|
} catch (IOException e) { |
||||
|
e.printStackTrace(); |
||||
|
} finally { |
||||
|
try { |
||||
|
httpClient.close(); |
||||
|
if (response != null) { |
||||
|
response.close(); |
||||
|
} |
||||
|
} catch (IOException e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/* 中间工具 */ |
||||
|
private static ArrayList<NameValuePair> covertParams2NVPS(Map<String, Object> params) { |
||||
|
ArrayList<NameValuePair> pairs = new ArrayList<NameValuePair>(); |
||||
|
for (Map.Entry<String, Object> param : params.entrySet()) { |
||||
|
pairs.add(new BasicNameValuePair(param.getKey(), String.valueOf(param.getValue()))); |
||||
|
} |
||||
|
return pairs; |
||||
|
} |
||||
|
|
||||
|
/* 发送的json的参数请求 */ |
||||
|
public static String httpPostJSON(String url, String json) throws UnsupportedEncodingException { |
||||
|
log.info("json"+json); |
||||
|
HttpPost httpPost = new HttpPost(url); |
||||
|
StringEntity entity = new StringEntity(json); |
||||
|
entity.setContentEncoding(UTF_8); |
||||
|
entity.setContentType("application/json");// 发送json数据需要设置contentType
|
||||
|
httpPost.setEntity(entity); |
||||
|
return getResult(httpPost); |
||||
|
} |
||||
|
|
||||
|
/* 发送的json的参数请求 */ |
||||
|
public static HttpResponse httpImagePostJSON(String url, String json) throws UnsupportedEncodingException { |
||||
|
CloseableHttpClient httpClient = HttpClientBuilder.create().build(); |
||||
|
HttpPost httpPost = new HttpPost(url); |
||||
|
httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json"); |
||||
|
StringEntity entity; |
||||
|
entity = new StringEntity(json); |
||||
|
entity.setContentType("image/png"); |
||||
|
httpPost.setEntity(entity); |
||||
|
HttpResponse response = null; |
||||
|
try { |
||||
|
response = httpClient.execute(httpPost); |
||||
|
} catch (IOException e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
return response; |
||||
|
} |
||||
|
|
||||
|
/* 发送的xml字符串 */ |
||||
|
public static String httpPostXML(String url, String xmlData) throws UnsupportedEncodingException { |
||||
|
HttpPost post = new HttpPost(url); |
||||
|
StringEntity entity = new StringEntity(xmlData); |
||||
|
entity.setContentEncoding(UTF_8); |
||||
|
entity.setContentType("text/xml;charset=UTF-8"); |
||||
|
return getResult(post); |
||||
|
} |
||||
|
|
||||
|
private static String getResult(HttpRequestBase request) { |
||||
|
return getHttpResult(request).getData(); |
||||
|
} |
||||
|
|
||||
|
private static HttpResult getHttpResult(HttpRequestBase request) { |
||||
|
CloseableHttpClient httpClient = getHttpClient(); |
||||
|
String errMsg = null; |
||||
|
Integer code = 500; |
||||
|
try { |
||||
|
CloseableHttpResponse response = httpClient.execute(request); |
||||
|
code = response.getStatusLine().getStatusCode(); |
||||
|
HttpEntity entity = response.getEntity(); |
||||
|
if (entity != null) { |
||||
|
String data = EntityUtils.toString(entity, UTF_8); |
||||
|
response.close(); |
||||
|
HttpResult result = new HttpResult(code,null,data); |
||||
|
return result; |
||||
|
} |
||||
|
} catch (ClientProtocolException e) { |
||||
|
log.error(e.getMessage()); |
||||
|
errMsg = e.getMessage(); |
||||
|
} catch (IOException e) { |
||||
|
log.error(e.getMessage()); |
||||
|
errMsg = e.getMessage(); |
||||
|
} |
||||
|
return new HttpResult(code,errMsg); |
||||
|
} |
||||
|
|
||||
|
public static String getXMLString() { |
||||
|
StringBuffer sb = new StringBuffer(); |
||||
|
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); |
||||
|
sb.append("<AastraIPPhoneInputScreen type=\"string\">"); |
||||
|
sb.append("<Title>Hello world!</Title>"); |
||||
|
sb.append("<Prompt>Enter value</Prompt>"); |
||||
|
sb.append("<URL>http://localhost/xmlserver/test.do</URL>"); |
||||
|
sb.append("<Parameter>value</Parameter>"); |
||||
|
sb.append("<Default></Default>"); |
||||
|
sb.append("</AastraIPPhoneInputScreen>"); |
||||
|
return sb.toString(); |
||||
|
} |
||||
|
|
||||
|
public static String doPost(String apiUrl, Object json) { |
||||
|
CloseableHttpClient httpClient = HttpClients.createDefault(); |
||||
|
String httpStr = null; |
||||
|
HttpPost httpPost = new HttpPost(apiUrl); |
||||
|
CloseableHttpResponse response = null; |
||||
|
try { |
||||
|
httpPost.setConfig(requestConfig); |
||||
|
StringEntity stringEntity = new StringEntity(json.toString(), "UTF-8");// 解决中文乱码问题
|
||||
|
stringEntity.setContentEncoding("UTF-8"); |
||||
|
stringEntity.setContentType("application/json"); |
||||
|
httpPost.setEntity(stringEntity); |
||||
|
response = httpClient.execute(httpPost); |
||||
|
HttpEntity entity = response.getEntity(); |
||||
|
System.out.println(response.getStatusLine().getStatusCode()); |
||||
|
httpStr = EntityUtils.toString(entity, "UTF-8"); |
||||
|
} catch (IOException e) { |
||||
|
e.printStackTrace(); |
||||
|
} finally { |
||||
|
if (response != null) { |
||||
|
try { |
||||
|
EntityUtils.consume(response.getEntity()); |
||||
|
} catch (IOException e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return httpStr; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 发送 SSL POST 请求(HTTPS),K-V形式 |
||||
|
*/ |
||||
|
public static String doPostSSLXml(String apiUrl, String xml) { |
||||
|
CloseableHttpClient httpClient = createSSLClientDefault(); |
||||
|
HttpPost httpPost = new HttpPost(apiUrl); |
||||
|
CloseableHttpResponse response = null; |
||||
|
String httpStr = null; |
||||
|
try { |
||||
|
httpPost.setConfig(requestConfig); |
||||
|
StringEntity stringEntity = new StringEntity(xml, "UTF-8");// 解决中文乱码问题
|
||||
|
stringEntity.setContentEncoding("UTF-8"); |
||||
|
stringEntity.setContentType("text/xml;charset=UTF-8"); |
||||
|
httpPost.setEntity(stringEntity); |
||||
|
response = httpClient.execute(httpPost); |
||||
|
System.out.println(response); |
||||
|
// int statusCode = response.getStatusLine().getStatusCode();
|
||||
|
// if (statusCode != HttpStatus.SC_OK) {
|
||||
|
// return null;
|
||||
|
// }
|
||||
|
HttpEntity entity = response.getEntity(); |
||||
|
// if (entity == null) {
|
||||
|
// return null;
|
||||
|
// }
|
||||
|
httpStr = EntityUtils.toString(entity, "utf-8"); |
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} finally { |
||||
|
if (response != null) { |
||||
|
try { |
||||
|
EntityUtils.consume(response.getEntity()); |
||||
|
} catch (IOException e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return httpStr; |
||||
|
} |
||||
|
|
||||
|
public static String doGetSSL(String apiUrl) throws ClientProtocolException, IOException { |
||||
|
CloseableHttpClient httpClient = createSSLClientDefault(); |
||||
|
HttpGet httpget = new HttpGet(apiUrl); |
||||
|
CloseableHttpResponse response = null; |
||||
|
String httpStr = null; |
||||
|
httpget.setConfig(requestConfig); |
||||
|
response = httpClient.execute(httpget); |
||||
|
HttpEntity entity = response.getEntity(); |
||||
|
httpStr = EntityUtils.toString(entity, "utf-8"); |
||||
|
return httpStr; |
||||
|
} |
||||
|
|
||||
|
public static String doPostSSL(String apiUrl, Map<String, Object> params) |
||||
|
throws ClientProtocolException, IOException { |
||||
|
CloseableHttpClient httpClient = createSSLClientDefault(); |
||||
|
HttpPost httpPost = new HttpPost(apiUrl); |
||||
|
CloseableHttpResponse response = null; |
||||
|
String httpStr = null; |
||||
|
httpPost.setConfig(requestConfig); |
||||
|
List<NameValuePair> pairList = new ArrayList<NameValuePair>(params.size()); |
||||
|
for (Map.Entry<String, Object> entry : params.entrySet()) { |
||||
|
NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry.getValue().toString()); |
||||
|
pairList.add(pair); |
||||
|
} |
||||
|
httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("utf-8"))); |
||||
|
response = httpClient.execute(httpPost); |
||||
|
HttpEntity entity = response.getEntity(); |
||||
|
httpStr = EntityUtils.toString(entity, "utf-8"); |
||||
|
return httpStr; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 发送 SSL POST 请求(HTTPS),JSON形式 |
||||
|
* |
||||
|
* @param apiUrl |
||||
|
* API接口URL |
||||
|
* @param json |
||||
|
* JSON对象 |
||||
|
* @return |
||||
|
*/ |
||||
|
public static String doPostSSL(String apiUrl, Object json) { |
||||
|
CloseableHttpClient httpClient = createSSLClientDefault(); |
||||
|
HttpPost httpPost = new HttpPost(apiUrl); |
||||
|
CloseableHttpResponse response = null; |
||||
|
String httpStr = null; |
||||
|
try { |
||||
|
httpPost.setConfig(requestConfig); |
||||
|
StringEntity stringEntity = new StringEntity(json.toString(), "UTF-8");// 解决中文乱码问题
|
||||
|
stringEntity.setContentEncoding("UTF-8"); |
||||
|
stringEntity.setContentType("application/json"); |
||||
|
httpPost.setEntity(stringEntity); |
||||
|
response = httpClient.execute(httpPost); |
||||
|
int statusCode = response.getStatusLine().getStatusCode(); |
||||
|
if (statusCode != HttpStatus.SC_OK) { |
||||
|
return null; |
||||
|
} |
||||
|
HttpEntity entity = response.getEntity(); |
||||
|
if (entity == null) { |
||||
|
return null; |
||||
|
} |
||||
|
httpStr = EntityUtils.toString(entity, "utf-8"); |
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} finally { |
||||
|
if (response != null) { |
||||
|
try { |
||||
|
EntityUtils.consume(response.getEntity()); |
||||
|
} catch (IOException e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return httpStr; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
public static CloseableHttpClient createSSLClientDefault() { |
||||
|
try { |
||||
|
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { |
||||
|
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { |
||||
|
return true; |
||||
|
} |
||||
|
}).build(); |
||||
|
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext); |
||||
|
return HttpClients.custom().setSSLSocketFactory(sslsf).build(); |
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
return HttpClients.createDefault(); |
||||
|
} |
||||
|
|
||||
|
@Getter |
||||
|
@Setter |
||||
|
public static class HttpResult { |
||||
|
|
||||
|
public HttpResult(Integer code,String message){ |
||||
|
this.massage = message; |
||||
|
this.code = code; |
||||
|
} |
||||
|
|
||||
|
public HttpResult(Integer code,String message,String data){ |
||||
|
this.data = data; |
||||
|
this.massage = message; |
||||
|
this.code = code; |
||||
|
} |
||||
|
|
||||
|
private String massage; |
||||
|
|
||||
|
private Integer code; |
||||
|
|
||||
|
private String data; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,121 @@ |
|||||
|
package com.qs.cost.common.utils; |
||||
|
|
||||
|
import com.qs.cost.common.dto.HttpResult; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.apache.http.HttpEntity; |
||||
|
import org.apache.http.NameValuePair; |
||||
|
import org.apache.http.client.ClientProtocolException; |
||||
|
import org.apache.http.client.config.RequestConfig; |
||||
|
import org.apache.http.client.entity.UrlEncodedFormEntity; |
||||
|
import org.apache.http.client.methods.CloseableHttpResponse; |
||||
|
import org.apache.http.client.methods.HttpGet; |
||||
|
import org.apache.http.client.methods.HttpPost; |
||||
|
import org.apache.http.client.methods.HttpRequestBase; |
||||
|
import org.apache.http.entity.StringEntity; |
||||
|
import org.apache.http.impl.client.CloseableHttpClient; |
||||
|
import org.apache.http.impl.client.HttpClients; |
||||
|
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; |
||||
|
import org.apache.http.message.BasicNameValuePair; |
||||
|
import org.apache.http.util.EntityUtils; |
||||
|
|
||||
|
import java.io.IOException; |
||||
|
import java.io.UnsupportedEncodingException; |
||||
|
import java.nio.charset.StandardCharsets; |
||||
|
import java.util.ArrayList; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
/** |
||||
|
* @author YenHex |
||||
|
* @since 2022/2/28 |
||||
|
*/ |
||||
|
@Slf4j |
||||
|
public class HttpUtil { |
||||
|
|
||||
|
private static PoolingHttpClientConnectionManager cm; |
||||
|
private static RequestConfig requestConfig; |
||||
|
private static String UTF8 = "UTF-8"; |
||||
|
|
||||
|
private static void init() { |
||||
|
int poolSize = 10; |
||||
|
int connSize = 5; |
||||
|
int socketTimeout = 2000; |
||||
|
int reqTimeout = 2000; |
||||
|
int connTimeout = 2000; |
||||
|
if (cm == null) { |
||||
|
cm = new PoolingHttpClientConnectionManager(); |
||||
|
// 整个连接池最大连接数
|
||||
|
cm.setMaxTotal(poolSize); |
||||
|
// 每路由最大连接数,默认值是2
|
||||
|
cm.setDefaultMaxPerRoute(connSize); |
||||
|
// 建立构造器
|
||||
|
requestConfig = RequestConfig.custom() |
||||
|
// 设置连接超时
|
||||
|
.setConnectTimeout(connTimeout*1000) |
||||
|
// 设置从连接池获取连接实例的超时
|
||||
|
.setConnectionRequestTimeout(reqTimeout*1000) |
||||
|
// 设置读取超时
|
||||
|
.setSocketTimeout(socketTimeout*1000) |
||||
|
// 在提交请求之前 测试连接是否可用
|
||||
|
.build(); |
||||
|
} |
||||
|
} |
||||
|
/** 通过连接池获取HttpClient */ |
||||
|
private static CloseableHttpClient getHttpClient() { |
||||
|
init(); |
||||
|
return HttpClients.custom().setConnectionManager(cm).setDefaultRequestConfig(requestConfig).build(); |
||||
|
} |
||||
|
|
||||
|
public static HttpResult get(String url){ |
||||
|
HttpGet httpGet = new HttpGet(url); |
||||
|
httpGet.setHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"); |
||||
|
return getHttpResult(httpGet); |
||||
|
} |
||||
|
|
||||
|
/** post的URL的参数map请求 */ |
||||
|
public static HttpResult post(String url, String json) { |
||||
|
HttpPost httpPost = new HttpPost(url); |
||||
|
httpPost.setHeader("Accept","application/json"); |
||||
|
httpPost.setHeader("Content-Type","application/json"); |
||||
|
httpPost.setEntity(new StringEntity(json, StandardCharsets.UTF_8)); |
||||
|
return getHttpResult(httpPost); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 请求返回统一封装 |
||||
|
* @param request |
||||
|
* @return |
||||
|
*/ |
||||
|
private static HttpResult getHttpResult(HttpRequestBase request) { |
||||
|
CloseableHttpClient httpClient = getHttpClient(); |
||||
|
String errMsg = null; |
||||
|
Integer code = 500; |
||||
|
try { |
||||
|
CloseableHttpResponse response = httpClient.execute(request); |
||||
|
code = response.getStatusLine().getStatusCode(); |
||||
|
HttpEntity entity = response.getEntity(); |
||||
|
if (entity != null) { |
||||
|
String data = EntityUtils.toString(entity, UTF8); |
||||
|
response.close(); |
||||
|
HttpResult result = new HttpResult(code,null,data); |
||||
|
return result; |
||||
|
} |
||||
|
} catch (ClientProtocolException e) { |
||||
|
log.error(e.getMessage()); |
||||
|
errMsg = e.getMessage(); |
||||
|
} catch (IOException e) { |
||||
|
log.error(e.getMessage()); |
||||
|
errMsg = e.getMessage(); |
||||
|
} |
||||
|
return new HttpResult(code,errMsg); |
||||
|
} |
||||
|
|
||||
|
/** 中间工具 */ |
||||
|
private static ArrayList<NameValuePair> covertParams2NVPS(Map<String, Object> params) { |
||||
|
ArrayList<NameValuePair> pairs = new ArrayList<>(); |
||||
|
for (Map.Entry<String, Object> param : params.entrySet()) { |
||||
|
pairs.add(new BasicNameValuePair(param.getKey(), String.valueOf(param.getValue()))); |
||||
|
} |
||||
|
return pairs; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,16 @@ |
|||||
|
package com.qs.cost.common.utils; |
||||
|
|
||||
|
import java.util.UUID; |
||||
|
|
||||
|
/** |
||||
|
* @author YenHex |
||||
|
* @since 2022/2/28 |
||||
|
*/ |
||||
|
public class IdUtil { |
||||
|
|
||||
|
public static final IdWorker ID_WORKER = new IdWorker(0,0); |
||||
|
|
||||
|
public static Long getLong(){ |
||||
|
return ID_WORKER.nextId()-1541318968076140673L; |
||||
|
} |
||||
|
} |
@ -0,0 +1,155 @@ |
|||||
|
package com.qs.cost.common.utils; |
||||
|
|
||||
|
import java.lang.management.ManagementFactory; |
||||
|
import java.net.InetAddress; |
||||
|
import java.net.NetworkInterface; |
||||
|
|
||||
|
/** |
||||
|
* <p>名称:IdWorker.java</p> |
||||
|
* <p>描述:分布式自增长ID</p> |
||||
|
* <pre> |
||||
|
* Twitter的 Snowflake JAVA实现方案 |
||||
|
* </pre> |
||||
|
* 核心代码为其IdWorker这个类实现,其原理结构如下,我分别用一个0表示一位,用—分割开部分的作用: |
||||
|
* 1||0---0000000000 0000000000 0000000000 0000000000 0 --- 00000 ---00000 ---000000000000 |
||||
|
* 在上面的字符串中,第一位为未使用(实际上也可作为long的符号位),接下来的41位为毫秒级时间, |
||||
|
* 然后5位datacenter标识位,5位机器ID(并不算标识符,实际是为线程标识), |
||||
|
* 然后12位该毫秒内的当前毫秒内的计数,加起来刚好64位,为一个Long型。 |
||||
|
* 这样的好处是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和机器ID作区分), |
||||
|
* 并且效率较高,经测试,snowflake每秒能够产生26万ID左右,完全满足需要。 |
||||
|
* <p> |
||||
|
* 64位ID (42(毫秒)+5(机器ID)+5(业务编码)+12(重复累加)) |
||||
|
* @author USER |
||||
|
*/ |
||||
|
public class IdWorker { |
||||
|
|
||||
|
// 时间起始标记点,作为基准,一般取系统的最近时间(一旦确定不能变动)
|
||||
|
private final static long twepoch = 1288834974657L; |
||||
|
// 机器标识位数
|
||||
|
private final static long workerIdBits = 5L; |
||||
|
// 数据中心标识位数
|
||||
|
private final static long datacenterIdBits = 5L; |
||||
|
// 机器ID最大值
|
||||
|
private final static long maxWorkerId = -1L ^ (-1L << workerIdBits); |
||||
|
// 数据中心ID最大值
|
||||
|
private final static long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); |
||||
|
// 毫秒内自增位
|
||||
|
private final static long sequenceBits = 12L; |
||||
|
// 机器ID偏左移12位
|
||||
|
private final static long workerIdShift = sequenceBits; |
||||
|
// 数据中心ID左移17位
|
||||
|
private final static long datacenterIdShift = sequenceBits + workerIdBits; |
||||
|
// 时间毫秒左移22位
|
||||
|
private final static long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; |
||||
|
|
||||
|
private final static long sequenceMask = -1L ^ (-1L << sequenceBits); |
||||
|
/* 上次生产id时间戳 */ |
||||
|
private static long lastTimestamp = -1L; |
||||
|
// 0,并发控制
|
||||
|
private long sequence = 0L; |
||||
|
|
||||
|
private final long workerId; |
||||
|
// 数据标识id部分
|
||||
|
private final long datacenterId; |
||||
|
|
||||
|
public IdWorker(){ |
||||
|
this.datacenterId = getDatacenterId(maxDatacenterId); |
||||
|
this.workerId = getMaxWorkerId(datacenterId, maxWorkerId); |
||||
|
} |
||||
|
/** |
||||
|
* @param workerId 工作机器ID |
||||
|
* @param datacenterId 序列号 |
||||
|
*/ |
||||
|
public IdWorker(long workerId, long datacenterId) { |
||||
|
if (workerId > maxWorkerId || workerId < 0) { |
||||
|
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); |
||||
|
} |
||||
|
if (datacenterId > maxDatacenterId || datacenterId < 0) { |
||||
|
throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId)); |
||||
|
} |
||||
|
this.workerId = workerId; |
||||
|
this.datacenterId = datacenterId; |
||||
|
} |
||||
|
/** |
||||
|
* 获取下一个ID |
||||
|
* @return |
||||
|
*/ |
||||
|
public synchronized long nextId() { |
||||
|
long timestamp = timeGen(); |
||||
|
if (timestamp < lastTimestamp) { |
||||
|
throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); |
||||
|
} |
||||
|
|
||||
|
if (lastTimestamp == timestamp) { |
||||
|
// 当前毫秒内,则+1
|
||||
|
sequence = (sequence + 1) & sequenceMask; |
||||
|
if (sequence == 0) { |
||||
|
// 当前毫秒内计数满了,则等待下一秒
|
||||
|
timestamp = tilNextMillis(lastTimestamp); |
||||
|
} |
||||
|
} else { |
||||
|
sequence = 0L; |
||||
|
} |
||||
|
lastTimestamp = timestamp; |
||||
|
// ID偏移组合生成最终的ID,并返回ID
|
||||
|
long nextId = ((timestamp - twepoch) << timestampLeftShift) |
||||
|
| (datacenterId << datacenterIdShift) |
||||
|
| (workerId << workerIdShift) | sequence; |
||||
|
|
||||
|
return nextId; |
||||
|
} |
||||
|
|
||||
|
private long tilNextMillis(final long lastTimestamp) { |
||||
|
long timestamp = this.timeGen(); |
||||
|
while (timestamp <= lastTimestamp) { |
||||
|
timestamp = this.timeGen(); |
||||
|
} |
||||
|
return timestamp; |
||||
|
} |
||||
|
|
||||
|
private long timeGen() { |
||||
|
return System.currentTimeMillis(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取 maxWorkerId |
||||
|
*/ |
||||
|
protected static long getMaxWorkerId(long datacenterId, long maxWorkerId) { |
||||
|
StringBuffer mpid = new StringBuffer(); |
||||
|
mpid.append(datacenterId); |
||||
|
String name = ManagementFactory.getRuntimeMXBean().getName(); |
||||
|
if (!name.isEmpty()) { |
||||
|
/* |
||||
|
* GET jvmPid |
||||
|
*/ |
||||
|
mpid.append(name.split("@")[0]); |
||||
|
} |
||||
|
/* |
||||
|
* MAC + PID 的 hashcode 获取16个低位 |
||||
|
*/ |
||||
|
return (mpid.toString().hashCode() & 0xffff) % (maxWorkerId + 1); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 数据标识id部分 |
||||
|
*/ |
||||
|
protected static long getDatacenterId(long maxDatacenterId) { |
||||
|
long id = 0L; |
||||
|
try { |
||||
|
InetAddress ip = InetAddress.getLocalHost(); |
||||
|
NetworkInterface network = NetworkInterface.getByInetAddress(ip); |
||||
|
if (network == null) { |
||||
|
id = 1L; |
||||
|
} else { |
||||
|
byte[] mac = network.getHardwareAddress(); |
||||
|
id = ((0x000000FF & (long) mac[mac.length - 1]) |
||||
|
| (0x0000FF00 & (((long) mac[mac.length - 2]) << 8))) >> 6; |
||||
|
id = id % (maxDatacenterId + 1); |
||||
|
} |
||||
|
} catch (Exception e) { |
||||
|
System.out.println(" getDatacenterId: " + e.getMessage()); |
||||
|
} |
||||
|
return id; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,83 @@ |
|||||
|
package com.qs.cost.common.utils; |
||||
|
|
||||
|
import com.alibaba.fastjson.JSONObject; |
||||
|
import com.fasterxml.jackson.annotation.JsonInclude; |
||||
|
import com.fasterxml.jackson.core.JsonProcessingException; |
||||
|
//import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
|
import com.fasterxml.jackson.databind.JavaType; |
||||
|
//import com.fasterxml.jackson.databind.MapperFeature;
|
||||
|
import com.fasterxml.jackson.databind.MapperFeature; |
||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Jackson json序列化和反序列化工具类 |
||||
|
* @Author JcYen |
||||
|
* @Date 2019/6/3 |
||||
|
* @Version 1.0 |
||||
|
*/ |
||||
|
public class JsonUtil { |
||||
|
|
||||
|
/** |
||||
|
* jackson对象 |
||||
|
*/ |
||||
|
static final ObjectMapper MAPPER = new ObjectMapper(); |
||||
|
|
||||
|
static { |
||||
|
MAPPER.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true); |
||||
|
MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将对象转换成json字符串。 |
||||
|
*/ |
||||
|
public static String objectToJson(Object data) { |
||||
|
try { |
||||
|
String string = MAPPER.writeValueAsString(data); |
||||
|
return string; |
||||
|
} catch (JsonProcessingException e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 将json结果集转化为对象 |
||||
|
* |
||||
|
* @param jsonData json数据 |
||||
|
* @param beanType 对象中的object类型 |
||||
|
*/ |
||||
|
public static <T> T jsonToPojo(String jsonData, Class<T> beanType) { |
||||
|
try { |
||||
|
T t = MAPPER.readValue(jsonData, beanType); |
||||
|
return t; |
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将json数据转换成pojo对象list |
||||
|
*/ |
||||
|
public static <T> List<T> jsonToList(String jsonData, Class<T> beanType) { |
||||
|
JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType); |
||||
|
try { |
||||
|
List<T> list = MAPPER.readValue(jsonData, javaType); |
||||
|
return list; |
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
public static Map<String, Object> jsonToMap(String jsonStr){ |
||||
|
Map<String, Object> json = JSONObject.parseObject(jsonStr, Map.class); |
||||
|
return json; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,47 @@ |
|||||
|
package com.qs.cost.common.utils; |
||||
|
|
||||
|
import com.qs.cost.common.utils.model.DesUtils; |
||||
|
|
||||
|
/** |
||||
|
* @author YenHex |
||||
|
* @since 2022/2/25 |
||||
|
*/ |
||||
|
public class SecureUtil extends cn.hutool.crypto.SecureUtil { |
||||
|
|
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 加密 |
||||
|
* @param secretKey |
||||
|
* @param clientId |
||||
|
* @return |
||||
|
*/ |
||||
|
public static String desEncrypt(String secretKey,String clientId){ |
||||
|
String formatStr = clientId+"-"+System.currentTimeMillis(); |
||||
|
DesUtils des = new DesUtils(secretKey); |
||||
|
try { |
||||
|
return des.encrypt(formatStr); |
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 解密 |
||||
|
* @param secretKey |
||||
|
* @param encryptText |
||||
|
* @return clientId |
||||
|
*/ |
||||
|
public static String desDecrypt(String secretKey,String encryptText){ |
||||
|
DesUtils des = new DesUtils(secretKey); |
||||
|
try { |
||||
|
String formatStr = des.decrypt(encryptText); |
||||
|
return formatStr.split("-")[0]; |
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,123 @@ |
|||||
|
package com.qs.cost.common.utils; |
||||
|
|
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.http.MediaType; |
||||
|
import org.springframework.web.context.request.RequestContextHolder; |
||||
|
import org.springframework.web.context.request.ServletRequestAttributes; |
||||
|
|
||||
|
import javax.servlet.ServletException; |
||||
|
import javax.servlet.ServletRequest; |
||||
|
import javax.servlet.http.HttpServletRequest; |
||||
|
import javax.servlet.http.HttpServletResponse; |
||||
|
import java.io.BufferedReader; |
||||
|
import java.io.IOException; |
||||
|
import java.io.InputStream; |
||||
|
import java.io.InputStreamReader; |
||||
|
import java.nio.charset.StandardCharsets; |
||||
|
import java.util.Enumeration; |
||||
|
import java.util.HashMap; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
/** |
||||
|
* @author YenHex |
||||
|
* @since 2022/2/25 |
||||
|
*/ |
||||
|
@Slf4j |
||||
|
public class ServletUtil { |
||||
|
|
||||
|
/** |
||||
|
* 获取用户真实IP |
||||
|
* |
||||
|
* @return |
||||
|
*/ |
||||
|
public static String getIpAddress(HttpServletRequest request) { |
||||
|
// 优先取X-Real-IP
|
||||
|
String ip = request.getHeader("X-Real-IP"); |
||||
|
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
||||
|
ip = request.getHeader("x-forwarded-for"); |
||||
|
} |
||||
|
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
||||
|
ip = request.getRemoteAddr(); |
||||
|
if ("0:0:0:0:0:0:0:1".equals(ip)) { |
||||
|
ip = "undefined"; |
||||
|
} |
||||
|
} |
||||
|
if ("unknown".equalsIgnoreCase(ip)) { |
||||
|
ip = "undefined"; |
||||
|
return ip; |
||||
|
} |
||||
|
int pos = ip.indexOf(','); |
||||
|
if (pos >= 0) { |
||||
|
ip = ip.substring(0, pos); |
||||
|
} |
||||
|
return ip; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 判断本次请求的数据类型是否为json |
||||
|
* @param request request |
||||
|
* @return true: 是 JSON 数据; false: 非 json 数据 |
||||
|
*/ |
||||
|
public static boolean isJsonRequest(HttpServletRequest request) { |
||||
|
if (request.getContentType() != null) { |
||||
|
return request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE) || |
||||
|
request.getContentType().equals(MediaType.APPLICATION_JSON_UTF8_VALUE); |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取query参数 |
||||
|
* @param request |
||||
|
* @return |
||||
|
*/ |
||||
|
public static Map<String, String> getParameterMapAll(HttpServletRequest request) { |
||||
|
Enumeration<String> parameters = request.getParameterNames(); |
||||
|
Map<String, String> params = new HashMap<>(); |
||||
|
while (parameters.hasMoreElements()) { |
||||
|
String parameter = parameters.nextElement(); |
||||
|
String value = request.getParameter(parameter); |
||||
|
params.put(parameter, value); |
||||
|
} |
||||
|
return params; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取请求Body |
||||
|
* |
||||
|
* @param request |
||||
|
* @return |
||||
|
*/ |
||||
|
public static String getBodyString(ServletRequest request) { |
||||
|
StringBuilder sb = new StringBuilder(); |
||||
|
InputStream inputStream = null; |
||||
|
BufferedReader reader = null; |
||||
|
try { |
||||
|
inputStream = request.getInputStream(); |
||||
|
reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); |
||||
|
String line = ""; |
||||
|
while ((line = reader.readLine()) != null) { |
||||
|
sb.append(line); |
||||
|
} |
||||
|
} catch (IOException e) { |
||||
|
e.printStackTrace(); |
||||
|
} finally { |
||||
|
if (inputStream != null) { |
||||
|
try { |
||||
|
inputStream.close(); |
||||
|
} catch (IOException e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
} |
||||
|
if (reader != null) { |
||||
|
try { |
||||
|
reader.close(); |
||||
|
} catch (IOException e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return sb.toString(); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,132 @@ |
|||||
|
package com.qs.cost.common.utils; |
||||
|
|
||||
|
import java.text.NumberFormat; |
||||
|
import java.util.Random; |
||||
|
|
||||
|
/** |
||||
|
* @Description 创建字符串工具类 |
||||
|
* @Author JcYen |
||||
|
* @Date 2019/4/9 |
||||
|
* @Version v1.0 |
||||
|
**/ |
||||
|
public class StringCreateUtil { |
||||
|
|
||||
|
private static final String CHARSET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; |
||||
|
|
||||
|
private static final String CHARSET2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; |
||||
|
|
||||
|
/** |
||||
|
* 根据长度随机生成字符串(根据时间,有出现重复现象) |
||||
|
*/ |
||||
|
public static String randomTimeStr(int length) { |
||||
|
String randomStr = ""; |
||||
|
int randomInt; |
||||
|
Random random = new Random(System.currentTimeMillis()); |
||||
|
for (int i = 0; i < length; i++) { |
||||
|
randomInt = random.nextInt(CHARSET.length()); |
||||
|
randomStr += CHARSET.charAt(randomInt); |
||||
|
} |
||||
|
return randomStr; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* ID对应字符串匹配 |
||||
|
* @param id |
||||
|
* @return |
||||
|
*/ |
||||
|
public static String caveIdString(Long id){ |
||||
|
String idString = id.toString(); |
||||
|
String rs = ""; |
||||
|
for(int i=0;i<idString.length();i++){ |
||||
|
Integer c2idx = Integer.parseInt(idString.charAt(i)+""); |
||||
|
rs += CHARSET2.charAt(c2idx); |
||||
|
} |
||||
|
return reverseStr(rs); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 字符串倒序输出 |
||||
|
* @param str |
||||
|
* @return |
||||
|
*/ |
||||
|
private static String reverseStr(String str) { |
||||
|
StringBuffer buffer = new StringBuffer(str); |
||||
|
return buffer.reverse().toString().toLowerCase(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 根据长度随机生成字符串 |
||||
|
*/ |
||||
|
public static String randomStr(int length){ |
||||
|
Random random=new Random(); |
||||
|
StringBuffer sb=new StringBuffer(); |
||||
|
for(int i=0;i<length;i++){ |
||||
|
int number=random.nextInt(3); |
||||
|
long result=0; |
||||
|
switch(number){ |
||||
|
case 0: |
||||
|
result= Math.round(Math.random()*25+65); |
||||
|
sb.append(String.valueOf((char)result)); |
||||
|
break; |
||||
|
case 1: |
||||
|
result= Math.round(Math.random()*25+97); |
||||
|
sb.append(String.valueOf((char)result)); |
||||
|
break; |
||||
|
case 2: |
||||
|
sb.append(String.valueOf(new Random().nextInt(10))); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
return sb.toString(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 生成随机数字字符串 |
||||
|
*/ |
||||
|
public static String randomNumStr(int length) { |
||||
|
Random random = new Random(); |
||||
|
String result = ""; |
||||
|
for (int i = 0; i < length; i++) { |
||||
|
result += random.nextInt(10); |
||||
|
} |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 返回随机数 |
||||
|
* @param length |
||||
|
* @return |
||||
|
*/ |
||||
|
public static int randomNum(int length){ |
||||
|
String str = randomNumStr(length); |
||||
|
return Integer.parseInt(str); |
||||
|
} |
||||
|
|
||||
|
public static String ellipticalTitle(String title, Integer len){ |
||||
|
if(title!=null&&title.length()>len){ |
||||
|
return title.substring(len)+"..."; |
||||
|
}return title; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* description: 格式化数字,实现左侧补 0. |
||||
|
* @param num 格式化的数字 |
||||
|
* @param min 最小位数 |
||||
|
* @param max 最大位数 |
||||
|
*/ |
||||
|
public static String fill(int num , int min , int max) { |
||||
|
NumberFormat numberFormat = NumberFormat.getInstance(); |
||||
|
// 禁用数字格式化分组。 如: 000,001
|
||||
|
numberFormat.setGroupingUsed(false); |
||||
|
// 保留最小位数
|
||||
|
numberFormat.setMinimumIntegerDigits(min); |
||||
|
// 保留最大位数
|
||||
|
numberFormat.setMaximumIntegerDigits(max); |
||||
|
return numberFormat.format(num); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,20 @@ |
|||||
|
package com.qs.cost.common.utils; |
||||
|
|
||||
|
import org.springframework.util.StringUtils; |
||||
|
|
||||
|
/** |
||||
|
* @author YenHex |
||||
|
* @version 1.0 |
||||
|
* @date 2021/6/16 |
||||
|
**/ |
||||
|
public class StringUtil { |
||||
|
|
||||
|
public static boolean isEmpty(Object obj){ |
||||
|
return StringUtils.isEmpty(obj); |
||||
|
} |
||||
|
|
||||
|
public static boolean isNotEmpty(String str){ |
||||
|
return str!=null && str.trim().length()>0; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,126 @@ |
|||||
|
package com.qs.cost.common.utils.model; |
||||
|
|
||||
|
import java.security.Key; |
||||
|
|
||||
|
import javax.crypto.Cipher; |
||||
|
|
||||
|
/** |
||||
|
* 使用DES算法对字符串进行加密解密 (加密解密的操作步骤正好相反, 参考 {@link #encrypt(String)}, {@link #decrypt(String)}) |
||||
|
*/ |
||||
|
public class DesUtils { |
||||
|
private static String defaultSecretKey = "default_secret_key"; //默认密钥
|
||||
|
private Cipher encryptCipher = null; //加密器
|
||||
|
private Cipher decryptCipher = null; //解密器
|
||||
|
|
||||
|
public DesUtils() throws Exception { |
||||
|
this(defaultSecretKey); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param secretKey 加密解密使用的密钥 |
||||
|
*/ |
||||
|
public DesUtils(String secretKey) { |
||||
|
Key key; |
||||
|
try { |
||||
|
key = getKey(secretKey.getBytes()); |
||||
|
encryptCipher = Cipher.getInstance("DES"); |
||||
|
encryptCipher.init(Cipher.ENCRYPT_MODE, key); |
||||
|
decryptCipher = Cipher.getInstance("DES"); |
||||
|
decryptCipher.init(Cipher.DECRYPT_MODE, key); |
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 加密 (逻辑: 1. 将要加密的字符串转换为字节数组(byte array)<br/> |
||||
|
* 2. 将第一步的字节数组作为输入使用加密器(Cipher)的doFinal方法进行加密, 返回字节数组<br/> |
||||
|
* 3. 把加密后的字节数组转换成十六进制的字符串)<br/> |
||||
|
* @param strIn 要加密的字符串 |
||||
|
* @return 返回加密后的十六进制字符串 |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public String encrypt(String strIn) throws Exception { |
||||
|
return byteArr2HexStr(encrypt(strIn.getBytes())); |
||||
|
} |
||||
|
|
||||
|
public byte[] encrypt(byte[] arrB) throws Exception { |
||||
|
return encryptCipher.doFinal(arrB); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 解密 (逻辑: 1. 把加密后的十六进制字符串转换成字节数组(byte array)<br/> |
||||
|
* 2. 将第一步的字节数组作为输入使用加密器(Cipher)的doFinal方法进行解密, 返回字节数组(byte array)<br/> |
||||
|
* 3. 把解密后的字节数组转换成字符串)<br/> |
||||
|
* @param strIn |
||||
|
* @return |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public String decrypt(String strIn) throws Exception { |
||||
|
return new String(decrypt(hexStr2ByteArr(strIn))); |
||||
|
} |
||||
|
|
||||
|
public byte[] decrypt(byte[] arrB) throws Exception { |
||||
|
return decryptCipher.doFinal(arrB); |
||||
|
} |
||||
|
|
||||
|
public static String byteArr2HexStr(byte[] arrB) throws Exception { |
||||
|
int iLen = arrB.length; |
||||
|
// 每个byte用两个字符才能表示,所以字符串的长度是数组长度的两倍
|
||||
|
StringBuffer sb = new StringBuffer(iLen * 2); |
||||
|
for (int i = 0; i < iLen; i++) { |
||||
|
int intTmp = arrB[i]; |
||||
|
// 把负数转换为正数
|
||||
|
while (intTmp < 0) { |
||||
|
intTmp = intTmp + 256; |
||||
|
} |
||||
|
// 小于0F的数需要在前面补0
|
||||
|
if (intTmp < 16) { |
||||
|
sb.append("0"); |
||||
|
} |
||||
|
sb.append(Integer.toString(intTmp, 16)); |
||||
|
} |
||||
|
return sb.toString(); |
||||
|
} |
||||
|
|
||||
|
public static byte[] hexStr2ByteArr(String strIn) throws Exception { |
||||
|
byte[] arrB = strIn.getBytes(); |
||||
|
int iLen = arrB.length; |
||||
|
// 两个字符表示一个字节,所以字节数组长度是字符串长度除以2
|
||||
|
byte[] arrOut = new byte[iLen / 2]; |
||||
|
for (int i = 0; i < iLen; i = i + 2) { |
||||
|
String strTmp = new String(arrB, i, 2); |
||||
|
arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16); |
||||
|
} |
||||
|
return arrOut; |
||||
|
} |
||||
|
|
||||
|
private Key getKey(byte[] arrBTmp) throws Exception { |
||||
|
// 创建一个空的8位字节数组(默认值为0)
|
||||
|
byte[] arrB = new byte[8]; |
||||
|
// 将原始字节数组转换为8位
|
||||
|
for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) { |
||||
|
arrB[i] = arrBTmp[i]; |
||||
|
} |
||||
|
// 生成密钥
|
||||
|
Key key = new javax.crypto.spec.SecretKeySpec(arrB, "DES"); |
||||
|
return key; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 用法实例 |
||||
|
*/ |
||||
|
public static void main(String[] args) { |
||||
|
try { |
||||
|
String test = "liwc"; |
||||
|
DesUtils des = new DesUtils("leemenz"); //自定义密钥
|
||||
|
System.out.println("加密前的字符:" + test); |
||||
|
System.out.println("加密后的字符:" + des.encrypt(test)); |
||||
|
System.out.println("解密后的字符:" + des.decrypt(des.encrypt(test))); |
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,24 @@ |
|||||
|
package com.qs.cost.module.controller; |
||||
|
|
||||
|
import com.qs.cost.common.dto.R; |
||||
|
import com.qs.cost.common.dto.u8.U8CallbackVo; |
||||
|
import com.qs.cost.common.utils.JsonUtil; |
||||
|
import lombok.AllArgsConstructor; |
||||
|
import org.springframework.web.bind.annotation.*; |
||||
|
|
||||
|
/** |
||||
|
* @author YenHex |
||||
|
* @since 2022/7/7 |
||||
|
*/ |
||||
|
@AllArgsConstructor |
||||
|
@RestController |
||||
|
@RequestMapping("/u8") |
||||
|
public class LzOrderController { |
||||
|
|
||||
|
@PostMapping("/callback") |
||||
|
public R callback(@RequestBody U8CallbackVo requestVo){ |
||||
|
System.out.println(JsonUtil.objectToJson(requestVo)); |
||||
|
return R.ok(); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,64 @@ |
|||||
|
package com.qs.cost.module.domain; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.annotation.TableField; |
||||
|
import com.baomidou.mybatisplus.annotation.TableId; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.util.Date; |
||||
|
|
||||
|
/** |
||||
|
* @author YenHex |
||||
|
* @since 2022/9/27 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class VmSupplierPo { |
||||
|
|
||||
|
@TableId(value = "serialNumber") |
||||
|
private String serialNumber; |
||||
|
|
||||
|
@TableField(value = "empNo") |
||||
|
private String empNo; |
||||
|
|
||||
|
@TableField(value = "name") |
||||
|
private String name; |
||||
|
|
||||
|
@TableField(value = "applyDate") |
||||
|
private Date applyDate; |
||||
|
|
||||
|
@TableField(value = "applyType") |
||||
|
private String applyType; |
||||
|
|
||||
|
@TableField(value = "cVenCode") |
||||
|
private String cVenCode; |
||||
|
|
||||
|
@TableField(value = "cVenName") |
||||
|
private String cVenName; |
||||
|
|
||||
|
@TableField(value = "cVenAbbName") |
||||
|
private String cVenAbbName; |
||||
|
|
||||
|
@TableField(value = "cVCCode") |
||||
|
private String cVCCode; |
||||
|
|
||||
|
@TableField(value = "cVCName") |
||||
|
private String cVCName; |
||||
|
|
||||
|
@TableField(value = "cDCCode") |
||||
|
private String cDCCode; |
||||
|
|
||||
|
@TableField(value = "cDCName") |
||||
|
private String cDCName; |
||||
|
|
||||
|
@TableField(value = "cCusAddress") |
||||
|
private String cCusAddress; |
||||
|
|
||||
|
@TableField(value = "cCusEmail") |
||||
|
private String cCusEmail; |
||||
|
|
||||
|
@TableField(value = "cCusPerson") |
||||
|
private String cCusPerson; |
||||
|
|
||||
|
@TableField(value = "cCusPhone") |
||||
|
private String cCusPhone; |
||||
|
|
||||
|
} |
@ -0,0 +1,39 @@ |
|||||
|
package com.qs.cost.module.domain.dto; |
||||
|
|
||||
|
import com.fasterxml.jackson.annotation.JsonProperty; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* Vendor t = new Vendor(); |
||||
|
* t.Editprop = "A";//编辑属性:A表新增,M表修改 string类型
|
||||
|
* t.cVenCode = "01020302";//供应商编码 (必填)
|
||||
|
* t.cVenName = "测试名称";//供应商名称 (必填)
|
||||
|
* t.cVenAbbName = "测试";//供应商简称
|
||||
|
* t.cVCCode = "01";//供应商分类编码(必填)
|
||||
|
* t.cDCCode = "";//地区编码
|
||||
|
* |
||||
|
* @author YenHex |
||||
|
* @since 2022/9/27 |
||||
|
*/ |
||||
|
@Data |
||||
|
public class U8Vendor { |
||||
|
|
||||
|
@JsonProperty("Editprop") |
||||
|
private String editprop; |
||||
|
|
||||
|
@JsonProperty("cVenCode") |
||||
|
private String cVenCode; |
||||
|
|
||||
|
@JsonProperty("cVenName") |
||||
|
private String cVenName; |
||||
|
|
||||
|
@JsonProperty("cVenAbbName") |
||||
|
private String cVenAbbName; |
||||
|
|
||||
|
@JsonProperty("cVCCode") |
||||
|
private String cVcCode; |
||||
|
|
||||
|
@JsonProperty("cDCCode") |
||||
|
private String cDCCode; |
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
package com.qs.cost.module.mapper; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
|
import com.qs.cost.module.domain.VmSupplierPo; |
||||
|
import org.apache.ibatis.annotations.Mapper; |
||||
|
|
||||
|
/** |
||||
|
* @author YenHex |
||||
|
* @since 2022/9/27 |
||||
|
*/ |
||||
|
public interface VmSupplierMapper extends BaseMapper<VmSupplierPo> { |
||||
|
|
||||
|
} |
@ -0,0 +1,59 @@ |
|||||
|
package com.qs.cost.module.service; |
||||
|
|
||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
||||
|
import com.qs.cost.common.conf.MainServerProperties; |
||||
|
import com.qs.cost.common.dto.u8.U8RequestBo; |
||||
|
import com.qs.cost.common.utils.HttpUtil; |
||||
|
import com.qs.cost.common.utils.JsonUtil; |
||||
|
import com.qs.cost.module.domain.VmSupplierPo; |
||||
|
import com.qs.cost.module.domain.dto.U8Vendor; |
||||
|
import com.qs.cost.module.mapper.VmSupplierMapper; |
||||
|
import lombok.AllArgsConstructor; |
||||
|
import org.springframework.stereotype.Service; |
||||
|
|
||||
|
import java.time.LocalDateTime; |
||||
|
import java.util.Arrays; |
||||
|
import java.util.List; |
||||
|
/** |
||||
|
* @author YenHex |
||||
|
* @since 2022/9/27 |
||||
|
*/ |
||||
|
@Service |
||||
|
@AllArgsConstructor |
||||
|
public class VmSupplierService { |
||||
|
|
||||
|
private final VmSupplierMapper vmSupplierMapper; |
||||
|
private final MainServerProperties mainServerProperties; |
||||
|
|
||||
|
public void test() { |
||||
|
String host = mainServerProperties.getHost(); |
||||
|
String year = mainServerProperties.getYear(); |
||||
|
String book = mainServerProperties.getBook(); |
||||
|
List<VmSupplierPo> supplierPoList = vmSupplierMapper.selectList(new QueryWrapper<>()); |
||||
|
for (VmSupplierPo supplierPo : supplierPoList) { |
||||
|
U8Vendor vendor = new U8Vendor(); |
||||
|
//编辑属性:A表新增,M表修改 string类型
|
||||
|
vendor.setEditprop("A"); |
||||
|
vendor.setCVenCode(supplierPo.getCVenCode()); |
||||
|
vendor.setCVenName(supplierPo.getCVenName()); |
||||
|
vendor.setCVenAbbName(supplierPo.getCVenAbbName()); |
||||
|
vendor.setCDCCode(supplierPo.getCDCCode()); |
||||
|
vendor.setCVcCode(supplierPo.getCVCCode()); |
||||
|
String jsonBody = JsonUtil.objectToJson(vendor); |
||||
|
//发起U8服务中台
|
||||
|
U8RequestBo requestBo = new U8RequestBo(); |
||||
|
requestBo.setPk(vendor.getCVenCode()); |
||||
|
requestBo.setCmd("BasicVendor"); |
||||
|
requestBo.setYear(year); |
||||
|
requestBo.setBook(book); |
||||
|
requestBo.setJsonBody(jsonBody); |
||||
|
requestBo.setKeyId(""); |
||||
|
requestBo.setSettingRetryTimes(2); |
||||
|
requestBo.setCallbackState("1"); |
||||
|
requestBo.setCallbackHost( host + "/lzOrder/callback"); |
||||
|
HttpUtil.post(mainServerProperties.getU8url(),JsonUtil.objectToJson(requestBo)); |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,34 @@ |
|||||
|
#服务配置 |
||||
|
server: |
||||
|
port: 7101 |
||||
|
#本服务访问根地址,用于回调 |
||||
|
host: 'http://127.0.0.1:7101' |
||||
|
#帐套 |
||||
|
book: 999 |
||||
|
#年份 |
||||
|
year: 2020 |
||||
|
#U8平台 |
||||
|
u8url: http://127.0.0.1:7100/api/jobRequest |
||||
|
#SpringBoot相关 |
||||
|
spring: |
||||
|
#数据源 |
||||
|
datasource: |
||||
|
#url: jdbc:mysql://127.0.0.1:3333/jsl_cost_api?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai |
||||
|
url: jdbc:sqlserver://192.168.10.7:1433;DatabaseName=JSLGROUPDB |
||||
|
username: sa |
||||
|
password: '#JSL2282125' |
||||
|
#driverClassName: com.mysql.cj.jdbc.Driver |
||||
|
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver |
||||
|
#mybatis plus |
||||
|
mybatis-plus: |
||||
|
type-aliases-package: com.qs.cost.module.domain |
||||
|
configuration: |
||||
|
map-underscore-to-camel-case: true |
||||
|
global-config: |
||||
|
banner: false |
||||
|
db-config: |
||||
|
logic-delete-value: 1 # 逻辑已删除值(默认为 1) |
||||
|
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0) |
||||
|
# 日志配置 |
||||
|
logging: |
||||
|
config: classpath:logback-spring.xml |
@ -0,0 +1,3 @@ |
|||||
|
spring: |
||||
|
profiles: |
||||
|
active: dev |
@ -0,0 +1,51 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<configuration> |
||||
|
<!-- 文件输出格式 --> |
||||
|
<property name="PATTERN" |
||||
|
value="%boldMagenta(%-12(%d{yyyy-MM-dd HH:mm:ss.SSS})) |- %highlight(%-5level) %cyan([%thread]) %green(%c [%L]) -| %msg%n"/> |
||||
|
<property name="LOG_NAME" value="qs"/> |
||||
|
<!--所在项目包 打印日志用--> |
||||
|
<property name="PACKAGE_NAME" value="com.qs"/> |
||||
|
<!-- test文件路径 --> |
||||
|
<property name="TEST_FILE_PATH" value="logs/${LOG_NAME}"/> |
||||
|
<!-- pro文件路径 --> |
||||
|
<property name="PROD_FILE_PATH" value="logs/${LOG_NAME}"/> |
||||
|
|
||||
|
<!-- 开发环境 --> |
||||
|
<springProfile name="dev"> |
||||
|
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> |
||||
|
<encoder> |
||||
|
<pattern>${PATTERN}</pattern> |
||||
|
</encoder> |
||||
|
</appender> |
||||
|
<!-- 输出到文件 --> |
||||
|
<logger name="org.springframework.jdbc.core.JdbcTemplate" level="INFO"/> |
||||
|
<logger name="${PACKAGE_NAME}" level="debug"/> |
||||
|
<root level="info"> |
||||
|
<appender-ref ref="CONSOLE"/> |
||||
|
</root> |
||||
|
</springProfile> |
||||
|
|
||||
|
<!-- 生产环境 --> |
||||
|
<springProfile name="prod"> |
||||
|
<appender name="PROD_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
||||
|
<file>${PROD_FILE_PATH}${file.separator}${LOG_NAME}.log</file> |
||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> |
||||
|
<!-- rollover daily --> |
||||
|
<fileNamePattern>${PROD_FILE_PATH}${file.separator}${LOG_NAME}-%d{yyyy-MM-dd}.%i.log</fileNamePattern> |
||||
|
<!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB --> |
||||
|
<maxHistory>7</maxHistory> |
||||
|
<maxFileSize>100MB</maxFileSize> |
||||
|
<totalSizeCap>1GB</totalSizeCap> |
||||
|
</rollingPolicy> |
||||
|
<encoder> |
||||
|
<pattern> |
||||
|
[%date{yyyy-MM-dd HH:mm:ss.SSS}] %X{logthreadId} %-5level %logger{80} %method %line - %msg%n |
||||
|
</pattern> |
||||
|
</encoder> |
||||
|
</appender> |
||||
|
<root level="info"> |
||||
|
<appender-ref ref="PROD_FILE"/> |
||||
|
</root> |
||||
|
</springProfile> |
||||
|
</configuration> |
Loading…
Reference in new issue