Activiti 流程查询出的结果封装为 JSON 时出现的异常

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”:""}]


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值