より複雑な問題の解決策を書きます: map GET params throw MultivaluedMap to Object. 他の人に役立つかもしれません。
GET クエリは、サーバーとチャットするための非常に簡単な方法です。ブラウザーの URL コントロールを使用する非プログラマーでも、単純な API タスクを実行できます。
ただし、「get」クエリからオブジェクトを作成する方法はお勧めしません (理由の 1 つは、シンボルの最大制限が 4000 であることです)。
GET クエリには、デフォルトで MediaType.APPLICATION_OCTET_STREAM があります。
// GOAL: create simple in use API (for non-programmers) to call rest service to test functional. User can use any business object field.
// So need map GET query params to server business object.
// Create Provider and save it in jersey rest folder (for auto detect).
//
// PROBLEM: "get" query hasn't body and query params don't available get from readFrom prodiver method
// So use uriInfo for getting query params
@Provider
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
public class GETQueryMapperProvider<T> implements MessageBodyReader<T> {
//[!!!] MAIN PART: save the uri
@Context
private UriInfo uriInfo;
@Override
public boolean isReadable(Class<?> aClass, Type type, Annotation[] annotations, MediaType mediaType) {
return true;
}
@Override
public T readFrom(Class<T> tClass, Type type, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> stringStringMultivaluedMap,
InputStream inputStream) throws IOException, WebApplicationException {
MultivaluedMap queryParams = uriInfo.getQueryParameters();
//create from Map Object
return ServiceUtils.convertMapToObject(queryParams, tClass);
}
}
そして2番目の部分の解決策:
public static <T> T convertMapToObject(Map map, Class<T> objectClass) {
try {
//[!!!] MAIN PART - MultivaluedMap for each value create list.
//But we list only for fields with collection type, for other need take first value.
map = fixCollectionsValue(map, objectClass);
ObjectMapper ob = new ObjectMapper();
StringWriter json = new StringWriter();
ob.writeValue(json, map);
return ob.readValue(json.toString(), objectClass);
} catch (IOException e) {
log.error(e.getMessage(), e);
}
return null;
}
protected static Map fixCollectionsValue(Map map, Class objectClass) {
Map newMap = new HashMap(map);
for(Field field : objectClass.getDeclaredFields()) {
if(!Modifier.isStatic(field.getModifiers())
&&!Modifier.isFinal(field.getModifiers())) {
String name = field.getName();
Object value = map.get(name);
Object newValue = value;
if(value != null) {
if(isCollectionClass(field.getType())) {
if(!isCollectionClass(value.getClass())) {
newValue = new ArrayList();
((ArrayList) newValue).add(value);
newMap.put(name, newValue);
}
} else {
if(isCollectionClass(value.getClass())) {
//take first value to our object
newValue = ((Collection) newValue).iterator().next();
newMap.put(name, newValue);
}
}
}
}
}
return newMap;
}
protected static boolean isCollectionClass(Class clazz) {
return clazz.isArray() ||
Collection.class.isAssignableFrom(clazz);
}