java标准--校验参数

以往在写接口实现的时候,经常会在方法的开始,对参数做各种判断,如:if (name == null){.......}

现在好了,JSR-303提供了一套标准的annotation,只要给参数加上诸如@NotNull的注解,一切就交给javax.validation的实现去做吧!常用的实现方案有hibernate-validation-4.2.0-Final。基本用法:

ValidationFactory vf = Validation.buildDefaultValidationFactory();

Validator validator = vf.getValidator();

Set<ConstraintViolation> constrains = validator.validate(javabean, groupClass);  //校验失败的一组信息

ConstraintViolation{

    getMessage()--返回提示信息,hibernate-validation会在jar里面的ValidationMessages_{Local}.properties中查找相关信息

    getRootBeanClass()--返回JavaBean类名

    getPropertyPath()--返回属性名

}

分组校验:为了使同一个Bean在不同场合校验不同的属性,默认是Default.class,也可以自己定义N个接口来作为分组。

分组序列(@GroupSequence=({Group1.class, Group2.class,.....})):提示检验器按照顺序逐个进行(原本是无序的),一旦失败则终止后面的Group校验。

关联校验(@Valid):标记此时要校验Bean里面的(Pojo或集合类)子对象。

可以为Validator注解的message,使用ResourceMessage属性文件来自定义Hints,只要在注解的时候message属性以"{}"括起。另:在属性文件中同样可以使用{min}来引用其他的属性值,如:user.username.length=用户名长度必须在{min}到{max}之间。


自定义validation的约束:

 @Constraint(validatedBy={BetweenValidator.class} )

interface @Between{

      //必须有以下三个方法

      String message() default "{data.between.message}";    //返回 ResourceMessage的key

      Class<?>[] group();

      Class<? extends Payload> payload();

      Number min();

      Number max();  

}

在这个类中需要使用 @Constraint指明使用哪个Validator来实现校验操作,其中:

public class BetweenValidator implements ConstraintValidator<Between, Double> {

@Override
public void initialize(Between constraintAnnotation) {

}

@Override
public boolean isValid(Double value, ConstraintValidatorContext context) {

}

}


-------------------------一些常用的注解

@AssertTrue //用于boolean字段,该字段只能为true  

@AssertFalse//该字段的值只能为false  

@CreditCardNumber//对信用卡号进行一个大致的验证  

@DecimalMax//只能小于或等于该值  

@DecimalMin//只能大于或等于该值  

@Digits(integer=2,fraction=20)//检查是否是一种数字的整数、分数,小数位数的数字。  

@Email//检查是否是一个有效的email地址  

@Future//检查该字段的日期是否是属于将来的日期  

@Length(min=,max=)//检查所属的字段的长度是否在minmax之间,只能用于字符串  

@Max//该字段的值只能小于或等于该值  

@Min//该字段的值只能大于或等于该值  

@NotNull//不能为null  

@NotBlank//不能为空,检查时会将空格忽略  

@NotEmpty//不能为空,这里的空是指空字符串  

@Null//检查该字段为空  

@Past//检查该字段的日期是在过去  

@Size(min=, max=)//检查该字段的size是否在minmax之间,可以是字符串、数组、集合、Map  

@URL(protocol=,host,port) // 检查是否是一个有效的 URL ,如果提供了 protocol host 等,则该 URL 还需满足提供的条件 
<think>嗯,用户想在Java中实现CRC16-MODBUS校验的示例代码。首先,我需要回忆一下CRC16-MODBUS的具体参数。记得MODBUS协议用的是CRC-16-ANSI,也就是多项式是0x8005,初始值是0xFFFF,并且输入和输出都是按位异或的,可能还需要反转。 然后,用户提到参考的引用里有一个Java的例子,是计算CRC-16-ANSI的,可能可以在此基础上修改。引用1中的代码用的是0x8005多项式,初始值0xFFFF,还有输入反转和输出反转,这些是否和MODBUS的要求一致呢?对的,MODBUS的CRC16确实使用这些参数,所以那个例子可以作为基础。 接下来,我需要考虑代码的结构。通常CRC计算会有一个预计算的查找表来提高效率,所以需要初始化一个256长度的数组。然后,逐字节处理数据,更新CRC值。最后,处理字节序,因为MODBUS是低字节在前,高字节在后,所以需要将计算出的CRC值交换字节顺序。 还要注意,数据在计算前是否需要反转每个字节。根据MODBUS的标准,每个字节是按位反转后处理的,所以代码中应该包括这一步。比如,在初始化查找表时,每个字节会被反转处理。 然后,测试部分,用户可能需要一个示例字符串,比如"123456789",然后计算它的CRC值是否正确。根据已知的测试用例,正确的CRC应该是0x4B37,转换成字节就是0x37和0x4B,但按照MODBUS的小端顺序,应该是0x37在前,0x4B在后,所以最终的校验码应该是0x374B,即十进制14155。 代码中可能需要一个main函数来演示如何使用这个CRC计算函数。比如,将字符串转换成字节数组,调用计算函数,然后输出结果。 另外,用户的问题中还提到要考虑字节序和数据格式,确保正确性。所以,在代码中处理完CRC值后,需要将结果的两个字节按照小端顺序排列,即低字节在前,高字节在后。 现在需要验证代码的正确性。比如,用测试数据"123456789",计算出的CRC是否正确。根据引用中的例子,正确的校验码是0x4B37,但按MODBUS的顺序,应该是0x37 0x4B,所以代码中的处理是否正确。 可能还需要注意,在计算时,初始CRC是0xFFFF,然后每次处理一个字节,与当前CRC异或,然后进行8次移位和异或操作。查找表的方法可以加速这个过程。 最后,确保代码中的注释清晰,解释每个步骤的作用,特别是初始值、多项式和字节顺序的处理。这样用户能够理解代码的逻辑,并根据需要进行调整。</think>以下是Java实现CRC16-MODBUS校验的详细步骤和示例代码: ### CRC16-MODBUS校验核心实现 1. **参数定义**: - 多项式:0x8005 - 初始值:0xFFFF - 输入反转:true - 输出反转:true - 结果异或值:0x0000 2. **预计算CRC表**: ```java private static final int[] CRC_TABLE = new int[256]; static { for (int i = 0; i < 256; i++) { int crc = i; for (int j = 0; j < 8; j++) { if ((crc & 0x0001) != 0) { crc = (crc >>> 1) ^ 0xA001; // 0xA001是0x8005的位反转 } else { crc >>>= 1; } } CRC_TABLE[i] = crc; } } ``` 3. **校验码计算函数**: ```java public static int calculateCRC16(byte[] data) { int crc = 0xFFFF; for (byte b : data) { crc = (crc >>> 8) ^ CRC_TABLE[(crc ^ (b & 0xFF)) & 0xFF]; } return crc ^ 0x0000; // 最终异或操作 } ``` 4. **完整示例代码**: ```java public class Crc16Modbus { private static final int[] CRC_TABLE = new int[256]; static { for (int i = 0; i < 256; i++) { int crc = i; for (int j = 0; j < 8; j++) { if ((crc & 0x0001) != 0) { crc = (crc >>> 1) ^ 0xA001; } else { crc >>>= 1; } } CRC_TABLE[i] = crc; } } public static byte[] getCRC(byte[] bytes) { int crc = 0xFFFF; for (byte b : bytes) { crc = (crc >>> 8) ^ CRC_TABLE[(crc ^ (b & 0xFF)) & 0xFF]; } crc = crc ^ 0x0000; return new byte[] { (byte) crc, (byte) (crc >>> 8) }; // 低字节在前 } public static void main(String[] args) { String testData = "123456789"; byte[] crcBytes = getCRC(testData.getBytes()); System.out.println(String.format("CRC16-MODBUS: %02X%02X", crcBytes[0]&0xFF, crcBytes[1]&0xFF)); } } ``` ### 关键特性说明 1. **字节顺序处理**:结果采用小端模式(低字节在前),符合Modbus协议要求[^3] 2. **预计算优化**:使用查找表提升计算效率 3. **数据验证**:测试数据"123456789"的校验码应为0x4B37(输出显示为0x374B,符合小端格式) ### 应用场景 1. 工业控制系统的Modbus RTU通信 2. 串口设备数据传输校验 3. 物联网设备状态监测[^1]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值