因此, 可以
使用
ParamConverter/
来完成
ParamConverterProvider。我们只需要注入即可
ResourceInfo。从那里我们可以获取资源
Method,并进行一些反思。下面是我测试过的示例实现,大部分都可以使用。
import java.lang.reflect.Type;import java.lang.reflect.Method;import java.lang.reflect.Parameter;import java.lang.annotation.Annotation;import java.util.Set;import java.util.HashSet;import java.util.Collections;import javax.ws.rs.FormParam;import javax.ws.rs.QueryParam;import javax.ws.rs.core.Context;import javax.ws.rs.ext.Provider;import javax.ws.rs.container.ResourceInfo;import javax.ws.rs.ext.ParamConverter;import javax.ws.rs.ext.ParamConverterProvider;import javax.ws.rs.BadRequestException;import javax.ws.rs.InternalServerErrorException;@Providerpublic class base32UUIDParamConverter implements ParamConverterProvider { @Context private javax.inject.Provider<ResourceInfo> resourceInfo; private static final Set<Class<? extends Annotation>> ANNOTATIONS; static { Set<Class<? extends Annotation>> annots = new HashSet<>(); annots.add(QueryParam.class); annots.add(FormParam.class); ANNOTATIONS = Collections.<Class<? extends Annotation>>unmodifiableSet(annots); } @Override public <T> ParamConverter<T> getConverter(Class<T> type, Type type1, Annotation[] annots) { // Check if it is @FormParam or @QueryParam for (Annotation annotation : annots) { if (!ANNOTATIONS.contains(annotation.annotationType())) { return null; } } if (base32UUID.class == type) { return new ParamConverter<T>() { @Override public T fromString(String value) { try { Method method = resourceInfo.get().getResourceMethod(); Parameter[] parameters = method.getParameters(); Parameter actualParam = null; // Find the actual matching parameter from the method. for (Parameter param : parameters) { Annotation[] annotations = param.getAnnotations(); if (matchingAnnotationValues(annotations, annots)) { actualParam = param; } } // null warning, but assuming my logic is correct, // null shouldn't be possible. Maybe check anyway :-) String paramName = actualParam.getName(); System.out.println("Param name : " + paramName); base32UUID uuid = new base32UUID(value, paramName); return type.cast(uuid); } catch (base32UUIDException ex) { throw new BadRequestException(ex.getMessage()); } catch (Exception ex) { throw new InternalServerErrorException(ex); } } @Override public String toString(T t) { return ((base32UUID) t).value; } }; } return null; } private boolean matchingAnnotationValues(Annotation[] annots1, Annotation[] annots2) throws Exception { for (Class<? extends Annotation> annotType : ANNOTATIONS) { if (isMatch(annots1, annots2, annotType)) { return true; } } return false; } private <T extends Annotation> boolean isMatch(Annotation[] a1, Annotation[] a2, Class<T> aType) throws Exception { T p1 = getParamAnnotation(a1, aType); T p2 = getParamAnnotation(a2, aType); if (p1 != null && p2 != null) { String value1 = (String) p1.annotationType().getMethod("value").invoke(p1); String value2 = (String) p2.annotationType().getMethod("value").invoke(p2); if (value1.equals(value2)) { return true; } } return false; } private <T extends Annotation> T getParamAnnotation(Annotation[] annotations, Class<T> paramType) { T paramAnnotation = null; for (Annotation annotation : annotations) { if (annotation.annotationType() == paramType) { paramAnnotation = (T) annotation; break; } } return paramAnnotation; }}有关实施的一些注意事项
- 最重要的部分是如何
ResourceInfo
注入。由于需要在请求范围上下文中进行访问,因此我注入了javax.inject.Provider
,这使我们可以延迟检索对象。当我们实际执行get()
此操作时,它将在请求范围内。
需要注意的是,
get()必须
在的
fromString方法内部调用它
ParamConverter。在应用程序加载期间,多次调用的
getConverter方法
ParamConverterProvider,因此我们无法
get()在这段时间内尝试调用。
java.lang.reflect.Parameter
我使用的类是Java 8类,因此,要使用此实现,您需要使用Java8。如果您不使用Java 8,则本文章可能会有助于尝试以其他方式获取参数名称。与上述观点,编译器参数
-parameters
进行编译时的指出了应用,才能够访问形式参数的名称,在这里。我只是将其放在链接中指出的maven-cmpiler-plugin中。<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>2.5.1</version><inherited>true</inherited><configuration> <compilerArgument>-parameters</compilerArgument> <testCompilerArgument>-parameters</testCompilerArgument> <source>1.8</source> <target>1.8</target></configuration>



