如何结合Sping与Java封装自己的Exception?

         本文要实现的一个功能是将异常封装,并在抛出时能映射到对应的中文提示,同时这个异常抛出中文信息可以动态变化。

        简单思路:将异常码对应的code-value关系写到property文件中去,spring加载这个配置文件内容器中去。然后封装一个exception,每次抛出异常时就根据对应的code值去找到它对应的中文码值,并且要实现异常信息可以在运行时动态改变。对于第二点一般如何异常信息用枚举的话,动态更改参数不是很方便。所以结合spring来设计自己的一个异常类。

下面来讲讲步骤

1、定义PropertyPlaceholderConfigurer

专门用来读取配置文件到Spring中中中

package com.lin.config;

import java.io.IOException;
import java.util.Properties;
/**
 * 初始化配置文件
 * @author linbingwen
 *
 */
public class PropertyPlaceholderConfigurer extends
		org.springframework.beans.factory.config.PropertyPlaceholderConfigurer {

	private static Properties props;

	public Properties mergeProperties() throws IOException {
		props = super.mergeProperties();
		Property.init(props);
		return props;
	}

	public static String getProperty(String key) {
		return props.getProperty(key);
	}

	public String getProperty(String key, String defaultValue) {
		return props.getProperty(key, defaultValue);

	}

}
使用方法为在spring的配置文件中application.xml:

	<bean id="propertyConfigurer"
		class="com.lin.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<list>
                <value>classpath:properties/*.properties</value>
            </list>
		</property>
		<property name="fileEncoding" value="UTF-8"/>
		<property name="ignoreUnresolvablePlaceholders" value="true" />
	</bean>	

这样就将配置文件加载到Spring中去

配置文件的内容示例如下,它就放在ctsErrorCode.properties:

注意下面这个文件要改成iso标准编码

##/***
##* 公用错误码
##*/
CTS00000=处理成功
CTS99999=未知错误
CTSWB888=查无此记录

##/***
##* WB--业务WARN--公用错误码--CTSWBA01-CTSWBA99
##*/
CTSWBA01=【{0}】为空
CTSWBA02=参数【{0}】格式错误
CTSWBA03=参数【{0}】错误
CTSWBA04=参数【{0}】长度错误
CTSWBA05={0}不匹配
CTSWBA06=未查询到{0}
CTSWBA07=参数【{0}】应大于0
CTSWBA08={0}不能修改
CTSWBA09=参数【{0}】应大于或等于0
CTSWBA10={0}不存在
CTSWBA11=交易参考号重复
CTSWBA12=调用CIF接口根据{0}查询{1}结果为空
CTSWBA13=设置{0}发生异常
CTSWBA14={0}应大于或等于{1}
{}里面可以动态改变



定义一个用来取配置文件的工具:

package com.lin.config;


/**
 * 用于在java类中取得配置文件变量的值
 * @author linbingwen
 *
 */
public class Property {

	private static java.util.Properties property;

	private Property() {
	}

	static void init(java.util.Properties props) {
		property = props;
	}

	public static String getProperty(String key) {
		return property.getProperty(key);
	}

	public static String getProperty(String key, String defaultValue) {
		return property.getProperty(key, defaultValue);
	}

}

2、封装异常类

package com.lin.exception;

import java.text.MessageFormat;

import com.lin.errorcode.ErrorCode;

/**
 * 
 * <b>类说明:</b>Service层统一抛出的异常
 * 
 * <p>
 * <b>详细描述:</b>
 * 
 * @author costin_law 
 * @since 2014-5-5
 */
public class ServiceException extends RuntimeException {	

    private static final long serialVersionUID = 6514891174875747380L;

    private ErrorCode errorCode;
    /** 异常错误码 **/
    private String code;

    /** 异常描述 **/
    private String msg; 
    /** 扩展异常描述(包括msg) **/
    private String extMsg;

    /**
     * ServiceException构造方法,有format字符组
     * @param errorCode 错误码
     * @param param     format字符组
     * @param extMsg    扩展信息,给出具体的错误值信息等
     */
    public ServiceException(ErrorCode errorCode,String param[],String ... extMsg) {
        super(null==errorCode ? "" : errorCode.getCode());
        init(errorCode, param,extMsg);
    }

    /**
     * ServiceException构造方法,有format字符组
     * @param errCode
     * @param paramsList
     */
    public ServiceException(ErrorCode errCode, Object... paramsList) {
    	super(null==errCode ? "" : errCode.getCode());
        Object[] params = null;
        if ((paramsList != null) && (paramsList.length > 0) 
                && ((paramsList[(paramsList.length - 1)] instanceof Throwable))) 
        {
            Object[] newParam = new Object[paramsList.length - 1];
            System.arraycopy(paramsList, 0, newParam, 0, newParam.length);
            params = newParam;
            super.initCause((Throwable)paramsList[(paramsList.length - 1)]);
        }
        else {
            params = paramsList;
            super.initCause(null);
        }
        this.errorCode = errCode;
        this.code = null==errCode ? "" : errCode.getCode();
        this.msg = null==errCode ? "" :  MessageFormat.format(errCode.getMsg(),params);  
        this.extMsg = this.msg;
    }

    private void init(ErrorCode errorCode, String param[], String... extMsg) {
        this.errorCode = errorCode;
        this.code = null==errorCode ? "" : errorCode.getCode();
        this.msg = null==errorCode ? "" : MessageFormat.format(errorCode.getMsg(),param);
        StringBuilder builder = new StringBuilder(100);
        builder.append(this.msg);
        if(null != extMsg){
            for(String ext : extMsg ){
                builder.append("[").append(ext).append("]");
            }
        }
        this.extMsg = builder.toString();
    }

    /**
     * 
     * @param code  错误码
     * @param msg 描述信息
     */
    public ServiceException(String code, String msg) {
        super(code+":"+msg);
        this.code = code;
        this.msg = msg;
        this.extMsg = msg;
    }

    /**
     * 带Exception的构造方法,传format字符数组
     * @param errorCode 错误码基类
     * @param e  异常
     * @param extMsg    扩展信息,给出具体的错误值信息等
     */
    public ServiceException(ErrorCode errorCode, Throwable e,String param[] , String ...extMsg ) {
        super(null==errorCode ? "" : errorCode.getCode(), e);
        init(errorCode, param, extMsg);
    }

    /**
     * 
     * @param code 错误码
     * @param msg 描述信息
     * @param e  异常
     */
    /*public ServiceException(String code, String msg,Throwable e) {
		super(code+":"+msg, e);
		this.code = code;
		this.msg = msg; 
	}*/

    /**
     * 
     * 
     * 方法说明:异常错误码
     * 
     * @return
     */
    public String getCode() {
        return code;
    }

    /**
     * 
     * 
     * 方法说明:异常描述信息
     * 
     * @return
     */
    public String getMsg() {
        return msg;
    }

    public String getExtMsg() {
        return extMsg;
    }

    @Override
    public String getMessage() {		
        return super.getMessage() + ","+extMsg;
    }	

    public static void main(String[] args) {

    }

    
    public ErrorCode getErrorCode() {
        return errorCode;
    }

    
    public void setErrorCode(ErrorCode errorCode) {
        this.errorCode = errorCode;
    }

}

每次异常抛出时都要指明一个ErrorCode的类,

package com.lin.errorcode;

public interface ErrorCode {
	public String getCode();
	
	public String getMsg();
}
它是一个接口,实现类如下:

package com.lin.errorcode;

import com.lin.config.Property;
/**
 * 功能概要:CTS错误码
 * @author linbingwen
 *
 */
public enum CtsErrorCode implements ErrorCode {

    /**
     * 前三位固定:CTS  第四位表示日志级别:W/E   第五位系统错误类型:B业务类型/S系统类型    第六位:A公共错误码/B批量错误码/数字则为普通错误码
     */

    /***
     * 公用错误码
     */
    SUCCESS("CTS00000"), // 处理成功
    UNKHOWN_ERROR("CTS99999");// 未知错误


    private String code;

    private CtsErrorCode(String code) {
        this.code = code;
    }

    @Override
    public String getCode() {
        return this.code;
    }

    @Override
    public String getMsg() {
    	String msg = Property.getProperty(this.code);
        return msg == null ? "" : msg;
    }

}
注意这里的 String msg = Property.getProperty(this.code);

这里会从Spring中容器去取到配置文件。

3、使用

	@Test
	public void test(){
      throw new ServiceException(CtsErrorCode.ERROR_FORMAT,"参数格式出错");
	}
	

这里注意到异常信息有些部分可以动态传入进去。


  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot中,我们可以通过自定义拦截器来实现获取头部语言参数的封装。 首先,我们需要自定义一个拦截器,在拦截器中获取头部语言参数,并将其保存在本地线程中。代码如下: ```java public class LanguageInterceptor implements HandlerInterceptor { private static final ThreadLocal<String> languageHolder = new ThreadLocal<>(); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String language = request.getHeader("accept-language"); languageHolder.set(language); return true; } public static String getLanguage() { return languageHolder.get(); } public static void clearLanguage() { languageHolder.remove(); } } ``` 然后,我们需要在Spring Boot的配置文件中注册这个拦截器,并配置它的拦截路径。代码如下: ```java @Configuration public class InterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LanguageInterceptor()).addPathPatterns("/**"); } } ``` 最后,在我们的业务逻辑中,我们可以通过调用`LanguageInterceptor.getLanguage()`方法来获取头部语言参数。代码如下: ```java @RestController public class ExampleController { @GetMapping("/") public String hello() { String language = LanguageInterceptor.getLanguage(); // do something with language return "Hello"; } } ``` 需要注意的是,在业务逻辑中,我们需要在使用完头部语言参数后,调用`LanguageInterceptor.clearLanguage()`方法来清除本地线程中的数据,以避免内存泄漏。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值