该项目停滞多时,终于在今日重启了!原来的开发模式,效率太低了。现在重启,为了提高开发效率,决定做一系列的升级改造。
引入Lombok
引入MyBatisPlus
引入Swagger
引入代码生成器
使用Java8新特性语法
......
2021年3月28日
一、引入Lombok
1、添加pom依赖
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.8</version> </dependency>
2、实体类增加注解
@Data @NoArgsConstructor
二、引入MybatisPlus
1、添加pom依赖
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.2</version> </dependency>
2、去除已有的mybatis依赖
3、修改实体类,增加注解
@Data
@NoArgsConstructor
@TableName("admin_user")
@ApiModel(value = "AdminUser", description = "管理用户")
public class AdminUser implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@ApiModelProperty("主键id")
@NotNull(message = "主键id不能为空")
@TableId(value = "id", type = IdType.AUTO)
private Integer userId;
/**
* 用户名
*/
@ApiModelProperty("用户名")
@Length(max = 255, message = "用户名长度不能超过255")
@TableField(value = "userName")
private String userName;
/**
* 密码
*/
@ApiModelProperty("密码")
@Length(max = 255, message = "密码长度不能超过255")
@TableField(value = "passWord")
private String passWord;
/**
* 昵称
*/
@ApiModelProperty("昵称")
@Length(max = 255, message = "昵称长度不能超过255")
@TableField(value = "nickName")
private String nickName;
/**
* 创建时间
*/
@ApiModelProperty("创建时间")
@TableField("createTime")
@JsonFormat(shape =JsonFormat.Shape.STRING,pattern="yyyy-MM-dd")
private LocalDate createTime;
/**
* 更新时间
*/
@ApiModelProperty("更新时间")
@TableField("updateTime")
@JsonFormat(shape =JsonFormat.Shape.STRING,pattern="yyyy-MM-dd")
private LocalDate updateTime;
/**
* 用户状态 1 启用,2 禁用
*/
@ApiModelProperty("用户状态 1 启用,2 禁用")
@TableField("userStatus")
private String userStatus;
/**
* 是否是超级管理员
*/
@ApiModelProperty("是否是超级管理员")
@TableField("superUser")
private String superUser;
}4、service继承IService
public interface IAdminUserService extends IService<AdminUser>
5、serviceImpl继承ServiceImpl
public class AdminUserServiceImpl extends ServiceImpl<IAdminUserMapper, AdminUser> implements IAdminUserService
6、mapper继承BaseMapper
public interface IAdminUserMapper extends BaseMapper<AdminUser>
三、引入Swagger
1、增加pom依赖 使用其他的swaggerUI
<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <exclusions> <exclusion> <groupId>io.swagger</groupId> <artifactId>swagger-models</artifactId> </exclusion> </exclusions> <version>2.9.2</version> </dependency> <dependency> <groupId>io.swagger</groupId> <artifactId>swagger-models</artifactId> <version>1.5.21</version> </dependency> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>swagger-bootstrap-ui</artifactId> <version>1.9.6</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-bean-validators</artifactId> <version>2.9.2</version> </dependency>
2、添加如下三个文件
package com.zjh.swagger2;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.github.xiaoymin.swaggerbootstrapui.configuration.SwaggerBootstrapUIConfiguration;
import com.github.xiaoymin.swaggerbootstrapui.filter.ProductionSecurityFilter;
import com.github.xiaoymin.swaggerbootstrapui.filter.SecurityBasicAuthFilter;
import io.swagger.models.MarkdownFiles;
import lombok.extern.slf4j.Slf4j;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* Swagger2 启动类
* 启动条件:
* 1,配置文件中zxw.swagger.enabled=true
* 2,配置文件中不存在:zxw.swagger.enabled 值
*
*/
@Configuration
@ConditionalOnProperty(name = "zxw.swagger.enabled", havingValue = "true", matchIfMissing = true)
@EnableSwagger2
/*@EnableSwaggerBootstrapUI*/
@Import({BeanValidatorPluginsConfiguration.class, SwaggerBootstrapUIConfiguration.class, Swagger2Configuration.ZxwSecurityConfiguration.class})
public class Swagger2Configuration implements WebMvcConfigurer {
/**
* 这个地方要重新注入一下资源文件,不然不会注入资源的,也没有注入requestHandlerMappping,相当于xml配置的
* <!--swagger资源配置-->
* <mvc:resources location="classpath:/META-INF/resources/" mapping="swagger-ui.html"/>
* <mvc:resources location="classpath:/META-INF/resources/webjars/" mapping="/webjars/**"/>
* 不知道为什么,这也是spring boot的一个缺点(菜鸟觉得的)
*
* @param registry
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
@Slf4j
public static class ZxwSecurityConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(name = "zxw.swagger.production", havingValue = "true")
public ProductionSecurityFilter productionSecurityFilter(SwaggerProperties swaggerProperties) {
return new ProductionSecurityFilter(swaggerProperties.getProduction());
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(name = "zxw.swagger.basic.enable", havingValue = "true")
public SecurityBasicAuthFilter securityBasicAuthFilter(SwaggerProperties swaggerProperties) {
SwaggerProperties.Basic basic = swaggerProperties.getBasic();
return new SecurityBasicAuthFilter(basic.getEnable(), basic.getUsername(), basic.getPassword());
}
@Bean(initMethod = "init")
@ConditionalOnMissingBean
@ConditionalOnProperty(name = "zxw.swagger.markdown.enable", havingValue = "true")
public MarkdownFiles markdownFiles(SwaggerProperties swaggerProperties) {
return new MarkdownFiles(swaggerProperties.getMarkdown().getBasePath());
}
}
}package com.zjh.swagger2;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.web.bind.annotation.RequestMethod;
import com.github.xiaoymin.swaggerbootstrapui.model.OrderExtensions;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Lists;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.builders.ResponseMessageBuilder;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.Contact;
import springfox.documentation.service.Parameter;
import springfox.documentation.service.ResponseMessage;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
/**
* swagger 包扫描配置
* @Description:
*/
@Import({
Swagger2Configuration.class
})
@EnableConfigurationProperties(SwaggerProperties.class)
public class SwaggerAutoConfiguration implements BeanFactoryAware {
private static final String AUTH_KEY = "token";
@Autowired
SwaggerProperties swaggerProperties;
private BeanFactory beanFactory;
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(name = "zxw.swagger.enabled", havingValue = "true", matchIfMissing = true)
public List<Docket> createRestApi() {
ConfigurableBeanFactory configurableBeanFactory = (ConfigurableBeanFactory) beanFactory;
List<Docket> docketList = new LinkedList<>();
// 没有分组
if (swaggerProperties.getDocket().isEmpty()) {
final Docket docket = createDocket(swaggerProperties);
configurableBeanFactory.registerSingleton(swaggerProperties.getTitle(), docket);
docketList.add(docket);
return docketList;
}
// 分组创建
for (String groupName : swaggerProperties.getDocket().keySet()) {
SwaggerProperties.DocketInfo docketInfo = swaggerProperties.getDocket().get(groupName);
ApiInfo apiInfo = new ApiInfoBuilder()
.title(docketInfo.getTitle().isEmpty() ? swaggerProperties.getTitle() : docketInfo.getTitle())
.description(docketInfo.getDescription().isEmpty() ? swaggerProperties.getDescription() : docketInfo.getDescription())
.version(docketInfo.getVersion().isEmpty() ? swaggerProperties.getVersion() : docketInfo.getVersion())
.license(docketInfo.getLicense().isEmpty() ? swaggerProperties.getLicense() : docketInfo.getLicense())
.licenseUrl(docketInfo.getLicenseUrl().isEmpty() ? swaggerProperties.getLicenseUrl() : docketInfo.getLicenseUrl())
.contact(
new Contact(
docketInfo.getContact().getName().isEmpty() ? swaggerProperties.getContact().getName() : docketInfo.getContact().getName(),
docketInfo.getContact().getUrl().isEmpty() ? swaggerProperties.getContact().getUrl() : docketInfo.getContact().getUrl(),
docketInfo.getContact().getEmail().isEmpty() ? swaggerProperties.getContact().getEmail() : docketInfo.getContact().getEmail()
)
)
.termsOfServiceUrl(docketInfo.getTermsOfServiceUrl().isEmpty() ? swaggerProperties.getTermsOfServiceUrl() : docketInfo.getTermsOfServiceUrl())
.build();
// base-path处理
// 当没有配置任何path的时候,解析/**
if (docketInfo.getBasePath().isEmpty()) {
docketInfo.getBasePath().add("/**");
}
List<Predicate<String>> basePath = new ArrayList<>(docketInfo.getBasePath().size());
for (String path : docketInfo.getBasePath()) {
basePath.add(PathSelectors.ant(path));
}
// exclude-path处理
List<Predicate<String>> excludePath = new ArrayList<>(docketInfo.getExcludePath().size());
for (String path : docketInfo.getExcludePath()) {
excludePath.add(PathSelectors.ant(path));
}
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.host(swaggerProperties.getHost())
.apiInfo(apiInfo)
.globalOperationParameters(assemblyGlobalOperationParameters(swaggerProperties.getGlobalOperationParameters(),
docketInfo.getGlobalOperationParameters()))
.groupName(docketInfo.getGroup())
.select()
.apis(RequestHandlerSelectors.basePackage(docketInfo.getBasePackage()))
.paths(
Predicates.and(
Predicates.not(Predicates.or(excludePath)),
Predicates.or(basePath)
)
)
.build()
.securitySchemes(securitySchemes())
.securityContexts(securityContexts())
.globalResponseMessage(RequestMethod.GET, getResponseMessages())
.globalResponseMessage(RequestMethod.POST, getResponseMessages())
.globalResponseMessage(RequestMethod.PUT, getResponseMessages())
.globalResponseMessage(RequestMethod.DELETE, getResponseMessages())
.extensions(Lists.newArrayList(new OrderExtensions(swaggerProperties.getOrder())));
configurableBeanFactory.registerSingleton(groupName, docket);
docketList.add(docket);
}
return docketList;
}
/**
* 创建 Docket对象
*
* @param swaggerProperties swagger配置
* @return Docket
*/
private Docket createDocket(final SwaggerProperties swaggerProperties) {
//API 基础信息
ApiInfo apiInfo = new ApiInfoBuilder()
.title(swaggerProperties.getTitle())
.description(swaggerProperties.getDescription())
.version(swaggerProperties.getVersion())
.license(swaggerProperties.getLicense())
.licenseUrl(swaggerProperties.getLicenseUrl())
.contact(new Contact(swaggerProperties.getContact().getName(),
swaggerProperties.getContact().getUrl(),
swaggerProperties.getContact().getEmail()))
.termsOfServiceUrl(swaggerProperties.getTermsOfServiceUrl())
.build();
// base-path处理
// 当没有配置任何path的时候,解析/**
if (swaggerProperties.getBasePath().isEmpty()) {
swaggerProperties.getBasePath().add("/**");
}
List<Predicate<String>> basePath = new ArrayList<>();
for (String path : swaggerProperties.getBasePath()) {
basePath.add(PathSelectors.ant(path));
}
// exclude-path处理
List<Predicate<String>> excludePath = new ArrayList<>();
for (String path : swaggerProperties.getExcludePath()) {
excludePath.add(PathSelectors.ant(path));
}
return new Docket(DocumentationType.SWAGGER_2)
.host(swaggerProperties.getHost())
.apiInfo(apiInfo)
.groupName(swaggerProperties.getGroup())
.globalOperationParameters(
buildGlobalOperationParametersFromSwaggerProperties(
swaggerProperties.getGlobalOperationParameters()))
.select()
.apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage()))
.paths(
Predicates.and(
Predicates.not(Predicates.or(excludePath)),
Predicates.or(basePath)
)
)
.build()
.securitySchemes(securitySchemes())
.securityContexts(securityContexts())
.globalResponseMessage(RequestMethod.GET, getResponseMessages())
.globalResponseMessage(RequestMethod.POST, getResponseMessages())
.globalResponseMessage(RequestMethod.PUT, getResponseMessages())
.globalResponseMessage(RequestMethod.DELETE, getResponseMessages())
.extensions(Lists.newArrayList(new OrderExtensions(swaggerProperties.getOrder())))
;
}
protected List<ResponseMessage> getResponseMessages() {
List<ResponseMessage> collect = Arrays.asList(
new ResponseMessageBuilder().code(0).message("成功").build()
);
return collect;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
private List<SecurityContext> securityContexts() {
List<SecurityContext> contexts = new ArrayList<>(1);
SecurityContext securityContext = SecurityContext.builder()
.securityReferences(defaultAuth())
//.forPaths(PathSelectors.regex("^(?!auth).*$"))
.build();
contexts.add(securityContext);
return contexts;
}
private List<SecurityReference> defaultAuth() {
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
List<SecurityReference> references = new ArrayList<>(1);
references.add(new SecurityReference(AUTH_KEY, authorizationScopes));
return references;
}
private List<ApiKey> securitySchemes() {
List<ApiKey> apiKeys = new ArrayList<>(1);
ApiKey apiKey = new ApiKey(AUTH_KEY, AUTH_KEY, "header");
apiKeys.add(apiKey);
return apiKeys;
}
private List<Parameter> buildGlobalOperationParametersFromSwaggerProperties(
List<SwaggerProperties.GlobalOperationParameter> globalOperationParameters) {
List<Parameter> parameters = Lists.newArrayList();
if (Objects.isNull(globalOperationParameters)) {
/*parameters.add(new ParameterBuilder()
.name(AUTH_KEY)
.description("token令牌")
.modelRef(new ModelRef("string"))
.parameterType("header")
.defaultValue("test")
.required(false)
.order(1)
.build());*/
return parameters;
}
for (SwaggerProperties.GlobalOperationParameter globalOperationParameter : globalOperationParameters) {
parameters.add(new ParameterBuilder()
.name(globalOperationParameter.getName())
.description(globalOperationParameter.getDescription())
.modelRef(new ModelRef(globalOperationParameter.getModelRef()))
.parameterType(globalOperationParameter.getParameterType())
.required(Boolean.parseBoolean(globalOperationParameter.getRequired()))
.build());
}
return parameters;
}
/**
* 局部参数按照name覆盖局部参数
*
* @param globalOperationParameters
* @param docketOperationParameters
* @return
*/
private List<Parameter> assemblyGlobalOperationParameters(
List<SwaggerProperties.GlobalOperationParameter> globalOperationParameters,
List<SwaggerProperties.GlobalOperationParameter> docketOperationParameters) {
if (Objects.isNull(docketOperationParameters) || docketOperationParameters.isEmpty()) {
return buildGlobalOperationParametersFromSwaggerProperties(globalOperationParameters);
}
Set<String> docketNames = docketOperationParameters.stream()
.map(SwaggerProperties.GlobalOperationParameter::getName)
.collect(Collectors.toSet());
List<SwaggerProperties.GlobalOperationParameter> resultOperationParameters = Lists.newArrayList();
if (Objects.nonNull(globalOperationParameters)) {
for (SwaggerProperties.GlobalOperationParameter parameter : globalOperationParameters) {
if (!docketNames.contains(parameter.getName())) {
resultOperationParameters.add(parameter);
}
}
}
resultOperationParameters.addAll(docketOperationParameters);
return buildGlobalOperationParametersFromSwaggerProperties(resultOperationParameters);
}
}package com.zjh.swagger2;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.boot.context.properties.ConfigurationProperties;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* swagger2 属性配置
* 必须配置 prefix ,才能有提示
*
*/
@Data
//@RefreshScope
@Component
@ConfigurationProperties(prefix = "zxw.swagger")
public class SwaggerProperties {
/**
* 是否开启swagger
**/
private Boolean enabled = true;
/**
* 是否生产环境
*/
private Boolean production = false;
/**
* 离线文档路径
*/
private Markdown markdown = new Markdown();
/**
* 访问账号密码
*/
private Basic basic = new Basic();
/**
* 标题
**/
private String title = "在线文档";
private String group = "";
/**
* 描述
**/
private String description = "zxw 在线文档";
/**
* 版本
**/
private String version = "1.0";
/**
* 许可证
**/
private String license = "";
/**
* 许可证URL
**/
private String licenseUrl = "";
/**
* 服务条款URL
**/
private String termsOfServiceUrl = "";
private Contact contact = new Contact();
/**
* swagger会解析的包路径
**/
private String basePackage = "com.zjh";
/**
* swagger会解析的url规则
**/
private List<String> basePath = new ArrayList<>();
/**
* 在basePath基础上需要排除的url规则
**/
private List<String> excludePath = new ArrayList<>();
/**
* 分组文档
**/
private Map<String, DocketInfo> docket = new LinkedHashMap<>();
/**
* host信息
**/
private String host = "";
/**
* 排序
*/
private Integer order = 1;
/**
* 全局参数配置
**/
private List<GlobalOperationParameter> globalOperationParameters;
@Setter
@Getter
public static class GlobalOperationParameter {
/**
* 参数名
**/
private String name;
/**
* 描述信息
**/
private String description;
/**
* 指定参数类型
**/
private String modelRef;
/**
* 参数放在哪个地方:header,query,path,body.form
**/
private String parameterType;
/**
* 参数是否必须传
**/
private String required;
}
@Data
public static class DocketInfo {
/**
* 标题
**/
private String title = "在线文档";
/**
* 自定义组名
*/
private String group = "";
/**
* 描述
**/
private String description = "zxw 在线文档";
/**
* 版本
**/
private String version = "1.0";
/**
* 许可证
**/
private String license = "";
/**
* 许可证URL
**/
private String licenseUrl = "";
/**
* 服务条款URL
**/
private String termsOfServiceUrl = "";
private Contact contact = new Contact();
/**
* swagger会解析的包路径
**/
private String basePackage = "";
/**
* swagger会解析的url规则
**/
private List<String> basePath = new ArrayList<>();
/**
* 在basePath基础上需要排除的url规则
**/
private List<String> excludePath = new ArrayList<>();
private List<GlobalOperationParameter> globalOperationParameters;
/**
* 排序
*/
private Integer order = 1;
public String getGroup() {
if (group == null || "".equals(group)) {
return title;
}
return group;
}
}
public String getGroup() {
if (group == null || "".equals(group)) {
return title;
}
return group;
}
@Data
public static class Contact {
/**
* 联系人
**/
private String name = "zxw";
/**
* 联系人url
**/
private String url = "";
/**
* 联系人email
**/
private String email = "";
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class Basic {
private Boolean enable = false;
private String username = "zxw";
private String password = "zxw";
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class Markdown {
private Boolean enable = false;
private String basePath = "classpath:markdown/*";
}
}3、在mvcConfigurer中添加配置
4、界面效果
关于在配置swagger过程中碰到的问题,例如此类问题
我在过程中也碰到了doc.html打不开的问题,根据当前项目环境,过滤器中排除了doc.html请求,也在mvcConfigeurer中增加了resourceHandler,结果doc.html能打开了,但是接口内容并没有显示出来。直到最后,偶然间的尝试,成功显示了接口内容。那就是在启动类注解中,指定了扫描包范围,@SpringBootApplication(scanBasePackages = {"com.zjh"}),我猜测应该是没有配置时不会扫描进去,所以404找不到资源。还是怪自己,配置不够熟悉。
时间不早了,今天就先到这里,明天再继续后面的改造。
2021.03.29更新
今天继续做服务升级,原本的mybatisPlus还未完全集成好,在使用原有语句查询时,竟然报错提示
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):com.****
而直接使用mybatisPlus的条件构造器查询就正常显示,所以mybatisPlus的配置基本是没有问题的,问题可能就出在mapper.xml的配置上了。
直到后来才发现,可能是由于mapper-location配置引起的。
本工程引入的是
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.2</version> </dependency>
配置文件中如下
#mybatis sqlMap的xml文件目录 #mybatis.mapper-locations=classpath*:sqlmap/*.xml
经过查阅:
如果引用mybatis-plus-boot-starter 依赖,需要配置 mybatis-plus.mapper-locations
如果引用mybatis-plus 依赖,需要配置 mybatis.mapper-locations
所以,修改了配置如下
mybatis-plus.mapper-locations=classpath*:sqlmap/*.xml
这样,就能正常执行了。
另外,还解决了一个@JsonFormat(shape =JsonFormat.Shape.STRING,pattern="yyyy-MM-dd")注解,页面未格式化的问题
1、pom.xml需要引入依赖
<!-- jdk8 Time--> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> <version>2.9.8</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.module</groupId> <artifactId>jackson-module-parameter-names</artifactId> <version>2.9.8</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.8</version> </dependency>
2、后台请求原本是使用net.sf.json的方法,转换对象为json字符串,再前端解析的方式。其中将Date类型的进行了Json格式化
JsonConfig config = new JsonConfig ();
config.registerJsonValueProcessor (Date.class, new JsonDateValueProcessor ("yyyy-MM-dd"));
String resultStr=JSONObject.fromObject (resultMap,config).toString();
retrun resultStr;而现在将原来的java.util.Date更改为了java.time.LocalDate,虽然加上了@JsonFormat注解,但是界面显示的还是一个[Object]。
经过断点调试,发现实际已经生效了的。但是再通过JSONObject的转换,又成功将其转换成了普通的JSON对象,LocalDate对应的是一个LocalDate的JSON格式对象而不是一个字符串。后来直接在接口返回Map,界面显示正常了。
今天用来做事的时间不多,处理完这两个问题,已经是凌晨00:29了,那么代码生成器部分就有时间再做吧。
2021.03.30更新
今天继续研究,目标是搞定代码生成器
官网其实是有教程说明的,按照此步骤操作即可。为了节省时间,以及使用顺手,参考了公司代码生成模块,基于自身项目风格做了改造。
总体来说,服务升级算是差不多了,使用JAVA8新特性编写代码就在后续过程中慢慢应用。过段时间,有空的话,研究下jenkins自动化部署,在服务器上安装一套。接下来,就可以好好写代码了。








发表评论