Transient 的用法

JDK 1.8版本
所在包:java.beans

一、1.8版本对 transient的概述:
@Target(value=METHOD)
 @Retention(value=RUNTIME)
public @interface Transient

表示当Introspector构造与注释代码元素相关联的PropertyDescriptorEventSetDescriptor类时,应使用给定的value声明一个名为“transient”的属性。 “瞬态”属性的true值表示从Encoder派生的编码器应忽略此功能。

Transient注释可以用于FeatureDescriptor子类中涉及的任何方法,用于标识注释类及其子类中的瞬态特征。 通常,以“get”开头的方法是放置注释的最佳位置,在为同一特征定义多个注释的情况下,该声明优先。

要在超类声明它的类中声明非瞬态特征,请使用@Transient(false) 。 在所有情况下, Introspector决定是否一个特点是通过参照注释的最具体的超短暂的。 如果没有Transient注释存在于任何超类中,则该特征不是暂时的。

 

二、个人理解及遇到的问题总结

 

1.在用于生成JSON字符串的对象中,并没有遇到什么问题,正常示例代码:

package com.ssm.model;

import java.io.Serializable;

import lombok.Data;

/**
 * 人员指标属性表
 */
@Data
public class Person implements Serializable {

    /**
     * 人员ID唯一主键
     */
    private transient String pers_id;

    /**
     * 人员姓名
     */
    private String pers_name;
    

}

实体对象定义后,用JSON.toJSONString(Person); 生成JSON串(fastjson.jar),这样用是没一点问题的;

 

2.在Controller方法调用过程中的错误的用法,看错误的示例:

/**
 * 实体对象
 */
public class QuestionSnImportReq implements Serializable {

    @ApiModelProperty("导入试题编号的文件")
    transient MultipartFile file;

    @ApiModelProperty("试卷ID")
    String testPaperId;

    /**
     * @Transient 表示该方法不参与 序列化
     * @return
     */
    public MultipartFile getFile() {
        return file;
    }

    public void setFile(MultipartFile file) {
        this.file = file;
    }

    public String getTestPaperId() {
        return testPaperId;
    }

    public void setTestPaperId(String testPaperId) {
        this.testPaperId = testPaperId;
    }
}


/**
 * controller 方法
 */
@RequestMapping(value = "/importQuestionSn", method = RequestMethod.POST)
public Response<Map<String, String>> importQuestionSn(QuestionSnImportReq importReq) {
    Map<String, String> result = new LinkedHashMap<>();

    return ResponseUtils.createSuccess(result);
}



以上面这种写法,在方法返回时,就会出现以下序列化错误的BUG,原因就是transient 关键字用在了属性前,而不是属性的get方法上:

2019-08-09 19:05:13,168 [ERROR] [http-nio-8301-exec-1] [com.zzz.tool.json.JsonUtils] - 序列化错误: value={"url":"http:\/\/localhost:8301\/manager\/export\/excel\/importQuestionSns","op":"ExcelExportController.importQuestionSns","userId":null,"httpHeaderMap":{token=null, user-agent=PostmanRuntime/7.1.5},"fromInfo":"0:0:0:0:0:0:0:1","executor":"192.168.0.20","req":"com.zzzzzzzz.lms.test.web.dto.manager.paper.QuestionSnImportReq@1f13463a","resp":null,"code":"0","msg":"\u8BF7\u6C42\u6210\u529F","status":"S","cost":15}
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class java.io.FileDescriptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.zzz.common.lang.Digest["req"]->com.zzz.lms.test.web.dto.manager.paper.QuestionSnImportReq["file"]->org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile["inputStream"]->java.io.FileInputStream["fd"])
	at 

下面是正确的示例代码:

/**
 * 实体对象
 */
@ApiModel("试题编号导入请求参数")
public class QuestionSnImportReq implements Serializable {

    @ApiModelProperty("导入试题编号的文件")
    MultipartFile file;

    @ApiModelProperty("试卷ID")
    String testPaperId;

    /**
     * @Transient 表示该方法不参与 序列化
     * @return
     */
    @Transient
    public MultipartFile getFile() {
        return file;
    }

    public void setFile(MultipartFile file) {
        this.file = file;
    }

    public String getTestPaperId() {
        return testPaperId;
    }

    public void setTestPaperId(String testPaperId) {
        this.testPaperId = testPaperId;
    }
}



/**
 * controller方法
 */
@RequestMapping(value = "/importQuestionSn", method = RequestMethod.POST)
public Response<Map<String, String>> importQuestionSn(QuestionSnImportReq importReq) {
    Map<String, String> result = new LinkedHashMap<>();

    return ResponseUtils.createSuccess(result);
}

在我的实体对象中,MultipartFile 有属性,因此属性不能参与序列化,所以会报前面的错误;

 

止于此吧,其他类型的属性没有一一去试,但是想来编程思想上都是一样的...........

有不理解的地方可以QQ:577688028

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值