resteasy 数据校验之Hibernate validation 国际化问题

7 篇文章 0 订阅
4 篇文章 0 订阅

resteasy 添加数据校验参见官方文档

步骤

  1. 添加jar包
javax.validation:validation-api:1.1.0.Final
org.jboss.resteasy:resteasy-validator-provider-11:3.0.18.Final
  1. 在接口参数用使用
public class CompanyNewsCommand {
	
	@NotBlank(message="{title.not.blank}")
	private String title;
	
	@NotBlank(message="{content.not.blank}")
	@Length(max=65535,message="{content.length.max}")
	private String content;
	.........
}
  1. 捕获检验异常和message并输出 提供bean,并且注入spring
@Provider
public class ValidationExceptionHandler implements ExceptionMapper<ResteasyViolationException> {

	private static final String JSON_CONTENT_TYPE = "application/json;charset=UTF-8";

	@Override
	public Response toResponse(ResteasyViolationException exception) {
		StatusType statusType = Status.BAD_REQUEST;
		String errorCode = Integer.toString(statusType.getStatusCode());
		StringBuilder sb = new StringBuilder();
		for (ResteasyConstraintViolation violation : exception.getViolations()) {
			sb.append(violation.getMessage());
			sb.append(" ");
		}
		RestResponse entity = new RestResponse(errorCode, sb.toString());
		ResponseBuilder builder = Response.status(statusType).entity(entity);
		builder.header("Content-Type", JSON_CONTENT_TYPE);
		return builder.build();
	}

}

具体的缓存和多文件读取可以自行实现

4.国际化 在根目录中放置ValidationMessages_zh_CN.properties文件

title.not.blank=\u6807\u9898\u4E0D\u80FD\u4E3A\u7A7A
content.length.max=\u5185\u5BB9\u8D85\u8FC7\u6700\u5927\u957F\u5EA6\u6216\u8005\u56FE\u7247\u8FC7\u5927

提示信息国际化

我们这里主要讲在集成过程中遇到的问题

  1. 国际化文本 ValidationMessages_zh_CN.properties 必须放在根目录
  2. ValidationMessages_zh_CN.properties编码类型必须是ISO-8859-1,不能是utf-8
  3. ValidationMessages_zh_CN.properties文件名称不能更改
  4. 在非LANG=zh_CN.UTF-8环境中运行时国际化文本没有起作用
服务器上
# echo $LANG
en_US.UTF-8

本地
zh_CN.UTF-8

问题原因

ResourceBundleMessageInterpolator的实现问题

  • 该MessageInterpolator 写死了必须使用ValidationMessages_zh_CN.properties 文件,并且放置于根目录
  • 该MessageInterpolator 使用java.util.ResourceBundle 来解析properties文件,ResourceBundle在读取properties文件时统一使用iso8859-1编码
  • ResourceBundleMessageInterpolator 使用PlatformResourceBundleLocator来加载ResourceBundle,根据操作系统的LANG设置来加载,要求平台必须是LANG=zh_CN.UTF-8,并且该方式限制了只有一个properties 文件

对于国际化的问题,在springmvc+hivernate validation 中已经很好的解决了 但是对于resteasy,没有看到很好的解决方案

解决方案

  1. 添加 /META-INF/validation.xml
<validation-config
	xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration">

	<message-interpolator>com.dzj.frw.rest.validation.MyResourceBundleMessageInterpolator</message-interpolator>

</validation-config>
  1. 重写 ResourceBundleMessageInterpolator
public class MyResourceBundleMessageInterpolator extends org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator {
	private static final Logger LOGGER = LoggerFactory.getLogger(DzjResourceBundleMessageInterpolator.class);
	
	public DzjResourceBundleMessageInterpolator() {
	//在这里改写properties 文件名
		super(new PlatformResourceBundleLocator("ValidationMessages1"));
	}
	@Override
	public String interpolate(String message, Context context) {
	// 在这里改写编码
		String result = super.interpolate(message, context);
		try {
			return new String(result.getBytes("ISO-8859-1"),"UTF-8");
		} catch (UnsupportedEncodingException e) {
			return result;
		}
	}
}

进一步方案

这个方案还是有问题,不能支持多个文件的读,我们完全可以自己实现javax.validation.MessageInterpolator,用java.util.properties 来读取,并且支持多个文件,同时缓存内容到内存。

public class PropertiesMessageInterpolator  implements MessageInterpolator{

	@Override
	public String interpolate(String key, Context context) {
       String messageKey = StringUtils.trimPrefix(key, "{");
        messageKey = StringUtils.trimSuffix(messageKey, "}");
        Locale locale = LocaleContextHolder.getLocaleContext().getLocale();
        return interpolate(messageKey,context,locale);
	}

	@Override
	public String interpolate(String messageKey, Context context, Locale locale) {
        String message = MessageBundle.getInstance(locale).getString(messageKey);
		return message;
	}

}

具体的多文件读取和缓存可以自己实现。

reference

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值