推荐理由:
案例
// 配置查询条件
EntityWrapper accountWrapper = new EntityWrapper<>();
accountWrapper
.like(!StringUtils.isBlank(account),
"alipay_account", account)
.like(!StringUtils.isBlank(name), "alipay_name", name)
.like(!StringUtils.isBlank(aging), "aging", aging)
.eq(null != isOpen, "is_open", isOpen)
.eq("is_delete", 0);
Page page = this.selectPage(new Page<>(query.getCurrent(), query.getSize()), accountWrapper);
推荐理由:Lombok能以简单的注解形式来简化java代码,提高开发人员的开发效率。例如开发中经常需要写的javabean,都需要花时间去添加相应的getter/setter,也许还要去写构造器、equals等方法,而且需要维护,当属性多时会出现大量的getter/setter方法,这些显得很冗长也没有太多技术含量,一旦修改属性,就容易出现忘记修改对应方法的失误。
Lombok能通过注解的方式,在编译时自动为属性生成构造器、getter/setter、equals、hashcode、toString方法。出现的神奇就是在源码中没有getter和setter方法,但是在编译生成的字节码文件中有getter和setter方法。这样就省去了手动重建这些代码的麻烦,使代码看起来更简洁些。
example:
org.projectlombok
lombok
1.16.20
provided
Lombok有哪些注解
@Setter
@Getter
@Data
@Log(这是一个泛型注解,具体有很多种形式)
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@NonNull
@Cleanup
@ToString
@RequiredArgsConstructor
@Value
@SneakyThrows
@Synchronized
Spring RestTemplate 是 Spring 提供的用于访问 Rest 服务的客户端,RestTemplate 提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率,
结合spring cloud ribbon和fegin起到很好的效果,同时使用httpClient工具的不可维护性的问题,httpClient得到的response需要大量的json解析,使得系统维护麻烦。
example:
package com.fahui.core.live.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.fahui.common.exceptions.LawBizException;
import com.fahui.core.live.beans.channel.*;
import com.fahui.core.live.beans.vod.video.GetRequest;
import com.fahui.core.live.beans.vod.video.GetResponse;
import com.fahui.core.live.constants.LiveConstant;
import com.fahui.core.live.service.IFhLiveService;
import com.fahui.core.service.entity.FhLiveChannel;
import com.fahui.core.service.service.IFhLiveChannelService;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
/**
* @Description:
* @author:CAIYJ
* @Date:2018/7/21 10:14
*/
@Service
public class FhLiveServiceImpl implements IFhLiveService {
@Autowired
private IFhLiveChannelService liveChannelService;
@Autowired
@Qualifier("wyRestTemplate")
private RestTemplate restTemplate;
private static String prfixUrl = "https://vcloud.163.com";
@Override
public VodVideoListResponse vodVideoList(VodVideoListRequest request) throws Exception {
BaseResponseGeneric response = restTemplate.exchange(prfixUrl+"/app/vodvideolist",
HttpMethod.POST,
new HttpEntity<>(request),
new ParameterizedTypeReference>() {
}).getBody();
checkResponseGeneric(response);
return response != null ? response.getRet() : null;
}
@Override
public boolean setCallback(SetCallbackRequest request) throws Exception {
BaseResponse response = restTemplate.postForObject(prfixUrl+"/app/record/setcallback", request, BaseResponse.class);
checkResponse(response);
return true;
}
@Override
public boolean merge(MergeRequest request) throws Exception {
BaseResponse response = restTemplate.postForObject(prfixUrl+"/app/video/merge", request, BaseResponse.class);
checkResponse(response);
return true;
}
@Override
public boolean resetRecord(ResetRecordRequest request) throws Exception {
BaseResponse response = restTemplate.postForObject(prfixUrl+"/app/channel/resetRecord", request, BaseResponse.class);
checkResponse(response);
return true;
}
@Override
public TransCodeAddressResponse transCodeAddress(TransCodeAddressRequest request) throws Exception {
BaseResponse response = restTemplate.postForObject(prfixUrl+"/app/transcodeAddress", request, BaseResponse.class);
checkResponse(response);
TransCodeAddressResponse transCodeAddressResponse = new TransCodeAddressResponse();
BeanUtils.populate(transCodeAddressResponse, response.getRet());
return transCodeAddressResponse;
}
@Override
public CallbackQueryResponse callbackQuery() throws Exception {
BaseResponse response = restTemplate.postForObject(prfixUrl+"/app/record/callbackQuery", null, BaseResponse.class);
checkResponse(response);
CallbackQueryResponse callbackQueryResponse = new CallbackQueryResponse();
BeanUtils.populate(callbackQueryResponse, response.getRet());
return callbackQueryResponse;
}
@Override
public boolean setupRecordInfo(SetupRecordInfoRequest request) throws Exception {
if (null == request) {
return false;
}
BaseResponse response = restTemplate.postForObject(prfixUrl+"/app/channel/setupRecordInfo", request, BaseResponse.class);
checkResponse(response);
QueryWrapper ew = new QueryWrapper<>();
ew.eq(StringUtils.isNotEmpty(request.getCid()), "cid", request.getCid());
FhLiveChannel liveChannel = new FhLiveChannel();
BeanUtils.copyProperties(liveChannel, request);
liveChannelService.update(liveChannel, ew);
return true;
}
@Override
public GetResponse getVideo(GetRequest request) throws Exception {
BaseResponseGeneric response = restTemplate.exchange(prfixUrl+"/app/vod/video/get",
HttpMethod.POST,
new HttpEntity<>(request),
new ParameterizedTypeReference>() {
}).getBody();
checkResponseGeneric(response);
return response != null ? response.getRet() : null;
}
private void checkResponseGeneric(BaseResponseGeneric> response) throws Exception {
if (null == response) {
throw new LawBizException(602, "查询失败", null);
} else {
switch (response.getCode()) {
case 200:
return;
default:
throw new LawBizException(response.getCode(), response.getMsg(), null);
}
}
}
private void checkResponse(BaseResponse response) throws Exception {
if (null != response) {
switch (response.getCode()) {
case 200:
return;
default:
throw new LawBizException(response.getCode(), response.getMsg(), null);
}
} else {
throw new LawBizException(602, "查询失败", null);
}
}
}
4:hibernate-validator
理由:
1:使用注解的形式将参数校验与业务代码分离
2:定义通用的validator,切面的形式切入到业务代码中
3:结合spring boot中的全局异常捕捉,系统原理繁琐的入参校验
package com.fahui.liquidation.receiver.bean.po.example;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.*;
import java.util.Date;
import java.util.List;
/**
* @Description:
* @author:CAIYJ
* @Date:2018/8/13 11:34
*/
@Data
public class ConstraintExample {
private Integer id;
//---------------------------------------------Bean Validation 中内置的 constraint-------------------------------------
/**
* 被注释的元素必须不为 null(任何对象的value不能为null)_
*/
@NotNull
private String name;
/**
* 被注释的元素必须为 true
*/
@AssertTrue
private Boolean assertTrue;
/**
* 被注释的元素必须为 false
*/
@AssertFalse
private Boolean assertFalse;
/**
* 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
*/
@Min(11)
private Integer min;
/**
* 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
*/
@Max(60)
private Integer max;
/**
* 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
*/
@DecimalMin("11")
private String decimalMin;
/**
* 注释的元素必须是一个数字,其值必须小于等于指定的最大值
*/
@DecimalMax("60")
private String decimalMax;
/**
* 被注释的元素的大小必须在指定的范围内
*/
@Size(min = 11, max = 60, message = "大小在11-60之間")
private String size;
/**
* 被注释的元素必须是一个数字,其值必须在可接受的范围内
*/
@Digits(integer = 11, fraction = 60, message = "范围在11-60之间")
private Integer digits;
/**
* 被注释的元素必须是一个过去的日期
*/
@Past(message = "被注释的元素必须是一个过去的日期")
private Date past;
/**
* 被注释的元素必须是一个将来的日期
*/
@Future(message = "被注释的元素必须是一个将来的日期")
private Date future;
@Pattern(regexp = "^[0-9]{4}-[0-9]{2}-[0-9]{2}$", message = "出生日期格式不正确")
private String birth;
//---------------------------------------------Hibernate Validator 附加的 constraint-------------------------------------
/**
* 被注释的元素必须是电子邮箱地址
*/
@Email(message = "须是电子邮箱地址")
private String email;
/**
* 被注释的字符串的大小必须在指定的范围内
*/
@Length(min = 11, max = 60, message = "字符串长度在11-60之间")
private String length;
/**
* 被注释的字符串的必须非空(集合对象的元素不为0,即集合不为空,也可以用于字符串不为null)
*/
@NotEmpty
private List notEmpty;
@Range(min = 18, max = 30, message = "年龄限制在18-30岁之间")
private Integer age;
/**
* 被注释的字符串的必须非空
*/
@NotBlank(message = "字符必须非空")
private String notBlank;
}
package com.fahui.validator.example;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
/**
* @Description:不能存在空字符串
* @author:CAIYJ
* @Date:2018/8/16 16:57
*/
public class CannotContainSpacesValidator implements ConstraintValidator {
private int len;
/**
* 初始参数,获取注解中length的值
*/
@Override
public void initialize(CannotContainSpaces arg0) {
this.len = arg0.length();
}
@Override
public boolean isValid(String str, ConstraintValidatorContext constraintValidatorContext) {
if (str != null) {
if (str.indexOf(" ") < 0) {
return true;
}
} else {
constraintValidatorContext.disableDefaultConstraintViolation();//禁用默认的message的值
//重新添加错误提示语句
constraintValidatorContext
.buildConstraintViolationWithTemplate("字符串不能为空").addConstraintViolation();
}
return false;
}
}
理由:使用该jar中的消息转换,可以全局解决返给前端数据的问题
/**
* 增加消息转换器,将返回消息中的 null 转成空字符串
*
* @param converters
*/
@Override
protected void configureMessageConverters(List> converters) {
FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter();
FastJsonConfig fjc = new FastJsonConfig();
//1、序列化重点
fjc.setSerializerFeatures(SerializerFeature.BrowserCompatible);
//是否输出值为null的字段,默认为false
fjc.setSerializerFeatures(SerializerFeature.WriteMapNullValue,
// Boolean字段如果为null,输出为false,而非null
SerializerFeature.WriteNullBooleanAsFalse,
// 字符类型字段如果为null,输出为”“,而非null
SerializerFeature.WriteNullStringAsEmpty,
// Number类型为空则输出0
SerializerFeature.WriteNullNumberAsZero,
// 禁止循环引用
SerializerFeature.DisableCircularReferenceDetect,
// List为空则输出[]
SerializerFeature.WriteNullListAsEmpty);
// fjc.setSerializeFilters((ValueFilter) (o, s, source) -> {
// if (source instanceof Date) {
// return ((Date) source).getTime() + "";
// }
// return source;
// });
fastJsonConverter.setFastJsonConfig(fjc);
List mediaTypes;
mediaTypes = Arrays.asList(
MediaType.APPLICATION_JSON_UTF8,
MediaType.TEXT_PLAIN,
MediaType.TEXT_HTML,
MediaType.TEXT_XML,
MediaType.APPLICATION_OCTET_STREAM);
fastJsonConverter.setSupportedMediaTypes(mediaTypes);
fastJsonConverter.setDefaultCharset(Charset.forName("UTF-8"));
converters.add(fastJsonConverter);
}
理由:你懂得。最讨厌写word版本的接口文档了。。。
example:
@ApiOperation(value = "删除角色信息", notes = "删除角色信息", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@RequestMapping(value = "remove/{id}")
public BaseRestVO remove( @PathVariable Long id) throws Exception {
roloService.removeById(id);
return BaseRestVO.success("删除成功");
}
理由:一般大型系统是一个分布式部署的架构,不同的服务模块部署在不同的服务器上,问题出现时,大部分情况需要根据问题暴露的关键信息,定位到具体的服务器和服务模块,构建一套集中式日志系统,可以提高定位问题的效率。
一个完整的集中式日志系统,需要包含以下几个主要特点:
ELK提供了一整套解决方案,并且都是开源软件,之间互相配合使用,完美衔接,高效的满足了很多场合的应用。目前主流的一种日志系统。(es是个好东西)
理由:
Hutool是Hu + tool的自造词,前者致敬我的“前任公司”,后者为工具之意,谐音“糊涂”,寓意追求“万事都作糊涂观,无所谓失,无所谓得”的境界。
Hutool是一个Java工具包,也只是一个工具包,它帮助我们简化每一行代码,减少每一个方法,让Java语言也可以“甜甜的”。Hutool最初是我项目中“util”包的一个整理,后来慢慢积累并加入更多非业务相关功能,并广泛学习其它开源项目精髓,经过自己整理修改,最终形成丰富的开源工具集。(抄自作者简介),当然类似的也有Apache的commons包等
spring官网
springcloud中文官网
本人改过spring-data-elasticsearch,深知spring社区对elasticsearch封装的有多好。同时也是经历过原生elasticsearch java api代码转变到spring-data-elasticsearch的过程
http://shardingsphere.apache.org/