工具类-controller解析枚举

文章介绍了如何在SpringMVC中因自带的枚举解析器无法解析ordinal而创建自定义的@EnumParam注解和对应的EnumArgumentResolver参数解析器。该注解用于标记Controller方法的参数,解析器则负责将前端传入的字符串或ordinal转换为对应的枚举类型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于spring mvc自带的枚举解析器无法解析ordinal,所以自己写了一个,方便以后其他项目中用到
一:创建一个controller方法中的参数上使用的注解

import org.springframework.core.annotation.AliasFor;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 这个注解用于标记在Controller方法的参数上,表示该参数是个枚举,此时会将前端传递的字符串或者ordinal转换成该枚举类
 *
 * @author shiwentian
 * @since 7.6.2023
 **/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface EnumParam {

    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";

    String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}

二:实现参数解析器


import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.List;

/**
 * 解析Controller方法中标记{@link EnumParam}注解的参数
 *
 * @author shiwentian
 * @since 07.06.2023
 */
@Component
public class EnumArgumentResolver implements HandlerMethodArgumentResolver, WebMvcConfigurer {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(this);
    }

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        Annotation[] annotations = parameter.getParameterAnnotations();
        for (Annotation annotation : annotations) {
            if (annotation.annotationType() == EnumParam.class) {
                return true;
            }
        }
        return false;
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        HttpServletRequest httpRequest = webRequest.getNativeRequest(HttpServletRequest.class);
        if (httpRequest == null) {
            return null;
        }
        Parameter enumParam = parameter.getParameter();
        EnumParam enumAnnotation = parameter.getParameterAnnotation(EnumParam.class);
        String queryStringName = enumAnnotation.value();
        String queryStringValue = httpRequest.getParameter(queryStringName);
        if (queryStringValue.matches("^[0-9]+$")) {
            int ordinal = Integer.parseInt(queryStringValue);
            Object[] enumObjects = enumParam.getType().getEnumConstants();
            for (Object enumObject : enumObjects) {
                Method ordinalMethod = enumObject.getClass().getMethod("ordinal");
                int ordinalIndex = (int) ordinalMethod.invoke(enumObject);
                if (ordinal == ordinalIndex) {
                    return enumObject;
                }
            }
            return null;
        } else {
            Object[] enumObjects = enumParam.getType().getEnumConstants();
            for (Object enumObject : enumObjects) {
                Method nameMethod = enumObject.getClass().getMethod("name");
                Object enumName = nameMethod.invoke(enumObject);
                if (enumName.equals(queryStringValue)) {
                    return enumObject;
                }
            }
            return null;
        }
    }

}

三:使用示例(我只实现了get请求)

@GetMapping("xxx/xxx")
public 返回类型 test(@EnumParam("type") UserType userType) {
	System.out.print(userType);
    return XXX;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值