你好呀,我是小邹。
今天给大家分享一下mapstruct的基本使用。
MapStruct是一个Java注释处理器,用于生成类型安全的bean映射类。
您要做的就是定义一个映射器接口,该接口声明任何必需的映射方法。在编译期间,MapStruct将生成此接口的实现。此实现使用简单的Java方法调用在源对象和目标对象之间进行映射,即没有反射或类似内容。
与手动编写映射代码相比,MapStruct通过生成繁琐且易于出错的代码来节省时间。遵循配置方法上的约定,MapStruct使用合理的默认值,但在配置或实现特殊行为时不加理会。
与动态映射框架相比,MapStruct具有以下优点:
通过使用普通方法调用(settter/getter)而不是反射来快速执行
编译时类型安全性:只能映射相互映射的对象和属性,不能将order实体意外映射到customer DTO等。
如果有如下问题,编译时会抛出异常
可以通过freemarker定制化开发
我的个人博客评论功能初期是通过如下代码实现的:
/**
* 发表评论
*/
@ResponseBody
@PostMapping(value = {"comments"})
public void comments(HttpServletRequest request, @RequestBody @RequestParam("blogid") Integer blogId,
@RequestBody @RequestParam("blogUrl") String blogUrl,
@RequestBody @RequestParam("content") String content,
@RequestBody @RequestParam("nickname") String nickname,
@RequestBody @RequestParam("email") String email,
@RequestBody @RequestParam("avatar") String avatar,
@RequestBody @RequestParam("parentId") Integer parentId,
@RequestBody @RequestParam("parentName") String parentName,
@RequestBody @RequestParam("parentCommentId") Integer parentCommentId) throws Exception {
String ip = IpUtils.getIpAddr(request);
String province = IpUtils.getIpPossession(ip);
Comments comments = new Comments();
comments.setContent(content);
comments.setEmail(email);
comments.setCreateTime(new Date());
comments.setBlogId(blogId);
comments.setBlogUrl(blogUrl);
comments.setProvince(province);
comments.setIp(ip);
comments.setUpdateTime(new Date());
//数值越大则优先展示
if (parentId == -1) {
comments.setSort(1);
} else {
comments.setSort(Integer.parseInt(String.valueOf(System.currentTimeMillis() / 990)));
}
//未审核的评论默认不可见
//暂时可见
comments.setIsVisible(CommentStatus.VISIBLE.getStatus());
//设置父节点id,-1为首节点
comments.setParentId(parentId);
comments.setParentName(parentName);
comments.setNickname(nickname);
comments.setAvatar(avatar);
commentService.save(comments, parentCommentId);
}
上面的代码有什么毛病吗?没有!
但是看起来很臃肿,实现的一点也不优雅。今天就用mapstruct改造一下代码。
引入相关依赖
<dependency>
<groupId>org.mapstructgroupId>
<artifactId>mapstruct-jdk8artifactId>
<version>1.2.0.CR1version>
dependency>
<dependency>
<groupId>org.mapstructgroupId>
<artifactId>mapstruct-processorartifactId>
<version>1.2.0.CR1version>
dependency>
创建CommentInfoConverter接口
package com.zou.blog.convert;
import com.zou.blog.model.domain.Comments;
import com.zou.blog.model.enums.CommentStatus;
import com.zou.blog.util.IpUtils;
import org.mapstruct.Mapper;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
/**
* @author: 邹祥发
* @date: 2022/9/8 13:46
*/
@Mapper(componentModel = "spring")
public interface CommentInfoConverter {
default Comments map(HttpServletRequest request) throws Exception {
String ip = IpUtils.getIpAddr(request);
String province = IpUtils.getIpPossession(ip);
Comments comments = new Comments();
comments.setContent(request.getParameter("content"));
comments.setEmail(request.getParameter("email"));
comments.setCreateTime(new Date());
comments.setBlogId(Integer.valueOf(request.getParameter("blogid")));
comments.setBlogUrl(request.getParameter("blogUrl"));
comments.setProvince(province);
comments.setIp(ip);
comments.setUpdateTime(new Date());
int parentId = Integer.parseInt(request.getParameter("parentId"));
//数值越大则优先展示
if (parentId == -1) {
comments.setSort(1);
} else {
comments.setSort(Integer.parseInt(String.valueOf(System.currentTimeMillis() / 990)));
}
//未审核的评论默认不可见
//暂时可见
comments.setIsVisible(CommentStatus.VISIBLE.getStatus());
//设置父节点id,-1为首节点
comments.setParentId(parentId);
comments.setParentName(request.getParameter("parentName"));
comments.setNickname(request.getParameter("nickname"));
comments.setAvatar(request.getParameter("avatar"));
return comments;
}
}
controller层(这样看起来是不是优雅多了😄)
@Resource
private CommentInfoConverter commentInfoConverter;
/**
* 发表评论
*/
@ResponseBody
@PostMapping(value = {"comments"})
public void comments(HttpServletRequest request, @RequestBody @RequestParam("parentCommentId") Integer parentCommentId) throws Exception {
Comments comments = commentInfoConverter.map(request);
commentService.save(comments, parentCommentId);
}
启动报错:
java: Internal error in the mapping processor: java.lang.NullPointerException
at org.mapstruct.ap.internal.processor.DefaultVersionInformation.createManifestUrl(DefaultVersionInformation.java:182)
at org.mapstruct.ap.internal.processor.DefaultVersionInformation.openManifest(DefaultVersionInformation.java:153)
at org.mapstruct.ap.internal.processor.DefaultVersionInformation.getLibraryName(DefaultVersionInformation.java:129)
at org.mapstruct.ap.internal.processor.DefaultVersionInformation.getCompiler(DefaultVersionInformation.java:122)
at org.mapstruct.ap.internal.processor.DefaultVersionInformation.fromProcessingEnvironment(DefaultVersionInformation.java:95)
at org.mapstruct.ap.internal.processor.DefaultModelElementProcessorContext.<init>(DefaultModelElementProcessorContext.java:50)
at org.mapstruct.ap.MappingProcessor.processMapperElements(MappingProcessor.java:218)
at org.mapstruct.ap.MappingProcessor.process(MappingProcessor.java:156)
at org.jetbrains.jps.javac.APIWrappers$ProcessorWrapper.process(APIWrappers.java:109)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.jetbrains.jps.javac.APIWrappers$1.invoke(APIWrappers.java:213)
at org.mapstruct.ap.MappingProcessor.process(Unknown Source)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:794)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:705)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91)
at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1035)
at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1176)
at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:856)
at com.sun.tools.javac.main.Main.compile(Main.java:523)
at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129)
at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138)
at org.jetbrains.jps.javac.JavacMain.compile(JavacMain.java:231)
at org.jetbrains.jps.incremental.java.JavaBuilder.compileJava(JavaBuilder.java:501)
at org.jetbrains.jps.incremental.java.JavaBuilder.compile(JavaBuilder.java:353)
at org.jetbrains.jps.incremental.java.JavaBuilder.doBuild(JavaBuilder.java:277)
at org.jetbrains.jps.incremental.java.JavaBuilder.build(JavaBuilder.java:231)
at org.jetbrains.jps.incremental.IncProjectBuilder.runModuleLevelBuilders(IncProjectBuilder.java:1441)
at org.jetbrains.jps.incremental.IncProjectBuilder.runBuildersForChunk(IncProjectBuilder.java:1100) at org.jetbrains.jps.incremental.IncProjectBuilder.buildTargetsChunk(IncProjectBuilder.java:1224) at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunkIfAffected(IncProjectBuilder.java:1066) at org.jetbrains.jps.incremental.IncProjectBuilder.buildChunks(IncProjectBuilder.java:832) at org.jetbrains.jps.incremental.IncProjectBuilder.runBuild(IncProjectBuilder.java:419) at org.jetbrains.jps.incremental.IncProjectBuilder.build(IncProjectBuilder.java:183) at org.jetbrains.jps.cmdline.BuildRunner.runBuild(BuildRunner.java:132) at org.jetbrains.jps.cmdline.BuildSession.runBuild(BuildSession.java:302) at org.jetbrains.jps.cmdline.BuildSession.run(BuildSession.java:132) at org.jetbrains.jps.cmdline.BuildMain$MyMessageHandler.lambda$channelRead0$0(BuildMain.java:219) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)
问题描述:
在使用MapStruct,idea2022.2版本在build项目的时候出现错误:java: Internal error in the mapping processor: java.lang.NullPointerException
解决方案:
Setting -->Build,Execution,Deployment -->Compiler -->User-local build加上参数:
-Djps.track.ap.dependencies=false
然后就可以正常启动了,评论功能的代码也正常执行。
本篇文章记录了使用mapstruct改造代码的具体步骤,大家可作参考。
作为一名合格的Java工程师,不应该只局限于"功能的实现",我们更应该追求高性能,优雅整洁的代码!