mirror of
https://gitee.com/jmix/cuba.git
synced 2024-12-03 19:57:36 +08:00
PL-8907 Rest API V2: queries params with list types
This commit is contained in:
parent
77f4529ba7
commit
556a7c63d1
@ -16,7 +16,11 @@
|
||||
|
||||
package com.haulmont.restapi.common;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.haulmont.chile.core.datatypes.Datatypes;
|
||||
import com.haulmont.chile.core.datatypes.impl.*;
|
||||
import com.haulmont.chile.core.model.MetaClass;
|
||||
@ -26,14 +30,13 @@ import com.haulmont.cuba.core.global.Metadata;
|
||||
import com.haulmont.restapi.transform.JsonTransformationDirection;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.ParseException;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*/
|
||||
@ -49,7 +52,7 @@ public class RestParseUtils {
|
||||
@Inject
|
||||
protected Metadata metadata;
|
||||
|
||||
public Object toObject(Type type, String value, String modelVersion) throws ParseException {
|
||||
public Object toObject(Type type, String value, @Nullable String modelVersion) throws ParseException {
|
||||
if (value == null) return null;
|
||||
Class clazz;
|
||||
Class argumentTypeClass = null;
|
||||
@ -129,4 +132,26 @@ public class RestParseUtils {
|
||||
Gson gson = new Gson();
|
||||
return gson.toJson(instance);
|
||||
}
|
||||
|
||||
public Map<String, String> parseParamsJson(String paramsJson) {
|
||||
Map<String, String> result = new LinkedHashMap<>();
|
||||
if (Strings.isNullOrEmpty(paramsJson)) return result;
|
||||
|
||||
JsonParser jsonParser = new JsonParser();
|
||||
JsonObject jsonObject = jsonParser.parse(paramsJson).getAsJsonObject();
|
||||
|
||||
for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
|
||||
String paramName = entry.getKey();
|
||||
JsonElement paramValue = entry.getValue();
|
||||
if (paramValue.isJsonNull()) {
|
||||
result.put(paramName, null);
|
||||
} else if (paramValue.isJsonPrimitive()) {
|
||||
result.put(paramName, paramValue.getAsString());
|
||||
} else {
|
||||
result.put(paramName, paramValue.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ public class EntitiesController {
|
||||
String resultJson = entitiesControllerManager.loadEntitiesList(entityName, view, limit, offset, sort, returnNulls, dynamicAttributes, modelVersion);
|
||||
ResponseEntity.BodyBuilder responseBuilder = ResponseEntity.status(HttpStatus.OK);
|
||||
if (BooleanUtils.isTrue(returnCount)) {
|
||||
String count = queriesControllerManager.getCount(entityName, RestQueriesConfiguration.ALL_ENTITIES_QUERY_NAME, modelVersion, new HashMap<>());
|
||||
String count = queriesControllerManager.getCountGet(entityName, RestQueriesConfiguration.ALL_ENTITIES_QUERY_NAME, modelVersion, new HashMap<>());
|
||||
responseBuilder.header("X-Total-Count", count);
|
||||
}
|
||||
return responseBuilder.body(resultJson);
|
||||
|
@ -40,7 +40,7 @@ public class QueriesController {
|
||||
protected QueriesControllerManager queriesControllerManager;
|
||||
|
||||
@GetMapping("/{entityName}/{queryName}")
|
||||
public ResponseEntity<String> executeQuery(@PathVariable String entityName,
|
||||
public ResponseEntity<String> executeQueryGet(@PathVariable String entityName,
|
||||
@PathVariable String queryName,
|
||||
@RequestParam(required = false) Integer limit,
|
||||
@RequestParam(required = false) Integer offset,
|
||||
@ -50,21 +50,50 @@ public class QueriesController {
|
||||
@RequestParam(required = false) Boolean returnCount,
|
||||
@RequestParam(required = false) String modelVersion,
|
||||
@RequestParam Map<String, String> params) {
|
||||
String resultJson = queriesControllerManager.executeQuery(entityName, queryName, limit, offset, view, returnNulls, dynamicAttributes, modelVersion, params);
|
||||
String resultJson = queriesControllerManager.executeQueryGet(entityName, queryName, limit, offset, view, returnNulls, dynamicAttributes, modelVersion, params);
|
||||
ResponseEntity.BodyBuilder responseBuilder = ResponseEntity.status(HttpStatus.OK);
|
||||
if (BooleanUtils.isTrue(returnCount)) {
|
||||
String count = queriesControllerManager.getCount(entityName, queryName, modelVersion, params);
|
||||
String count = queriesControllerManager.getCountGet(entityName, queryName, modelVersion, params);
|
||||
responseBuilder.header("X-Total-Count", count);
|
||||
}
|
||||
return responseBuilder.body(resultJson);
|
||||
}
|
||||
|
||||
@PostMapping("/{entityName}/{queryName}")
|
||||
public ResponseEntity<String> executeQueryPost(@PathVariable String entityName,
|
||||
@PathVariable String queryName,
|
||||
@RequestParam(required = false) Integer limit,
|
||||
@RequestParam(required = false) Integer offset,
|
||||
@RequestParam(required = false) String view,
|
||||
@RequestParam(required = false) Boolean returnNulls,
|
||||
@RequestParam(required = false) Boolean dynamicAttributes,
|
||||
@RequestParam(required = false) Boolean returnCount,
|
||||
@RequestParam(required = false) String modelVersion,
|
||||
@RequestBody String paramsJson) {
|
||||
|
||||
String resultJson = queriesControllerManager.executeQueryPost(entityName, queryName, limit, offset, view, returnNulls, dynamicAttributes, modelVersion, paramsJson);
|
||||
ResponseEntity.BodyBuilder responseBuilder = ResponseEntity.status(HttpStatus.OK);
|
||||
if (BooleanUtils.isTrue(returnCount)) {
|
||||
String count = queriesControllerManager.getCountPost(entityName, queryName, modelVersion, paramsJson);
|
||||
responseBuilder.header("X-Total-Count", count);
|
||||
}
|
||||
return responseBuilder.body(resultJson);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/{entityName}/{queryName}/count", produces = "text/plain;charset=UTF-8")
|
||||
public String getCount(@PathVariable String entityName,
|
||||
public String getCountGet(@PathVariable String entityName,
|
||||
@PathVariable String queryName,
|
||||
@RequestParam(required = false) String modelVersion,
|
||||
@RequestParam Map<String, String> params) throws ClassNotFoundException, ParseException {
|
||||
return queriesControllerManager.getCount(entityName, queryName, modelVersion, params);
|
||||
return queriesControllerManager.getCountGet(entityName, queryName, modelVersion, params);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/{entityName}/{queryName}/count", produces = "text/plain;charset=UTF-8")
|
||||
public String getCountPost(@PathVariable String entityName,
|
||||
@PathVariable String queryName,
|
||||
@RequestParam(required = false) String modelVersion,
|
||||
@RequestBody String paramsJson) throws ClassNotFoundException, ParseException {
|
||||
return queriesControllerManager.getCountPost(entityName, queryName, modelVersion, paramsJson);
|
||||
}
|
||||
|
||||
@GetMapping("/{entityName}")
|
||||
|
@ -17,6 +17,9 @@
|
||||
package com.haulmont.restapi.service;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.haulmont.chile.core.datatypes.Datatypes;
|
||||
import com.haulmont.chile.core.datatypes.impl.*;
|
||||
import com.haulmont.chile.core.model.MetaClass;
|
||||
@ -30,6 +33,7 @@ import com.haulmont.cuba.core.global.Metadata;
|
||||
import com.haulmont.cuba.core.global.Security;
|
||||
import com.haulmont.cuba.security.entity.EntityOp;
|
||||
import com.haulmont.restapi.common.RestControllerUtils;
|
||||
import com.haulmont.restapi.common.RestParseUtils;
|
||||
import com.haulmont.restapi.exception.RestAPIException;
|
||||
import com.haulmont.restapi.config.RestQueriesConfiguration;
|
||||
import com.haulmont.restapi.transform.JsonTransformationDirection;
|
||||
@ -40,6 +44,7 @@ import org.springframework.util.ClassUtils;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import java.lang.reflect.Array;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.ParseException;
|
||||
import java.util.*;
|
||||
@ -68,15 +73,35 @@ public class QueriesControllerManager {
|
||||
@Inject
|
||||
protected PersistenceManagerClient persistenceManagerClient;
|
||||
|
||||
public String executeQuery(String entityName,
|
||||
String queryName,
|
||||
@Nullable Integer limit,
|
||||
@Nullable Integer offset,
|
||||
@Nullable String viewName,
|
||||
@Nullable Boolean returnNulls,
|
||||
@Nullable Boolean dynamicAttributes,
|
||||
@Nullable String version,
|
||||
Map<String, String> params) {
|
||||
@Inject
|
||||
protected RestParseUtils restParseUtils;
|
||||
|
||||
public String executeQueryGet(String entityName,
|
||||
String queryName,
|
||||
@Nullable Integer limit,
|
||||
@Nullable Integer offset,
|
||||
@Nullable String viewName,
|
||||
@Nullable Boolean returnNulls,
|
||||
@Nullable Boolean dynamicAttributes,
|
||||
@Nullable String version,
|
||||
Map<String, String> params) {
|
||||
return _executeQuery(entityName, queryName, limit, offset, viewName, returnNulls, dynamicAttributes, version, params);
|
||||
}
|
||||
|
||||
public String executeQueryPost(String entityName,
|
||||
String queryName,
|
||||
@Nullable Integer limit,
|
||||
@Nullable Integer offset,
|
||||
@Nullable String viewName,
|
||||
@Nullable Boolean returnNulls,
|
||||
@Nullable Boolean dynamicAttributes,
|
||||
@Nullable String version,
|
||||
String paramsJson) {
|
||||
Map<String, String> paramsMap = restParseUtils.parseParamsJson(paramsJson);
|
||||
return _executeQuery(entityName, queryName, limit, offset, viewName, returnNulls, dynamicAttributes, version, paramsMap);
|
||||
}
|
||||
|
||||
protected String _executeQuery(String entityName, String queryName, @Nullable Integer limit, @Nullable Integer offset, @Nullable String viewName, @Nullable Boolean returnNulls, @Nullable Boolean dynamicAttributes, @Nullable String version, Map<String, String> params) {
|
||||
LoadContext<Entity> ctx;
|
||||
entityName = restControllerUtils.transformEntityNameIfRequired(entityName, version, JsonTransformationDirection.FROM_VERSION);
|
||||
try {
|
||||
@ -104,10 +129,22 @@ public class QueriesControllerManager {
|
||||
return json;
|
||||
}
|
||||
|
||||
public String getCount(String entityName,
|
||||
String queryName,
|
||||
String version,
|
||||
Map<String, String> params) {
|
||||
public String getCountGet(String entityName,
|
||||
String queryName,
|
||||
String version,
|
||||
Map<String, String> params) {
|
||||
return _getCount(entityName, queryName, version, params);
|
||||
}
|
||||
|
||||
public String getCountPost(String entityName,
|
||||
String queryName,
|
||||
String version,
|
||||
String paramsJson) {
|
||||
Map<String, String> paramsMap = restParseUtils.parseParamsJson(paramsJson);
|
||||
return _getCount(entityName, queryName, version, paramsMap);
|
||||
}
|
||||
|
||||
protected String _getCount(String entityName, String queryName, String version, Map<String, String> params) {
|
||||
entityName = restControllerUtils.transformEntityNameIfRequired(entityName, version, JsonTransformationDirection.FROM_VERSION);
|
||||
LoadContext<Entity> ctx;
|
||||
try {
|
||||
@ -180,6 +217,20 @@ public class QueriesControllerManager {
|
||||
}
|
||||
|
||||
protected Object toObject(Class clazz, String value) throws ParseException {
|
||||
if (clazz.isArray()) {
|
||||
Class componentType = clazz.getComponentType();
|
||||
JsonParser jsonParser = new JsonParser();
|
||||
JsonArray jsonArray = jsonParser.parse(value).getAsJsonArray();
|
||||
List result = new ArrayList();
|
||||
for (JsonElement jsonElement : jsonArray) {
|
||||
String stringValue = (jsonElement.isJsonPrimitive() && jsonElement.getAsJsonPrimitive().isString()) ?
|
||||
jsonElement.getAsJsonPrimitive().getAsString() :
|
||||
jsonElement.toString();
|
||||
Object arrayElementValue = toObject(componentType, stringValue);
|
||||
result.add(arrayElementValue);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (String.class == clazz) return value;
|
||||
if (Integer.class == clazz || Integer.TYPE == clazz
|
||||
|| Byte.class == clazz || Byte.TYPE == clazz
|
||||
|
@ -84,7 +84,7 @@ public class ServicesControllerManager {
|
||||
|
||||
@Nullable
|
||||
public ServiceCallResult invokeServiceMethodPost(String serviceName, String methodName, String paramsJson, String modelVersion) {
|
||||
Map<String, String> paramsMap = parseParamsJson(paramsJson);
|
||||
Map<String, String> paramsMap = restParseUtils.parseParamsJson(paramsJson);
|
||||
List<String> paramNames = new ArrayList<>(paramsMap.keySet());
|
||||
List<String> paramValuesStr = new ArrayList<>(paramsMap.values());
|
||||
return _invokeServiceMethod(serviceName, methodName, paramNames, paramValuesStr, modelVersion);
|
||||
@ -104,28 +104,6 @@ public class ServicesControllerManager {
|
||||
return serviceInfo;
|
||||
}
|
||||
|
||||
private Map<String, String> parseParamsJson(String paramsJson) {
|
||||
Map<String, String> result = new LinkedHashMap<>();
|
||||
if (Strings.isNullOrEmpty(paramsJson)) return result;
|
||||
|
||||
JsonParser jsonParser = new JsonParser();
|
||||
JsonObject jsonObject = jsonParser.parse(paramsJson).getAsJsonObject();
|
||||
|
||||
for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
|
||||
String paramName = entry.getKey();
|
||||
JsonElement paramValue = entry.getValue();
|
||||
if (paramValue.isJsonNull()) {
|
||||
result.put(paramName, null);
|
||||
} else if (paramValue.isJsonPrimitive()) {
|
||||
result.put(paramName, paramValue.getAsString());
|
||||
} else {
|
||||
result.put(paramName, paramValue.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected ServiceCallResult _invokeServiceMethod(String serviceName, String methodName, List<String> paramNames,
|
||||
List<String> paramValuesStr, String modelVersion) {
|
||||
|
@ -779,6 +779,29 @@ paths:
|
||||
schema:
|
||||
$ref: '#/definitions/error'
|
||||
|
||||
post:
|
||||
tags:
|
||||
- Queries
|
||||
summary: Execute a query
|
||||
description: |
|
||||
Executes a predefined query. Query parameters must be passed in the request body as JSON map.
|
||||
responses:
|
||||
200:
|
||||
description: Success. A list of entitie is returned in the response body.
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/entityFull'
|
||||
403:
|
||||
description: Forbidden. The user doesn't have permissions to read the entity.
|
||||
schema:
|
||||
$ref: '#/definitions/error'
|
||||
404:
|
||||
description: |
|
||||
MetaClass not found or query with the given name not found
|
||||
schema:
|
||||
$ref: '#/definitions/error'
|
||||
|
||||
/queries/{entityName}/{queryName}/count:
|
||||
parameters:
|
||||
- $ref: '#/parameters/entityNameParam'
|
||||
@ -805,6 +828,28 @@ paths:
|
||||
MetaClass not found or query with the given name not found
|
||||
schema:
|
||||
$ref: '#/definitions/error'
|
||||
post:
|
||||
tags:
|
||||
- Queries
|
||||
summary: Return a number of entities in query result
|
||||
description: |
|
||||
Returns a number of entities that matches the query. You can use the `all` keyword for the `queryNameParam`
|
||||
to get the number of all available entities.
|
||||
responses:
|
||||
200:
|
||||
description: Success
|
||||
schema:
|
||||
title: Count
|
||||
type: integer
|
||||
403:
|
||||
description: Forbidden. The user doesn't have permissions to read the entity.
|
||||
schema:
|
||||
$ref: '#/definitions/error'
|
||||
404:
|
||||
description: |
|
||||
MetaClass not found or query with the given name not found
|
||||
schema:
|
||||
$ref: '#/definitions/error'
|
||||
|
||||
############################### Services #######################################
|
||||
/services/{serviceName}:
|
||||
|
Loading…
Reference in New Issue
Block a user