当前位置: 首页 > news >正文

域名备案需要网站吗海外推广营销

域名备案需要网站吗,海外推广营销,北京做电商网站设计,软件工程很难学吗目录 1.枚举简介 1.1.规范 1.2.枚举类真实的样子 1.3.枚举类的特点 1.4.枚举可以使用的方法 1.4.1.toString()方法 1.4.2.valueOf方法 1.4.3.values方法 1.4.4.ordinal方法 1.5.枚举的用法 1.5.1.常量 1.5.2.switch 1.5.3.枚举中增加方法 1.5.4.覆盖枚举方法 1.5…目录 1.枚举简介 1.1.规范 1.2.枚举类真实的样子 1.3.枚举类的特点 1.4.枚举可以使用的方法 1.4.1.toString()方法 1.4.2.valueOf方法 1.4.3.values方法 1.4.4.ordinal方法 1.5.枚举的用法 1.5.1.常量 1.5.2.switch 1.5.3.枚举中增加方法 1.5.4.覆盖枚举方法 1.5.5.实现接口 1.5.5.1.情况 1在 enum 类中实现接口 1.5.5.2.情况 2让枚举类中的对象分别实现接口中的方法 1.5.6.在接口中使用枚举类 1.5.7.使用枚举集合 1.5.7.1.EnumSet 1.5.7.2.EnumMap 2.序列化和反序列化 2.1.什么是序列化和反序列化 2.2.什么是serialVersionUID序列化ID 2.3.什么类型的数据不能被序列化 3.jackson 3.1.jackson序列化writeValueAsString 3.2.jackson反序列化readValue 3.3.集合转换 3.4.JsonProperty 3.5.ObjectMapper的一些配置 3.6.JsonParser 3.6.1.创建 3.6.2.解析 4.枚举的序列化 4.1.ordinal索引 4.2.时序图 4.3.json枚举序列化/反序列化处理 4.3.1.方法一使用JsonCreator和JsonValue 4.3.2.方法二自定义序列化/反序列化方法 4.4.mybatis枚举序列化/反序列化处理 4.4.1.TypeHandler 4.4.2.配置步骤 5.IDEA2019取消枚举提示 6.查看枚举调用的地方 1.枚举简介 枚举类型enum type是指由一组固定的常量组成合法的类型。 枚举类格式 public enum SexEnum {MAN, WOMAN } 1.1.规范 1.2.枚举类真实的样子 1、使用javac 命令编译得到.class文件 2、使用命令 javap 对class文件进行反编译 javac Sex.java javap Sex.class 得到如下结果 Compiled from Sex.java public final class Sex extends java.lang.EnumSex {public static final Sex MAN;public static final Sex WOMAN;public static Sex[] values();public static Sex valueOf(java.lang.String);static {}; } 3、这里其实是创建了2个对象 public final class Sex extends java.lang.EnumSex {public static final Sex MAN new Sex();public static final Sex WOMAN new Sex();public static Sex[] values();public static Sex valueOf(java.lang.String);static {}; } 1.3.枚举类的特点 1、枚举类是通过final修饰不能被继承 2、枚举类默认继承了枚举类型 java.lang.Enum 3、枚举类的第一行罗列的是枚举类对象并且是常量存储所以枚举类的第一行写的是常量名称默认存储了枚举对象。 4、枚举类的构造器是私有的。 5、枚举类相当于多例设计模式 1.4.枚举可以使用的方法 把上面的枚举类加上code和name public enum SexEnum {MAN(1, 男),WOMAN(2, 女);private Integer code;private String name;SexEnum(Integer code, String name) {this.code code;this.name name;}public Integer getCode() {return code;}public String getName() {return name;} } 1.4.1.toString()方法 这个方法会返回枚举常量名 // MAN System.out.println(SexEnum.MAN.toString()); // WOMAN System.out.println(SexEnum.WOMAN.toString()); 1.4.2.valueOf方法 这个方法用于构建枚举类传入枚举类常量名即可。 SexEnum sexEnum SexEnum.valueOf(MAN); // 男 System.out.println(sexEnum.getName()); try {// 报错: java.lang.IllegalArgumentException: No enum constant com.leelen.scd.api.amc.enums.SexEnum.UNKNOWNSystem.out.println(SexEnum.valueOf(UNKNOWN).getName()); } catch (IllegalArgumentException e) {e.printStackTrace(); } 如果不存在传入的枚举常量那么会报错 java.lang.IllegalArgumentException:  No enum constant com.leelen.scd.api.amc.enums.SexEnum.UNKNOWN     at java.lang.Enum.valueOf(Enum.java:238)     at com.leelen.scd.api.amc.enums.SexEnum.valueOf(SexEnum.java:3)     at com.leelen.scd.api.amc.enums.UseSex.main(UseSex.java:28) 1.4.3.values方法 使用枚举类名进行调用会返回所有枚举常量的数组 1.4.4.ordinal方法 这个方法会返回枚举常量在enum中声明的位置从0开始 SexEnum[] sexEnum SexEnum.values(); for (SexEnum s : sexEnum) {System.out.println(s.getCode() , s.getName() , s.ordinal()); } 打印结果 1,男,0 2,女,1 1.5.枚举的用法 1.5.1.常量 public enum ColorEnum {RED, GREEN, BLANK, YELLOW } 1.5.2.switch public static void getSexName(SexEnum sexEnum) {switch (sexEnum) {case MAN:System.out.println(男);break;case WOMAN:System.out.println(女);break;default:break;} } 这里不要使用 SexEnum.MAN, 不然会提示An enum switch case label must be the unqualified name of an enumeration constant 1.5.3.枚举中增加方法 public class EnumTest {public static void main(String[] args) {ErrorCodeEnum errorCode ErrorCodeEnum.SUCCESS;System.out.println(状态码 errorCode.code() 状态信息 errorCode.msg());} }enum ErrorCodeEnum {SUCCESS(1000, success),PARAM_ERROR(1001, parameter error),SYS_ERROR(1003, system error),NAMESPACE_NOT_FOUND(2001, namespace not found),NODE_NOT_EXIST(3002, node not exist),NODE_ALREADY_EXIST(3003, node already exist),UNKNOWN_ERROR(9999, unknown error);private int code;private String msg;ErrorCodeEnum(int code, String msg) {this.code code;this.msg msg;}public int code() {return code;}public String msg() {return msg;}public static ErrorCodeEnum getErrorCode(int code) {for (ErrorCodeEnum it : ErrorCodeEnum.values()) {if (it.code() code) {return it;}}return UNKNOWN_ERROR;} } 1.5.4.覆盖枚举方法 我们可以覆盖一些枚举中的方法用于实现自己的业务比如我们可以覆盖 toString() 方法实现代码如下 public class EnumTest {public static void main(String[] args) {ColorEnum colorEnum ColorEnum.RED;System.out.println(colorEnum.toString());} }enum ColorEnum {RED(红色, 1), GREEN(绿色, 2), BLANK(白色, 3), YELLOW(黄色, 4);// 成员变量private String name;private int index;// 构造方法private ColorEnum(String name, int index) {this.name name;this.index index;}//覆盖方法Overridepublic String toString() {return this.index this.name;} } 1.5.5.实现接口 枚举类可以用来实现接口但不能用于继承类因为枚举默认继承了 java.lang.Enum 类在 Java 语言中允许实现多接口但不能继承多个父类实现代码如下 1.5.5.1.情况 1在 enum 类中实现接口 public class EnumTest {public static void main(String[] args) {ColorEnum colorEnum ColorEnum.RED;colorEnum.print();System.out.println(颜色 colorEnum.getInfo());} }interface Behaviour {void print();String getInfo(); }enum ColorEnum implements Behaviour {RED(红色, 1), GREEN(绿色, 2), BLANK(白色, 3), YELLOW(黄色, 4);private String name;private int index;private ColorEnum(String name, int index) {this.name name;this.index index;}Overridepublic void print() {System.out.println(this.index this.name);}Overridepublic String getInfo() {return this.name;} } 1.5.5.2.情况 2让枚举类中的对象分别实现接口中的方法 public enum ColorEnum implements Behaviour{RED(红色, 1) {Overridepublic void print() {}Overridepublic String getInfo() {return null;}}, GREEN(绿色, 2) {Overridepublic void print() {}Overridepublic String getInfo() {return null;}}, BLANK(白色, 3) {Overridepublic void print() {}Overridepublic String getInfo() {return null;}}, YELLOW(黄色, 4) {Overridepublic void print() {}Overridepublic String getInfo() {return null;}};private String name;private int index;private ColorEnum(String name, int index) {this.name name;this.index index;} } 1.5.6.在接口中使用枚举类 我们可以在一个接口中创建多个枚举类用它可以很好的实现“多态”也就是说我们可以将拥有相同特性但又有细微实现差别的枚举类聚集在一个接口中实现代码如下 public class EnumTest {public static void main(String[] args) {// 赋值第一个枚举类ColorInterface colorEnum ColorInterface.ColorEnum.RED;System.out.println(colorEnum);// 赋值第二个枚举类colorEnum ColorInterface.NewColorEnum.NEW_RED;System.out.println(colorEnum);} }interface ColorInterface {enum ColorEnum implements ColorInterface {GREEN, YELLOW, RED}enum NewColorEnum implements ColorInterface {NEW_GREEN, NEW_YELLOW, NEW_RED} } 1.5.7.使用枚举集合 在 Java 语言中和枚举类相关的还有两个枚举集合类 java.util.EnumSet 和 java.util.EnumMap使用它们可以实现更多的功能。 1.5.7.1.EnumSet 使用 EnumSet 可以保证元素不重复并且能获取指定范围内的元素示例代码如下 public class EnumTest {public static void main(String[] args) {ListColorEnum list new ArrayList();list.add(ColorEnum.RED);list.add(ColorEnum.RED); // 重复元素list.add(ColorEnum.YELLOW);list.add(ColorEnum.GREEN);// 去掉重复数据EnumSetColorEnum enumSet EnumSet.copyOf(list);System.out.println(去重 enumSet);// 获取指定范围的枚举获取所有的失败状态EnumSetErrorCodeEnum errorCodeEnums EnumSet.range(ErrorCodeEnum.ERROR, ErrorCodeEnum.UNKNOWN_ERROR);System.out.println(所有失败状态 errorCodeEnums);} }enum ColorEnum {RED(红色, 1), GREEN(绿色, 2), BLANK(白色, 3), YELLOW(黄色, 4);private String name;private int index;private ColorEnum(String name, int index) {this.name name;this.index index;} }enum ErrorCodeEnum {SUCCESS(1000, success),ERROR(2001, parameter error),SYS_ERROR(2002, system error),NAMESPACE_NOT_FOUND(2003, namespace not found),NODE_NOT_EXIST(3002, node not exist),NODE_ALREADY_EXIST(3003, node already exist),UNKNOWN_ERROR(9999, unknown error);private int code;private String msg;ErrorCodeEnum(int code, String msg) {this.code code;this.msg msg;}public int code() {return code;}public String msg() {return msg;} } 1.5.7.2.EnumMap public class EnumTest {public static void main(String[] args) {EnumMapColorEnum, String enumMap new EnumMap(ColorEnum.class);enumMap.put(ColorEnum.RED, 红色);enumMap.put(ColorEnum.GREEN, 绿色);enumMap.put(ColorEnum.BLANK, 白色);enumMap.put(ColorEnum.YELLOW, 黄色);System.out.println(ColorEnum.RED : enumMap.get(ColorEnum.RED));} }enum ColorEnum {RED, GREEN, BLANK, YELLOW; } 2.序列化和反序列化 2.1.什么是序列化和反序列化 序列化过程是指把一个 Java 对象变成二进制内容实质上就是一个 byte[]。因为序列化后可以把 byte[] 保存到文件中或者把 byte[] 通过网络传输到远程(IO)如此就相当于把 Java 对象存储到文件或者通过网络传输出去了。 一个 Java 对象要能序列化必须实现一个特殊的java.io.Serializable接口它的定义如下 package java.io; public interface Serializable { } Serializable 没有定义任何方法它是一个空接口。这样的空接口称为“标记接口”(Marker Interface)实现了标记接口的类仅仅是给自身贴了个“标记”并没有增加任何方法。 反序列化过程把一个二进制内容(也就是 byte[])变回 Java 对象。有了反序列化保存到文件中的 byte[] 又可以“变回” Java 对象或者从网络上读取 byte[] 并把它“变回” Java 对象。 为什么需要序列化与反序列化 当两个进程进行远程通信时可以相互发送各种类型的数据包括文本、图片、音频、视频等 而这些数据都会以二进制序列的形式在网络上传送。 当两个 Java 进程进行通信时需要 Java 序列化与反序列化实现进程间的对象传送。换句话说一方面发送方需要把这个 Java 对象转换为字节序列然后在网络上传送另一方面接收方需要从字节序列中恢复出 Java 对象。 代码 import lombok.Data; import java.io.Serializable; Data public class Student implements Serializable {private String name;private Integer age;private Integer score; } import java.io.*; public class TypeDemo {public static void main(String[] args) throws IOException, ClassNotFoundException {serialize();deserialize();}/*** 序列化*/public static void serialize() throws IOException {Student student new Student();student.setName(new);student.setAge(18);student.setScore(100);ObjectOutputStream objectOutputStream new ObjectOutputStream(new FileOutputStream(new File(student.txt)));objectOutputStream.writeObject(student);objectOutputStream.close();System.out.println(序列化成功已经生成student.txt文件);System.out.println();}/*** 反序列化*/public static void deserialize() throws IOException, ClassNotFoundException {ObjectInputStream objectInputStream new ObjectInputStream(new FileInputStream(new File(student.txt)));Student student (Student) objectInputStream.readObject();objectInputStream.close();System.out.println(反序列化结果为 student);} } 结果 序列化成功已经生成student.txt文件 反序列化结果为Student(namenew, age18, score100) 2.2.什么是serialVersionUID序列化ID private static final long serialVersionUID -4392658638228508589L; serialVersionUID 是一个常数用于唯一标识可序列化类的版本。 从输入流构造对象时JVM 在反序列化过程中检查此常数。如果正在读取的对象的 serialVersionUID 与类中指定的序列号不同则 JVM 抛出InvalidClassException。这是为了确保正在构造的对象与具有相同 serialVersionUID 的类兼容。 我们先调用serialize()方法把上面的Student对象序列化进student.txt文件中。然后修改Student类的内容去掉其中一个字段 Data public class Student implements Serializable {private String name;private Integer age; } 再调用反序列化方法deserialize()结果报错 Exception in thread main java.io.InvalidClassException: com.codejam.enums.demo.type.Student; local class incompatible: stream classdesc serialVersionUID -6951954515964250676, local class serialVersionUID 7327139321132172307 这是因为serialVersionUID 是可选的。如果不显式声明Java 编译器将自动生成一个。 2.3.什么类型的数据不能被序列化 声明为static和transient类型的成员数据不能被序列化。因为static代表类的状态transient代表对象的临时数据。 3.jackson 由于Spring自带的序列化和反序列化使用的是jackson所以项目不使用fastjson。 3.1.jackson序列化writeValueAsString 先创建对象 Data public class Student {private String name;private Integer age; } 创建保护集合的对象 Data public class Room {ListStudent studentList; } 1、使用writeValueAsString将一个对象序列化为字符串 public static void main(String[] args) throws JsonProcessingException {ObjectMapper objectMappernew ObjectMapper();Student studentnew Student();student.setName(abc);student.setAge(18);String s objectMapper.writeValueAsString(student);System.out.println(s); } 打印 {name:abc,age:18}、 2、使用writeValueAsString 将一个包含集合的对象序列化为字符串 public static void main(String[] args) throws JsonProcessingException {ListStudent list new ArrayList();for (int i 0; i 3; i) {Student student new Student();student.setName(name i);student.setAge(i);list.add(student);}Room classRoom new Room();classRoom.setStudentList(list);ObjectMapper objectMapper new ObjectMapper();String s objectMapper.writeValueAsString(classRoom);System.out.println(s); } 打印 {studentList:[{name:name0,age:0},{name:name1,age:1},{name:name2,age:2}]} 3.2.jackson反序列化readValue 使用readValue将字符串转换为student对象 public static void main(String[] args) throws JsonProcessingException {ObjectMapper objectMappernew ObjectMapper();String s {\name\:\abc\,\age\:18};Student student objectMapper.readValue(s, Student.class);System.out.println(student); } 使用readValue将字符串转为对象包含集合 public static void main(String[] args) throws JsonProcessingException {String s {\studentList\:[{\name\:\name0\,\age\:0},{\name\:\name1\,\age\:1},{\name\:\name2\,\age\:2}]};ObjectMapper objectMapper new ObjectMapper();Room room objectMapper.readValue(s, Room.class);System.out.println(room); } 3.3.集合转换 public static void main(String[] args) throws JsonProcessingException {String listStr [{\name\:\李四\,\age\:1},{\name\:\张三\,\age\:2}];ObjectMapper objectMapper new ObjectMapper();ListStudent students objectMapper.readValue(listStr, new TypeReferenceListStudent() {});System.out.println(students); } 3.4.JsonProperty 如果序列化的时候名称要更改的话则可以使用JsonProperty 3.5.ObjectMapper的一些配置 通过以下设置会在序列化和反序列化时忽略无法解析和为空的字段 import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper;ObjectMapper objectMapper new ObjectMapper(); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 3.6.JsonParser JsonParser 类是底层 Json解析器。 JsonParser实现相较于 ObjectMapper 更底层因此解析速度更快但相对复杂。 3.6.1.创建 import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonParser;public static void main(String[] args) throws IOException {String carJson { \brand\ : \Mercedes\, \doors\ : 5 };JsonFactory factory new JsonFactory();JsonParser parser factory.createParser(carJson); } createParser()方法传入 Reader, InputStream, URL, byte[] 或 char[] 参数可以实现解析不同来源 json 数据。 3.6.2.解析 JsonParser 工作方式是将 json 分解成一系列标记 (token) 逐个迭代这些标记进行解析 public static void main(String[] args) throws IOException {String carJson { \brand\ : \Mercedes\, \doors\ : 5 };JsonFactory factory new JsonFactory();JsonParser parser factory.createParser(carJson);while(!parser.isClosed()){JsonToken jsonToken parser.nextToken();System.out.println(jsonToken jsonToken);} } 输出结果 jsonToken START_OBJECT jsonToken FIELD_NAME jsonToken VALUE_STRING jsonToken FIELD_NAME jsonToken VALUE_NUMBER_INT jsonToken END_OBJECT jsonToken null 通过 JsonParser 的 nextToken() 方法获得 JsonToken我们可以检查 JsonToken 实例的类型JsonToken 类提供了一组常量表示标记类型 package com.fasterxml.jackson.core; public enum JsonToken {NOT_AVAILABLE(null, JsonTokenId.ID_NOT_AVAILABLE),START_OBJECT({, JsonTokenId.ID_START_OBJECT),END_OBJECT(}, JsonTokenId.ID_END_OBJECT),START_ARRAY([, JsonTokenId.ID_START_ARRAY),END_ARRAY(], JsonTokenId.ID_END_ARRAY),FIELD_NAME(null, JsonTokenId.ID_FIELD_NAME),VALUE_EMBEDDED_OBJECT(null, JsonTokenId.ID_EMBEDDED_OBJECT),VALUE_STRING(null, JsonTokenId.ID_STRING),VALUE_NUMBER_INT(null, JsonTokenId.ID_NUMBER_INT),VALUE_NUMBER_FLOAT(null, JsonTokenId.ID_NUMBER_FLOAT),VALUE_TRUE(true, JsonTokenId.ID_TRUE),VALUE_FALSE(false, JsonTokenId.ID_FALSE),VALUE_NULL(null, JsonTokenId.ID_NULL),; } 如果标记指针指向的是字段JsonParser 的 getCurrentName() 方法返回当前字段名称。 getValueAsString() 返回当前标记值的字符串类型同理 getValueAsInt() 返回整型值其他方法 public static void main(String[] args) throws IOException {String json { \name\ : \tom\, \age\ : 28, \height\: 1.75, \ok\: true};JsonFactory factory new JsonFactory();JsonParser parser factory.createParser(json);while (!parser.isClosed()) {JsonToken token parser.nextToken();if (JsonToken.FIELD_NAME token) {String fieldName parser.getCurrentName();System.out.print(fieldName : );parser.nextToken();switch (fieldName) {case name:System.out.println(parser.getValueAsString());break;case age:System.out.println(parser.getValueAsInt());break;case height:System.out.println(parser.getValueAsDouble());break;case ok:System.out.println(parser.getValueAsBoolean());break;}}} } 4.枚举的序列化 4.1.ordinal索引 枚举默认是使用索引ordinal 来进行序列化反序列化操作的 例如我这边定义了枚举1, 3  它对应的索引是0,1 Getter Accessors(fluent true) AllArgsConstructor public enum AmcManagementModeEnum implements IDictionaryEnum {UNIFIED_AUTHORIZATION_MANAGEMENT(1, 统一授权管理),//SEMI_AUTHORIZED_MANAGEMENT(2, 半授权管理),INDEPENDENT_MANAGEMENT(3, 独立管理),;/*** 字典码值*/private Integer code;/*** 字典描述*/private String desc; } 前端请求0的时候对应的是第一个 1, 统一授权管理。 请求1的时候对应的是第二个 3, 独立管理。 但如果我请求2的话则会报错越界了。 Invalid JSON input: Cannot deserialize value of type com.leelen.scd.module.amc.enums.AmcManagementModeEnum from number 2: index value outside legal index range [0..1]; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type com.leelen.scd.module.amc.enums.AmcManagementModeEnum from number 2: index value outside legal index range [0..1]\n at [Source: (PushbackInputStream); line: 17, column: 31] (through reference chain: com.leelen.scd.base.common.entity.RequestDTO[\body\]-com.leelen.scd.base.common.entity.PagerReqDTO[\params\]-com.leelen.scd.module.amc.vo.AmcNeighInfoPageReq[\managementMode\]) 4.2.时序图 4.3.json枚举序列化/反序列化处理 4.3.1.方法一使用JsonCreator和JsonValue JsonCreator 标记在反序列化时的初始化函数入参为对应该枚举类型的值。 JsonVale标记在序列化时枚举对应生成的值。 import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; import com.leelen.scd.base.common.enums.IDictEnum; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.experimental.Accessors;import java.util.Objects;Getter Accessors(fluent true) AllArgsConstructor public enum AmcManagementModeEnum implements IDictEnum{UNIFIED_AUTHORIZATION_MANAGEMENT( 1, 统一授权管理),//SEMI_AUTHORIZED_MANAGEMENT(2, 半授权管理),INDEPENDENT_MANAGEMENT(3, 独立管理),;/*** 字典码值*/private Integer code;/*** 字典描述*/private String desc;/*** 处理入参定义转换函数parse将code值入参转成对应的枚举类型* 在反序列化的时候Jackson会自动调用这个方法去自动帮我们转换*/JsonCreatorpublic static AmcManagementModeEnum parse(Integer code) {if (Objects.isNull(code)) {return null;}for (AmcManagementModeEnum item : AmcManagementModeEnum.values()) {if (item.code.equals(code)) {return item;}}return null;}/*** 处理出参在getter方法标记序列化后的值*/JsonValuepublic Integer code() {return code;}} 使用枚举 请求参数 import com.leelen.scd.module.amc.enums.AmcManagementModeEnum; import lombok.Data; Data public class AmcNeighInfoPageReq {/*** 小区管理模式*/private AmcManagementModeEnum managementMode; } 响应参数 Data public class AmcNeighInfoPageRes {/*** 小区管理模式*/private AmcManagementModeEnum managementMode; } 验证 RestController RequestMapping(/web/system/community/amc) public class AmcNeighInfoController {/*** 分页*/RequestMapping(/page)public ResponseDTOAmcNeighInfoPageRes page(RequestBody final RequestDTOPagerReqDTOAmcNeighInfoPageReq request) {AmcNeighInfoPageRes res new AmcNeighInfoPageRes();res.setManagementMode(request.getBody().getParams().getManagementMode());return ResponseHelper.successResponse(request.getHeader(), res);} } 4.3.2.方法二自定义序列化/反序列化方法 1、首先定义接口IDictEnum。  这里指定反序列化的方法EnumJsonDeserializer 这里指定序列化的方法EnumJsonSerializer import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize;JsonDeserialize(using EnumJsonDeSerializer.class) JsonSerialize(using EnumJsonSerializer.class) public interface IDictEnum {/*** 获得字典码值*/Integer code();/*** 获得字典描述, 这里不能用name, 因为java.lang.Enum已经定义了name*/String desc();} 2、反序列化方法EnumJsonDeserializer import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonStreamContext; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.deser.ContextualDeserializer;import java.io.IOException; import java.util.Arrays;public class EnumJsonDeSerializer extends JsonDeserializerIDictEnum implements ContextualDeserializer {private Class? extends IDictEnum clazz;public EnumJsonDeSerializer() {}public EnumJsonDeSerializer(Class? extends IDictEnum clazz) {this.clazz clazz;}Overridepublic IDictEnum deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException {String param jsonParser.getText();IDictEnum[] enumConstants clazz.getEnumConstants();JsonStreamContext parsingContext jsonParser.getParsingContext();IDictEnum iDictEnum Arrays.stream(enumConstants).filter(x - {//x.toString(),取枚举的具体值如xxx.enums.share.DelFlagEnum 枚举里的“NOT_DELETE”//从而使得两种形式都能识别String enumCodeStr x.toString();return enumCodeStr.equals(param) || param.equals(x.code() );}).findFirst().orElse(null);/*if (null iEnum) {String msg String.format(枚举类型%s从%s未能转换成功, clazz.toString(), param);throw new Exception(msg);}*/return iDictEnum;}Overridepublic Class? handledType() {return IDictEnum.class;}SuppressWarnings({unchecked})Overridepublic JsonDeserializer? createContextual(DeserializationContext ctxt, BeanProperty property)throws JsonMappingException {JavaType type property.getType();// 如果是容器则返回容器内部枚举类型while (type.isContainerType()) {type type.getContentType();}return new EnumJsonDeSerializer((Class? extends IDictEnum) type.getRawClass());} } 3、序列化方法EnumJsonSerializer import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import java.io.IOException; public class EnumJsonSerializer extends JsonSerializerIDictEnum {public void serialize(IDictEnum iDictEnum, JsonGenerator generator, SerializerProvider provider) throws IOException, JsonProcessingException {// 序列化只要code的值generator.writeNumber(iDictEnum.code());// 序列化形式: {code: , desc: }//generator.writeStartObject();//generator.writeNumberField(code, iBaseDict.code());//generator.writeStringField(desc, iBaseDict.desc());//generator.writeEndObject();} } 经验证以下这几种情况都能很好的识别成功 Data public class AmcNeighInfoPageReq {private AmcManagementModeDictEnum managementMode;private ListAmcManagementModeDictEnum managementModeList;private AmcNeighInfoPageReq amcNeighInfoPageReq;private MapInteger, AmcManagementModeDictEnum map1;private MapAmcManagementModeDictEnum, Integer map2; } 4.4.mybatis枚举序列化/反序列化处理 以上两种方法对于mybatis来说没有起到作用需要单独进行mybatis自定义序列化 MyBatis内置了两个枚举转换器分别是org.apache.ibatis.type.EnumTypeHandler和org.apache.ibatis.type.EnumOrdinalTypeHandler。 EnumTypeHandler是默认的枚举转换器该转换器将枚举实例转换为实例名称的字符串。比如有个枚举。 例如 前端输入1的话则后端insert的时候的值是 字符串“UNIFIED_AUTHORIZATION_MANAGEMENT” Getter Accessors(fluent true) AllArgsConstructor public enum AmcManagementModeEnum implements IDictEnum {UNIFIED_AUTHORIZATION_MANAGEMENT( 1, 统一授权管理),//SEMI_AUTHORIZED_MANAGEMENT(2, 半授权管理),INDEPENDENT_MANAGEMENT(3, 独立管理),;/*** 字典码值*/private Integer code;/*** 字典描述*/private String desc; } EnumOrdinalTypeHandler这个转换器将枚举实例的ordinal属性作为取值从0依次取值。还是上面的例子用这种转换器保存在数据库中的值就是0。 如果我们想保存枚举本身所定义的code值呢这就需要自定义一个类型转换器自定义一个int类型保存在数据库即insert时枚举转换为int型数据保存在数据库select时数据库中的int值转换成实体类的枚举类型。 4.4.1.TypeHandler TypeHandler顾名思义类型转换器就是将数据库中的类型与Java中的类型进行相互转换的处理器。 经常自定义类型转换器方式有两种实现 TypeHandler 接口 或继承抽象类 BaseTypeHandle并且可以指定转换后的字段类型。 其实BaseTypeHandler也是继承了TypeHandler接口在实现的TypeHandler接口的方法中调用的是自身抽象方法 抽象类BaseTypeHandler的抽象方法 // 执行之前将Java类型转换为对应的jdbc类型用于赋值sql中参数 public abstract void setNonNullParameter(PreparedStatement var1, int var2, T var3, JdbcType var4) throws SQLException; // 根据列名从resultSet中获取将JDBC类型转换为Java类型 public abstract T getNullableResult(ResultSet var1, String var2) throws SQLException; // 根据下标从resultSet中获取将JDBC类型转换为Java类型 public abstract T getNullableResult(ResultSet var1, int var2) throws SQLException; // 用于在执行完存储过程后将JDBC类型转换为Java类型 public abstract T getNullableResult(CallableStatement var1, int var2) throws SQLException; 4.4.2.配置步骤 1、mybatis自定义枚举类型转换 这里需要配置MappedTypes import com.leelen.scd.base.common.util.EnumUtil; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.MappedTypes;import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException;MappedTypes({IDictEnum.class}) public class EnumTypeHandlerE extends Enum? IDictEnum extends BaseTypeHandlerIDictEnum {private ClassE type;public EnumTypeHandler(ClassE type) {if (type null) {throw new IllegalArgumentException(Type argument cannot be null.);}this.type type;}/*** 用于定义设置参数时该如何把Java类型的参数转换为对应的数据库类型*/Overridepublic void setNonNullParameter(PreparedStatement ps, int i, IDictEnum parameter, JdbcType jdbcType)throws SQLException {ps.setInt(i, parameter.code());}/*** 用于定义通过字段名称获取字段数据时如何把数据库类型转换为对应的Java类型*/Overridepublic E getNullableResult(ResultSet rs, String columnName) throws SQLException {int code rs.getInt(columnName);return rs.wasNull() ? null : codeOf(code);}/*** 用于定义通过字段索引获取字段数据时如何把数据库类型转换为对应的Java类型*/Overridepublic E getNullableResult(ResultSet rs, int columnIndex) throws SQLException {int code rs.getInt(columnIndex);return rs.wasNull() ? null : codeOf(code);}/*** 用定义调用存储过程后如何把数据库类型转换为对应的Java类型*/Overridepublic E getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {int code cs.getInt(columnIndex);return cs.wasNull() ? null : codeOf(code);}private E codeOf(int code) {try {return EnumUtil.getEnumByCode(type, code);} catch (Exception ex) {throw new IllegalArgumentException(Cannot convert code to type.getSimpleName() by code value., ex);}} } 这里用到了工具类 public class EnumUtil {/*** 根据code获取枚举*/public static T extends IDictEnum T getEnumByCode(ClassT tClass, Integer code) {if (code ! null) {for (T t : tClass.getEnumConstants()) {if (t.code().equals(code)) {return t;}}}return null;} } 2、定义mybatis的typeHandler扫描包路径 # mybatis配置参数 mybatis:# 定义typeHandler扫描包路径type-handlers-package: com.leelen.scd 5.IDEA2019取消枚举提示 IDEA2019枚举自带入参提示个人感觉看的比较眼花建议把他取消掉。 Settings - Editor - Inlay Hints - Java 选择Parameter hints取消勾选Enum constants 效果如下 6.查看枚举调用的地方 我们通常使用 ctrl 鼠标左键来查看方法被哪些地方调用但是枚举却没法这么使用。 解决方法使用alt F7 来间接查看调用的地方或者右键选择Find Usage 或者使用快捷键 ctl alt F7 也可以在idea配置提示
http://www.pierceye.com/news/42666/

相关文章:

  • 用cms建设网站课程项目管理软件功能
  • 郑州网站建设专注乐云seowordpress新闻页面模板下载
  • 企业网站背景图片宠物网站建设的可行性
  • 网站设计策划书案例山西企业模板建站
  • 零起飞网站建设工作室沧州网站制作
  • 怎样自己动手做微官网站医院网页
  • 门户网站的首页模板云建站精品模版
  • 专业模板建站哪家好学习网站建设的书籍
  • 电子商务网站基本功能一个微信网站多少钱
  • 网站后台有些不显示成品网站设计网站
  • 山东省建设业协会网站缙云建设局网站
  • 做的网站一模一样会被告吗自己怎么做网站
  • 调兵山网站淘宝详情页制作
  • 网站建设标准合同网络维护难吗
  • 网站设计美工要怎么做关注公众号阅读全文wordpress
  • 谁会在掏宝网上做网站为什么我的网站只有新闻业被收录
  • seo网站首页优化排名怎么做网站后台更新后前台没有同步更新
  • 网站建设找哪一家比较好公司专业做网站
  • 电商网站建设运营协议wordpress怎么添加导航分类
  • 做钓鱼网站犯法吗上海高端网站设计
  • 在建设厅网站上查询注销建造师建设工程合同包括哪些合同?
  • 网站排版工具免费技能培训在哪里报名
  • 软件手机站郑州网站建设xinsu360
  • 深圳市手机网站建设公司wordpress 取消摘要
  • 域名注册后网站建设网站改版好吗
  • 网站建设公司团队简介wordpress做付费阅读
  • 建设银行信用卡网站多少七里香社区在线看
  • 汕头 网站设计企业建网站需要准备哪些资料呢
  • 怎么用wordpress建立自己的网站重庆谷歌seo关键词优化
  • 报考大专网站肇庆网站添加什么东西才能和用户体验