本文介绍了验证时,MongoDB java驱动程序3.0无法捕获异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我超级卡住o_0
尝试通过Java驱动程序进行身份验证时,存在捕获异常的问题。你可能会看到甚至 Throwable 类不起作用

I'm super stuck o_0While trying to authenticate via Java driver, there is an issue with catching exception. As you may see even Throwable class doesn't work

private MongoClient mongoClient;
private MongoDatabase mongoDatabase;



public MongoConnection(String login, String password) {

    try {
        mongoClient = new MongoClient(asList(new ServerAddress("localhost"), new ServerAddress("localhost:27017")),
                singletonList(MongoCredential.createCredential(login,
                        "cookbook",
                        password.toCharArray())));

        this.mongoDatabase = mongoClient.getDatabase("cookbook");
    } catch (Throwable e) {
        System.out.println("exception");
    }
}

仍然没有捕获异常

 INFO: Adding discovered server localhost:27017 to client view of cluster
 Jan 29, 2016 7:46:27 PM com.mongodb.diagnostics.logging.JULLogger log
 INFO: Exception in monitor thread while connecting to server      localhost:27017
 com.mongodb.MongoSecurityException: Exception authenticating       MongoCredential{mechanism=null, userName='asdasdasdasd', source='cookbook',      password=<hidden>, mechanismProperties={}}
at com.mongodb.connection.SaslAuthenticator.authenticate(SaslAuthenticator.java:61)
at com.mongodb.connection.DefaultAuthenticator.authenticate(DefaultAuthenticator.java:32)
at com.mongodb.connection.InternalStreamConnectionInitializer.authenticateAll(InternalStreamConnectionInitializer.java:99)
at com.mongodb.connection.InternalStreamConnectionInitializer.initialize(InternalStreamConnectionInitializer.java:44)
at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:115)
at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:127)
at java.lang.Thread.run(Thread.java:745)
 Caused by: com.mongodb.MongoCommandException: Command failed with error 18:    'Authentication failed.' on server localhost:27017. The full response is { "ok" : 0.0, "code" : 18, "errmsg" : "Authentication failed." }
at com.mongodb.connection.CommandHelper.createCommandFailureException(CommandHelper.java:170)
at com.mongodb.connection.CommandHelper.receiveCommandResult(CommandHelper.java:123)
at com.mongodb.connection.CommandHelper.executeCommand(CommandHelper.java:32)
at com.mongodb.connection.SaslAuthenticator.sendSaslStart(SaslAuthenticator.java:95)
at com.mongodb.connection.SaslAuthenticator.authenticate(SaslAuthenticator.java:45)


推荐答案

最新版本的MongoDB java API在一个单独的守护程序监视器线程中抛出连接异常,这就是为什么你无法捕获它 - 运行器在你的堆栈跟踪中: com.mongodb.connection.DefaultServerMonitor $ ServerMonitorRunnable.run

Recent versions of the MongoDB java API throw connection exceptions in within a separate daemon monitor thread, which is why you cannot catch it- the runner is here in your stack trace: com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run

要监视MongoDB客户端的异常,可以添加一个侦听器,允许您对可能发生的任何异常进行操作,并在需要时随时检查连接状态。您仍然无法捕获这些异常,但至少应该让您的应用程序了解它们。需要注意的一点是,连接建立(或失败)可能需要一些时间,所以如果您只想创建一次性使用连接,我建议实现一个检查连接的睡眠循环OK和失败/异常状态。我使用3.3版本编写了此解决方案():

To monitor the MongoDB client for exceptions, you can add a listener that will allow you to act on any exceptions that may occur and check the connection status anytime you need. You still won't be able to catch these exceptions, but your application will at least be made aware of them. One thing to note is it can take some time for the connection to be established (or fail), so if you're just interested in creating a one-time use connection I'd recommend implementing a sleep loop that checks for the connection OK and failed/exception states. I wrote this solution using version 3.3 (https://api.mongodb.com/java/3.3/):

public class MongoStatusListener implements ServerListener {

    private boolean available = false;

    public boolean isAvailable() {
        return available;
    }

    @Override
    public void serverOpening(ServerOpeningEvent event) {}

    @Override
    public void serverClosed(ServerClosedEvent event) {}

    @Override
    public void serverDescriptionChanged(ServerDescriptionChangedEvent event) {

        if (event.getNewDescription().isOk()) {
            available = true;
        } else if (event.getNewDescription().getException() != null) {
            //System.out.println("exception: " + event.getNewDescription().getException().getMessage());
            available = false;
        }
    }
}

public MongoClient getMongoClient(String login, String password) {

    if (mongoClient != null) {
        return mongoClient;
    }
    MongoClientOptions.Builder optionsBuilder = new MongoClientOptions.Builder();
    MongoStatusListener mongoStatusListener = new MongoStatusListener();
    optionsBuilder.addServerListener(mongoStatusListener);

    this.mongoClient = new MongoClient(asList(new ServerAddress("localhost"), new ServerAddress("localhost:27017")),
        singletonList(MongoCredential.createCredential(
        login,
        "cookbook",
        password.toCharArray())
    ), optionsBuilder.build());

    this.mongoDatabase = mongoClient.getDatabase("cookbook");
    return mongoClient;
}

public boolean isAvailable() {
    return mongoStatusListener.isAvailable();
}

这篇关于验证时,MongoDB java驱动程序3.0无法捕获异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 03:20