1、Controller
@RestController
public class ActivitiController extends BaseController {
/**
* Activiti 框架提供的操作 Repository 系列表的 Service
*/
@Autowired
private RepositoryService repositoryService;
@RequestMapping("/activiti/findProcessListPage/{startIndex}/{pageSize}")
public Object findProcessListPage(@PathVariable("startIndex") Integer startIndex, @PathVariable("pageSize") Integer pageSize) {
List<ProcessDefinition> processDefinitions = repositoryService
.createProcessDefinitionQuery()
.listPage(startIndex, pageSize);
System.out.println("---------------" + processDefinitions );
return processDefinitions ;
}
}
2、运行结果
java 控制台消息提示,可以正确的查询出 processDefinitions 结果:
浏览器提示错误消息如下:
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Thu Nov 21 09:27:46 CST 2019
There was an unexpected error (type=Internal Server Error, status=500).
Could not write JSON: (was java.lang.NullPointerException); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: java.util.ArrayList[0]->org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntityImpl["identityLinks"])
org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: (was java.lang.NullPointerException); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: java.util.ArrayList[0]->org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntityImpl["identityLinks"])
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:296)
at org.springframework.http.converter.AbstractGenericHttpMessageConverter.write(AbstractGenericHttpMessageConverter.java:104)
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:295)
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:181)
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:82)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:124)
......
Caused by: com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: java.util.ArrayList[0]->org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntityImpl["identityLinks"])
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:394)
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:353)
at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:316)
......
Caused by: java.lang.NullPointerException
at org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntityImpl.getIdentityLinks(ProcessDefinitionEntityImpl.java:66)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:688)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:721)
... 108 more
3、解决方法
将查询到每条结果封装到一个 Map 中,进多条结果封装到 List 中,将封装的结果返回即可,具体如下:
@RestController
public class ActivitiController extends BaseController {
/**
* Activiti 框架提供的操作 Repository 系列表的 Service
*/
@Autowired
private RepositoryService repositoryService;
@RequestMapping("/activiti/findProcessListPage/{startIndex}/{pageSize}")
public Object findProcessListPage(@PathVariable("startIndex") Integer startIndex, @PathVariable("pageSize") Integer pageSize) {
List<ProcessDefinition> processDefinitions = repositoryService
.createProcessDefinitionQuery()
.listPage(startIndex, pageSize);
// ============= 对上面查询结果进行封装 ==================
List<Map<String, Object>> pdResult = new ArrayList<>();
for (ProcessDefinition processDefinition : processDefinitions) {
Map<String, Object> pdMap = new HashMap<>();
pdMap.put("id", processDefinition.getId());
pdMap.put("key", processDefinition.getKey());
pdMap.put("name", processDefinition.getName());
pdMap.put("version", processDefinition.getVersion());
pdMap.put("deploymentId", processDefinition.getDeploymentId());
pdResult.add(pdMap);
}
// ================== 封装完成 =========================
System.out.println("---------------" + pdResult);
return pdResult;
}
}
运行结果如下:
[{“deploymentId”:“d05c66ec-09ad-11ea-a748-4ccc6ac9b5ee”,“name”:“请假审批流程”,“id”:“holiday:1:d07a9d4f-09ad-11ea-a748-4ccc6ac9b5ee”,“version”:1,“key”:“holiday”}]
4、通用的封装方法
使用反射动态获取类中的 get 方法,将方法的返回值进行封装,如下:
public class Util {
public static List<Map<String, Object>> activitiResult(List<?> objs) {
// 用于存放多个对象的集合
List<Map<String, Object>> pdResult = new ArrayList<>();
// 遍历方法参数中的集合
for (Object obj : objs) {
// 用于封装单个对象 get 方法返回值的 Map 集合
Map<String, Object> pdMap = new HashMap<>();
// 通过反射获取该对象的方法对象数组
Method[] methods = obj.getClass().getDeclaredMethods();
// 遍历方法对象数组
for (Method method : methods) {
// 获取方法名称
String methodName = method.getName();
// 判断该方法是否名称不为 null ,并且名称是以 get 开头,满足条件进入 if 中
if (methodName != null && methodName.startsWith("get")) {
// 设置方法的访问权限
method.setAccessible(true);
try {
// 将方法名的 get 前缀去掉,并增加 pd 前缀
String pdKey = "pb".concat(methodName.substring(3));
// 将 get 方法的名称作为 Map 的 key,将返回值作为 value 进行封装
pdMap.put(pdKey, method.invoke(obj, null));
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 将封装好的 Map 集合添加到 List 集合中
pdResult.add(pdMap);
}
return pdResult;
}
}
在需要封装结果的方法中调用此方法即可:
@RequestMapping("/activiti/findProcessListPage/{startIndex}/{pageSize}")
public Object findProcessListPage(@PathVariable("startIndex") Integer startIndex, @PathVariable("pageSize") Integer pageSize) {
List<ProcessDefinition> processDefinitions = repositoryService
.createProcessDefinitionQuery()
.listPage(startIndex, pageSize);
return Util.activitiResult(processDefinitions);
}
运行结果如下:
[{“pbCategory”:“http://www.activiti.org/testm1574044576798”,“pbDeploymentId”:“d05c66ec-09ad-11ea-a748-4ccc6ac9b5ee”,“pbPersistentState”:{“suspensionState”:1,“category”:“http://www.activiti.org/testm1574044576798”},“pbHasStartFormKey”:false,“pbSuspensionState”:1,“pbName”:“请假审批流程”,“pbDiagramResourceName”:“process/holiday.png”,“pbVersion”:1,“pbKey”:“holiday”,“pbResourceName”:“process/holiday.bpmn”,“pbTenantId”:""}]