java常用API -FILE+MapStruct

java常用API -FILE+MapStruct

FILE

文件上传原理解析

java常用API -FILE+MapStruct

FileItem解析

java常用API -FILE+MapStruct

DiskFileItemFactory解析

默认的FileItemFactory实现

  1. 此实现 创建FileItem实例,并将较小的items保存在内存中,将较大的items缓存到磁盘上的临时文件
  2. 存储到磁盘上内容的大小阈值和创建临时文件的目录都是可以配置的
  3. 如果没有配置,默认配置值如下:
    3.1 大小阈值为10KB
    3.2 Repository是系统默认的临时目录,由其返回:System.getProperty("java.io.tmpdir")
  4. 当使用DiskFileItemFactory时,您应该考虑以下内容:
    4.1 当临时文件不在需要时,临时文件会自动删除(更确切的说:当java.io.File对应的实例被垃圾回收时)
    4.2 清理这些临时文件是由一个FileCleaningTracker实例和一个相关的线程完成的
    4.3 在复杂的环境中,例如在Web应用程序中,您应该考虑终止此线程,例如,当您的Web应用程序结束时。
// get temporarily store files
public File getRepository() {
    return repository;
}
// set directory used to temproarily store files
public void setRepository(File repository) {
    this.repository = repository;
}

使用example

// transfer file to multipart
public static MultipartFile transferFileToMultiPartFile(File file) throws IOException {
    String defaultFileName = "file";
    String contentType = getContentType(file);
    FileItem fileItem = new DiskFileItemFactory().createItem(defaultFileName, contentType, true, file.getName());
    FileInputStream inputStream = new FileInputStream(file);
    OutputStream outputStream = fileItem.getOutputStream();
    // copy file content to fileItem
    IOUtils.copy(inputStream,outputStream);
    return new CommonsMultipartFile(fileItem);
}
// get ContentType
public static String getContentType(File file) throws IOException {
    Path path = Paths.get(file.getAbsolutePath());
    return Files.probeContentType(path);
}
//overload method
public static MultipartFile transferFileToMultiPartFile(String fileName) throws IOException {
    File file = FileUtils.getFile(fileName);
    return transferFileToMultiPartFile(file);
}

java常用API -FILE+MapStruct

note: 从NativeWebRequest获取multipart

MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) nativeWebRequest.getNativeRequest(HttpServletRequest.class);
// 这里必须获取requestparam 且指定参数必须一致
MultipartFile file  = multipartRequest.getFiles("file").get(0);

note1:在断点处获取请求信息

((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest().getHeader("token")

MapStruct

参考文档

  1. @Mapper——表示该接口作为映射接口,编译时MapStruct处理器的入口

  1)uese:外部引入的转换类;

  2)componentModel:就是依赖注入,类似于在spring的servie层用@servie注入,那么在其他地方可以使用@Autowired取到值。该属性可取的值为

    a)默认:这个就是经常使用的 xxxMapper.INSTANCE.xxx;

    b)cdi:使用该属性,则在其他地方可以使用@Inject取到值;

    c)spring:使用该属性,则在其他地方可以使用@Autowired取到值;

    d)jsr330/Singleton:使用者两个属性,可以再其他地方使用@Inject取到值;

1.2、@Mappings——一组映射关系,值为一个数组,元素为@Mapping

1.3、@Mapping——一对映射关系

  1)target:目标属性,赋值的过程是把“源属性”赋值给“目标属性”;

  2)source:源属性,赋值的过程是把“源属性”赋值给“目标属性”;

  3)dateFormat:用于源属性是Date,转化为String;

  4)numberFormat:用户数值类型与String类型之间的转化;

  5)constant:不管源属性,直接将“目标属性”置为常亮;

  6)expression:使用表达式进行属性之间的转化;

  7)ignore:忽略某个属性的赋值;

  8)qualifiedByName:根据自定义的方法进行赋值;

  9)defaultValue:默认值;

1.4、@MappingTarget——用在方法参数的前面。使用此注解,源对象同时也会作为目标对象,用于更新。

1.5、@InheritConfiguration——指定映射方法

1.6、@InheritInverseConfiguration——表示方法继承相应的反向方法的反向配置

1.7、@Named——定义类/方法的名称

使用example

实体类

注意:实体类必须具有完整的all args构造函数,使用@builder注解后将丢失全构造函数

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Test1Vo {
    private String name;
    private String password;
    private Integer count;
    private Double money;
    private String createTime;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Test2Vo {
    private String username;
    private String passwd;
    private Integer NewCount;
    private Integer NewMoney;
    // mapStruct 转换与这两个注解无关
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
}

MapStructInterface

@Mapper(uses = {testMap.class})
public interface TestVoTransfer {
    TestVoTransfer INSTANCE = Mappers.getMapper(TestVoTransfer.class);
    @Mappings({
            @Mapping(source = "username", target = "name",qualifiedByName = "Test2NameToTest1Name"),
            @Mapping(source = "passwd", target = "password"),
            @Mapping(source = "newCount", target = "count"),
            @Mapping(source = "newMoney", target = "money", qualifiedByName = "ConvertMoney"),
            @Mapping(source = "createTime",target = "createTime", dateFormat = "yyyy-MM-dd HH:mm:ss")
    })
    Test1Vo toTest1Vo(Test2Vo test2Vo);

    @InheritInverseConfiguration
    @Mappings({
            @Mapping(source = "name",target = "username",qualifiedByName = "Test1NameToTest2Name")
    })
    Test2Vo toTest2Vo(Test1Vo test1Vo);
	// 自动转换
    List<Test1Vo> toTest1Vos(List<Test2Vo> test2Vos);
	// 可以使用接口默认的转换类,或者使用实体类
    @Named("ConvertMoney")
    default Integer ConvertMoney(Double NewMoney) {
        return NewMoney.intValue();
    }
}

MapMain

 public static void main(String[] args) {
     Test2Vo test2Vo = Test2Vo.builder().username("username").passwd("123456")
         .NewCount(22).NewMoney(12).createTime(LocalDateTime.now()).build();
     Test1Vo test1Vo = TestVoTransfer.INSTANCE.toTest1Vo(test2Vo);
     String test1Json = ToStringBuilder.reflectionToString(test1Vo, ToStringStyle.JSON_STYLE);
     System.out.println("test1:" + test1Json);
     Test2Vo test2Vo1 = TestVoTransfer.INSTANCE.toTest2Vo(test1Vo);
     String test2Json = ToStringBuilder.reflectionToString(test2Vo1, ToStringStyle.JSON_STYLE);
     System.out.println("test2:" + test2Json);
     ArrayList<Test2Vo> test2Vos = Lists.newArrayList(test2Vo);
     List<Test1Vo> test1Vos = TestVoTransfer.INSTANCE.toTest1Vos(test2Vos);
     System.out.println("test1Vos:" + test1Vos.toString());
 }

testMap

注意:使用自定义转换器时,mapstruct无法自动反序列识别,必须手动指定

@Component
public class testMap {
    @Named("Test2NameToTest1Name")
    public static String UserNameMap(String inputValue){
        // key Test2 name  /  value test1Vo name
        Map<String, String> map = initNameMap();
        if (Objects.isNull(inputValue)|| !map.containsKey(inputValue)){
            return "defaultValue";
        }
        return map.get(inputValue);
    }
    @Named("Test1NameToTest2Name")
    public static String transferName(String inputValue){
        Map<String, String> map = initNameMap();
        if (Objects.isNull(inputValue)||!map.containsValue(inputValue)){
            return "defaultValue";
        }
        for (Map.Entry<String, String> entry : map.entrySet()) {
            if (entry.getValue().equals(inputValue)){
                return entry.getKey();
            }
        }
        return "defaultValue";
    }
    private static Map<String,String> initNameMap(){
        return new HashMap<String, String>() {
            {
                put("name", "test");
                put("age", "20");
                put("username","user");
            }
        };
    }
}

finally 生成的实体类

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2021-02-13T15:31:44+0800",
    comments = "version: 1.2.0.Final, compiler: javac, environment: Java 1.8.0_121 (Oracle Corporation)"
)
public class TestVoTransferImpl implements TestVoTransfer {

    @Override
    public Test1Vo toTest1Vo(Test2Vo test2Vo) {
        if ( test2Vo == null ) {
            return null;
        }

        Test1Vo test1Vo = new Test1Vo();

        test1Vo.setName( testMap.UserNameMap( test2Vo.getUsername() ) );
        test1Vo.setCount( test2Vo.getNewCount() );
        test1Vo.setPassword( test2Vo.getPasswd() );
        if ( test2Vo.getNewMoney() != null ) {
            test1Vo.setMoney( test2Vo.getNewMoney().doubleValue() );
        }
        if ( test2Vo.getCreateTime() != null ) {
            test1Vo.setCreateTime( DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss" ).format( test2Vo.getCreateTime() ) );
        }

        return test1Vo;
    }

    @Override
    public Test2Vo toTest2Vo(Test1Vo test1Vo) {
        if ( test1Vo == null ) {
            return null;
        }

        Test2Vo test2Vo = new Test2Vo();

        test2Vo.setNewCount( test1Vo.getCount() );
        test2Vo.setPasswd( test1Vo.getPassword() );
        if ( test1Vo.getCreateTime() != null ) {
            test2Vo.setCreateTime( java.time.LocalDateTime.parse( test1Vo.getCreateTime(), DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm:ss" ) ) );
        }
        test2Vo.setNewMoney( ConvertMoney( test1Vo.getMoney() ) );
        test2Vo.setUsername( testMap.transferName( test1Vo.getName() ) );

        return test2Vo;
    }

    @Override
    public List<Test1Vo> toTest1Vos(List<Test2Vo> test2Vos) {
        if ( test2Vos == null ) {
            return null;
        }

        List<Test1Vo> list = new ArrayList<Test1Vo>( test2Vos.size() );
        for ( Test2Vo test2Vo : test2Vos ) {
            list.add( toTest1Vo( test2Vo ) );
        }

        return list;
    }
}
上一篇:RHCS高可用集群配置(luci+ricci+fence)


下一篇:Mapstruct 使用教程