MobileFirst 8:存储数据时遇到意外错误

时间:2017-11-13 15:42:35

标签: ibm-mobilefirst mobilefirst-adapters

我们正在使用UserAuthenticationSecurityCheck来验证用户身份。

如果验证成功,MFP服务器将存储用户属性。

public class AuthSecurityCheck extends UserAuthenticationSecurityCheck {

    static Logger logger = Logger.getLogger(AuthSecurityCheck.class.getName());

    private String userId, displayName;
    private JSONObject attrObject;

    private String errorMessage;

    @Override
    protected AuthenticatedUser createUser() {
        Map<String, Object> userAttrsMap = new HashMap<String, Object>();
        userAttrsMap.put("attributes",attrObject); 
        return new AuthenticatedUser(userId, displayName, this.getName(), userAttrsMap);
    }
...
}

但是如果我们存储更大的数据(当userAttrsMap足够大时),我们将得到500错误。

  

errorMsg:存储数据时遇到意外错误

错误如下所示:

enter image description here

完整资料来源于Github:https://github.com/DannyYang/PMR_CreateUserStoredLargeData

MFP版本:

  • cordova-plugin-mfp 8.0.2017102115
  • MFP DevelopKit:8.0.0.00-20171024-064640

1 个答案:

答案 0 :(得分:3)

由于您在AuthenticatedUser对象中保存的数据大小以及Securitycheck的状态,会出现此问题。

MFP运行时将安全检查的状态以及所有属性保存到属性存储中。这涉及序列化安全检查状态并将其持久保存到DB。对于大对象(您拥有的自定义映射),此持久性操作将失败并以事务回滚结束。发生这种情况是因为您尝试保留的数据太大而且超出了分配的大小。

SecurityCheck的设计考虑因素是将其用于安全检查(验证)和创建身份对象。在安全检查实现中,您有以下内容:

//Here the large data is assigned to the variable.
attrObject = JSONObject.parse(largeJSONString);

//This data is set into the AuthenticatedUser object.
Map<String, Object> userAttrsMap = new HashMap<String, Object>();
userAttrsMap.put("attributes",attrObject);
return new AuthenticatedUser(userId, displayName, this.getName(), userAttrsMap);

在这种情况下,这些大数据将成为Securitycheck本身的一部分,并将被序列化并尝试持久存储到属性存储中。当此数据不适合列时,将回滚事务并将错误条件传播给最终用户。因此,您看到错误消息 - “存储数据时发生意外错误”。启用详细跟踪将在服务器跟踪日志中指出问题的实际原因。

无论哪种方式,生产系统都不推荐这种方法,因为:

a)客户端到达服务器的每个请求都会经过安全性内省,这将涉及服务器加载,检查和更新安全检查的状态。在承受重负荷(生产)的系统上,这可能并且将具有性能成本。该过程涉及序列化数据并在以后对其进行反序列化。在分布式拓扑(群集或群集)中,请求可能最终在任何节点中,并且这些节点必须加载并稍后将安全检查的状态保存到存储。所有这些都会影响您系统的性能。

b)在成功验证结束时,AuthenticatedUser对象将传播到客户端应用程序,指示登录流程的完成。即使SecurityCheck状态成功地存储在属性存储(具有大数据)中,通过网络传输大的有效负载只是为了表明成功登录将会适得其反。对于最终用户,它可能看起来好像没有发生任何事情,因为他们输入了凭证,而表示成功的数据仍然被下载。

c)在重负载下,服务器将从上面的a)和b)紧张。

您应该考虑在authenticateduser对象中减少传播到客户端的数据。在AuthenticatedUser对象中保持最小数据。相反,您应该将大量数据卸载到资源适配器,这可以在成功登录后访问。