1

JDOを使用してデータストアを管理するGAE/Jアプリを開発しています。データなどと対話するための多数のエンドポイントを提供します。また、これらのエンドポイント用のJavascriptクライアントも開発しています。

状況:

まずToken getSessionToken(User usr)、セッション トークンを生成してユーザーに割り当て、ユーザー トークンとセッション トークンの両方をデータストアに格納するエンドポイント メソッドがあります。

次にInfo getInfo(Token token)、セッション トークンを受け取り、そのセッション トークンがユーザーに対応しているかどうかを確認し、対応している場合は情報を返す別のエンドポイント メソッドがあります。

問題

Javascript クライアントから最初のメソッドを呼び出すと、すべて問題ありません。次に、以前に取得したセッション トークンを使用して 2 番目のメソッドを呼び出すと、セッション トークンがどのユーザーにも対応していないというエラーが表示されます...

確認したところ、新しいセッション トークンがまだ保持されていないためにこのエラーが発生することがわかりました。

質問

私の現在の解決策は、Javascript クライアントが 2 番目のメソッドを 1 回呼び出すようにすることです。エラーが発生した場合は、しばらく待ってからもう一度呼び出します...もっと良い解決策はありますか?


編集:

これは、最初のメソッド呼び出しに含まれるコードで、なぜそんなに時間がかかるのかを理解するためのものです...

終点:

@ApiMethod(
    name = "getSessionToken",
    path = "get_session_token",
    httpMethod = HttpMethod.GET
)
public SessionToken getSessionToken (@Named("email") String email, @Named("password") String password) 
        throws InternalServerErrorException {       
    SessionToken sessionToken = new UsersController().getSessionToken(email, password);
    return sessionToken;
}

コントロール:

public SessionToken getSessionToken(String email, String password) throws InternalServerErrorException {        
    SessionToken sessionToken = null;
    
    PersistenceManager pm = PMF.get().getPersistenceManager();      
    Transaction txn = DatastoreServiceFactory.getDatastoreService().beginTransaction();
    try {
        DAO dao = new DAO(pm);
        
        User user = dao.getUserByLogin(email, password);
        
        dao.deleteSessionToken(user.getSessionToken());
        sessionToken = SessionTokenManager.generateToken(user.getEmail(), user.getPassword());
        user.setSessionToken(sessionToken);
        
        user = dao.insertUser(user);    
    
        txn.commit();   
    
    } catch (Exception e) {
        throw new InternalServerErrorException();
    } finally {
        if (txn.isActive()) {
            txn.rollback();
        }
        pm.close();
    }       
    return sessionToken;
}

ダオ:

public User getUserByLogin(String email, String password) throws InternalServerErrorException {
    User user = null;
    Query query = null;
    try {
        query = this.pm.newQuery(User.class);
        query.setFilter("email == emailParam && password == passwordParam");
        query.declareParameters("String emailParam, String passwordParam");     
        List<User> results = (List<User>) query.execute(email, password);
        user = results.get(0);
    } catch (Exception e) {
        e.printStackTrace();
        throw new InternalServerErrorException("Error in DAO.getUserByLogin()");
    } finally {
        query.closeAll();
    }
    return user;
}

/////

public void deleteSessionToken(SessionToken sessionToken) throws InternalServerErrorException {
    try {
        this.pm.deletePersistent(sessionToken);
    } catch (Exception e) {
        e.printStackTrace();
        throw new InternalServerErrorException("Error in DAO.deleteSessionToken()");
    }
}

/////

public User insertUser(User user) throws InternalServerErrorException {     
    try {
        this.pm.makePersistent(user);
    } catch (Exception e) {
        e.printStackTrace();
        throw new InternalServerErrorException("Error in DAO.insertUser()", e);
    }                
    return user;
}

モデル:

@PersistenceCapable
public class User { 
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;    
    @Persistent
    private String name;
    @Persistent
    private String email;
    @Persistent
    private String password;    
    @Persistent
    private Folder rootFolder;  
    @Persistent
    private SessionToken sessionToken;  
    @Persistent(defaultFetchGroup = "true")
    private AccountContainer accountContainer;
    //getters & setters
}

/////

@PersistenceCapable
public class SessionToken {         
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;
    @Persistent
    private String token;
    @Persistent
    private Long created;
    @Persistent
    private String sha1;
    //getters & setters
}
4

1 に答える 1