Spring 请求参数(包装类)非法情况下的转换

参考资料:

http://jinnianshilongnian.iteye.com/blog/1723270

http://www.bubuko.com/infodetail-1428732.html

使用spring类型转换器注册器、类型转换服务:提供类型转换器注册支持,运行时类型转换API支持。

1、ConverterRegistry:类型转换器注册支持,可以注册/删除相应的类型转换器。

2、ConversionService:运行时类型转换服务接口,提供运行期类型转换的支持。

Spring提供了两个默认实现(其都实现了ConverterRegistry、ConversionService接口):

DefaultConversionService:默认的类型转换服务实现;

DefaultFormattingConversionService:带数据格式化支持的类型转换服务实现,一般使用该服务实现即可。

问题:

比如 参数为Integer 为空或非数字 则默认为负数,返回

条件:Integer 负数 没有任何意义或者参数非法的定义

查询spring  

StringToNumberConverterFactory   String----->Number(如Integer、Long等)

创建类实现Converter接口,例如返回MyStringToIntegerConverter对Integer类型进行必要的处理

package com.jyt.advice;

import org.springframework.core.convert.converter.Converter;

public class MyStringToIntegerConverter implements Converter<String, Integer> {

    @Override
    public Integer convert(String source) {
        System.out.println("转换前---------StringTOInteger转换:" + source);
        if (source.length() == 0) {
            return -1;
        }
        boolean isnumber = org.apache.commons.lang.StringUtils.isNumeric(source);
        source = isnumber == true ? source : "-1";
        System.out.println("转换后---------StringTOInteger转换:" + Integer.valueOf(source));
        return Integer.valueOf(source);
    }

}

 Spring 配置:

<mvc:annotation-driven conversion-service="conversionService"/>
<!-- 注册ConversionService -->  
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">  
    <property name="converters">  
       <list>  
            <bean class="com.jyt.advice.MyStringToIntegerConverter"/>  
        </list>  
    </property>  
</bean>  

对数字类工厂转换:

package com.jyt.advice;

import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;

public class MyStringToNumberConverterFactory implements ConverterFactory<String, Number> {

    @Override
    public <T extends Number> Converter<String, T> getConverter(Class<T> targetType) {
        return new StringToNumber<T>(targetType);
    }

    private static final class StringToNumber<T extends Number> implements Converter<String, T> {

        private final Class<T> targetType;

        public StringToNumber(Class<T> targetType) {
            this.targetType = targetType;
        }

        @Override
        public T convert(String source) {
            System.out.println("启动自定义的Integer转换类型转化器");
            if (source.length() == 0) {
                return null;
            }
            return MyNumberUtils.myParseNumber(source, this.targetType);
        }
    }

}
package com.jyt.advice;

import java.math.BigDecimal;
import java.math.BigInteger;

import org.springframework.util.Assert;
import org.springframework.util.NumberUtils;
import org.springframework.util.StringUtils;

public class MyNumberUtils extends NumberUtils {

    @SuppressWarnings("unchecked")
    public static <T extends Number> T myParseNumber(String text, Class<T> targetClass) {
        Assert.notNull(text, "Text must not be null");
        Assert.notNull(targetClass, "Target class must not be null");
        String trimmed = StringUtils.trimAllWhitespace(text);

        if (targetClass.equals(Byte.class)) {
            return (T) (isHexNumber(trimmed) ? Byte.decode(trimmed) : Byte.valueOf(trimmed));
        } else if (targetClass.equals(Short.class)) {
            return (T) (isHexNumber(trimmed) ? Short.decode(trimmed) : Short.valueOf(trimmed));
        } else if (targetClass.equals(Integer.class)) {
            System.out.println("StringTOInteger转换");
            boolean isnumber = org.apache.commons.lang.StringUtils.isNumeric(text);
            text = isnumber == true ? text : "-1";
            return (T) (isHexNumber(trimmed) ? Integer.decode(trimmed) : Integer.valueOf(trimmed));
        } else if (targetClass.equals(Long.class)) {
            System.out.println("StringTOLong转换");
            boolean isnumber = org.apache.commons.lang.StringUtils.isNumeric(text);
            text = isnumber == true ? text : "-1";
            return (T) (isHexNumber(trimmed) ? Long.decode(trimmed) : Long.valueOf(trimmed));
        } else if (targetClass.equals(BigInteger.class)) {
            System.out.println("StringTOBigInteger转换");
            boolean isnumber = org.apache.commons.lang.StringUtils.isNumeric(text);
            text = isnumber == true ? text : "-1";
            return (T) (isHexNumber(trimmed) ? decodeBigInteger(trimmed) : new BigInteger(trimmed));
        } else if (targetClass.equals(Float.class)) {
            return (T) Float.valueOf(trimmed);
        } else if (targetClass.equals(Double.class)) {
            return (T) Double.valueOf(trimmed);
        } else if (targetClass.equals(BigDecimal.class) || targetClass.equals(Number.class)) {
            return (T) new BigDecimal(trimmed);
        } else {
            throw new IllegalArgumentException("Cannot convert String [" + text + "] to target class [" + targetClass.getName() + "]");
        }
    }

    /**
     * Determine whether the given value String indicates a hex number, i.e. needs to be
     * passed into <code>Integer.decode</code> instead of <code>Integer.valueOf</code> (etc).
     */
    private static boolean isHexNumber(String value) {
        int index = (value.startsWith("-") ? 1 : 0);
        return (value.startsWith("0x", index) || value.startsWith("0X", index) || value.startsWith("#", index));
    }

    /**
     * Decode a {@link java.math.BigInteger} from a {@link String} value.
     * Supports decimal, hex and octal notation.
     * 
     * @see BigInteger#BigInteger(String, int)
     */
    private static BigInteger decodeBigInteger(String value) {
        int radix = 10;
        int index = 0;
        boolean negative = false;

        // Handle minus sign, if present.
        if (value.startsWith("-")) {
            negative = true;
            index++;
        }

        // Handle radix specifier, if present.
        if (value.startsWith("0x", index) || value.startsWith("0X", index)) {
            index += 2;
            radix = 16;
        } else if (value.startsWith("#", index)) {
            index++;
            radix = 16;
        } else if (value.startsWith("0", index) && value.length() > 1 + index) {
            index++;
            radix = 8;
        }

        BigInteger result = new BigInteger(value.substring(index), radix);
        return (negative ? result.negate() : result);
    }
}

 Spring 配置:

<mvc:annotation-driven conversion-service="conversionService"/>
<!-- 注册ConversionService -->  
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">  
    <property name="converters">  
       <list>  
            <bean class="com.jyt.advice.MyStringToNumberConverterFactory"/>  
        </list>  
    </property>  
</bean>

猜你喜欢

转载自luchangbin-java.iteye.com/blog/2306277
今日推荐