无法在跨客户端google oauth2.0中交换访问令牌和刷新令牌的授权代码

2023-12-27

我在 Android 应用程序上实现 Google Play 服务登录并将授权代码传递到后端服务器时遇到问题,因此服务器将交换访问令牌和刷新令牌的代码。

首先让我写几行已经尝试过/读过的内容:

在 code.google.com/apis/console 上我创建了一个新项目,有两个客户端(WEB 客户端和 Android 安装客户端) 阅读有关的文章https://developers.google.com/+/mobile/android/sign-in#cross-platform_single_sign_on https://developers.google.com/+/mobile/android/sign-in#cross-platform_single_sign_on and http://android-developers.blogspot.com/2013/01/verifying-back-end-calls-from-android.html http://android-developers.blogspot.com/2013/01/verifying-back-end-calls-from-android.html

这是我的客户端代码,用于检索授权代码和 IdToken:

    package com.google.drive.samples.crossclientoauth2;

    import java.util.Arrays;
    import java.util.List;

    import android.accounts.AccountManager;
import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.widget.EditText;

import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.UserRecoverableAuthException;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;

public class MainActivity extends Activity {

  final private String CLIENT_ID = MY WEB SERVER'S CLIENT ID;
  final private List<String> SCOPES = Arrays.asList(new String[]{
      "https://www.googleapis.com/auth/plus.login",
      "https://www.googleapis.com/auth/drive",
      "https://www.googleapis.com/auth/youtube",
      "https://www.googleapis.com/auth/youtube.readonly"
  });

  // I have modified the above line of code.  

  private GoogleAccountCredential mCredential;

  private EditText mExchangeCodeEditText;
  private EditText mIdTokenEditText;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);
    mExchangeCodeEditText = (EditText) findViewById(R.id.editTextExchangeCode);
    mIdTokenEditText = (EditText) findViewById(R.id.editTextIdToken);

    // initiate a credential object with drive and plus.login scopes
    // cross identity is only available for tokens retrieved with plus.login
    mCredential = GoogleAccountCredential.usingOAuth2(this, null);

    // user needs to select an account, start account picker
    startActivityForResult(
        mCredential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);

  }

  /**
   * Handles the callbacks from result returning
   * account picker and permission requester activities.
   */
  @Override
  protected void onActivityResult(
      final int requestCode, final int resultCode, final Intent data) {
    switch (requestCode) {
    // user has  returned back from the account picker,
    // initiate the rest of the flow with the account he/she has chosen.
    case REQUEST_ACCOUNT_PICKER:
      String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
      if (accountName != null) {
        mCredential.setSelectedAccountName(accountName);
        new RetrieveExchangeCodeAsyncTask().execute();
        new RetrieveJwtAsyncTask().execute();
      }
      break;
    // user has returned back from the permissions screen,
    // if he/she has given enough permissions, retry the the request.
    case REQUEST_AUTHORIZATION:
      if (resultCode == Activity.RESULT_OK) {
        // replay the same operations
        new RetrieveExchangeCodeAsyncTask().execute();
        new RetrieveJwtAsyncTask().execute();
      }
      break;
    }
  }

  /**
   * Retrieves the exchange code to be sent to the
   * server-side component of the app.
   */

  public class RetrieveExchangeCodeAsyncTask
      extends AsyncTask<Void, Boolean, String> {


    @Override
    protected String doInBackground(Void... params) {
      String scope = String.format("oauth2:server:client_id:%s:api_scope:%s",
          CLIENT_ID, TextUtils.join(" ", SCOPES));
      try {
        return GoogleAuthUtil.getToken(
            MainActivity.this, mCredential.getSelectedAccountName(), scope);
      } catch (UserRecoverableAuthException e) {
        startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
      } catch (Exception e) {
        e.printStackTrace(); // TODO: handle the exception
      }
      return null;
    }

    @Override
    protected void onPostExecute(String code) {
      // exchange code with server-side to retrieve an additional
      // access token on the server-side.
        Log.v("first One ","code 1 is: "+ code);
      mExchangeCodeEditText.setText(code);
    }
  }

  /**
   * Retrieves a JWT to identify the user without the
   * regular client-side authorization flow. The jwt payload needs to be
   * sent to the server-side component.
   */
  public class RetrieveJwtAsyncTask
      extends AsyncTask<Void, Boolean, String> {

    @Override
    protected String doInBackground(Void... params) {
      String scope = "audience:server:client_id:" + CLIENT_ID;
      try {
        return GoogleAuthUtil.getToken(
            MainActivity.this, mCredential.getSelectedAccountName(), scope);
      } catch(UserRecoverableAuthIOException e) {
        startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
      } catch (Exception e) {
        e.printStackTrace(); // TODO: handle the exception
      }
      return null;
    }

    @Override
    protected void onPostExecute(String idToken) {
      // exchange encrypted idToken with server-side to identify the user
        Log.v("Second One","2222"+ idToken);
      mIdTokenEditText.setText(idToken);
    }
  }

  private static final int REQUEST_ACCOUNT_PICKER = 100;
  private static final int REQUEST_AUTHORIZATION = 200;

}

上面的代码给了我两个代码: 1.由 RetrieveExchangeCodeAsyncTask 返回的一个 - 命名代码。 2.第二个由 RetrieveJwtAsyncTask 类返回,名为 IdToken。

现在,首先我很困惑我需要将上面的哪一个发送到我的网络服务器以进行交换。 我尝试使用第一个(以“4/....”开头的)在我的服务器端进行交换,但出现空指针异常。 另请指定我需要使用的重定向 URI。

这是我的服务器端交换代码:

package com.myAuthSample.tial;

import java.io.IOException;

import com.myAuthSample.tial.MyClass.CodeExchangeException;
import com.myAuthSample.tial.MyClass.NoRefreshTokenException;

public class MyMainDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
          try {
            MyClass.getCredentials("4/...something...", "state");  //passed the retrieved authorization code
        } catch (CodeExchangeException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoRefreshTokenException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}


public class MyClass {


    // Path to client_secrets.json which should contain a JSON document such as:
      //   {
      //     "web": {
      //       "client_id": "[[YOUR_CLIENT_ID]]",
      //       "client_secret": "[[YOUR_CLIENT_SECRET]]",
      //       "auth_uri": "https://accounts.google.com/o/oauth2/auth",
      //       "token_uri": "https://accounts.google.com/o/oauth2/token"
      //     }
      //   }
      private static final String CLIENTSECRETS_LOCATION = "/client_secrets_2.json";// client secrets of my android client

      // private static final String REDIRECT_URI = "<YOUR_REGISTERED_REDIRECT_URI>";

      private static String REDIRECT_URI ="";



      private static final List<String> SCOPES = Arrays.asList(
              "https://www.googleapis.com/auth/plus.login",
              "https://www.googleapis.com/auth/youtube");

      private static GoogleAuthorizationCodeFlow flow = null;

      /**
       * Exception thrown when an error occurred while retrieving credentials.
       */
      public static class GetCredentialsException extends Exception {

        protected String authorizationUrl;

        /**
         * Construct a GetCredentialsException.
         *
         * @param authorizationUrl The authorization URL to redirect the user to.
         */
        public GetCredentialsException(String authorizationUrl) {
          this.authorizationUrl = authorizationUrl;
        }

        /**
         * Set the authorization URL.
         */
        public void setAuthorizationUrl(String authorizationUrl) {
          this.authorizationUrl = authorizationUrl;
        }

        /**
         * @return the authorizationUrl
         */
        public String getAuthorizationUrl() {
          return authorizationUrl;
        }
      }

      /**
       * Exception thrown when a code exchange has failed.
       */
      public static class CodeExchangeException extends GetCredentialsException {

        /**
         * Construct a CodeExchangeException.
         *
         * @param authorizationUrl The authorization URL to redirect the user to.
         */
        public CodeExchangeException(String authorizationUrl) {
          super(authorizationUrl);
        }

      }

      /**
       * Exception thrown when no refresh token has been found.
       */
      public static class NoRefreshTokenException extends GetCredentialsException {

        /**
         * Construct a NoRefreshTokenException.
         *
         * @param authorizationUrl The authorization URL to redirect the user to.
         */
        public NoRefreshTokenException(String authorizationUrl) {
          super(authorizationUrl);
        }

      }

      /**
       * Exception thrown when no user ID could be retrieved.
       */
      private static class NoUserIdException extends Exception {
      }

      /**
       * Retrieved stored credentials for the provided user ID.
       *
       * @param userId User's ID.
       * @return Stored Credential if found, {@code null} otherwise.
       */
      static Credential getStoredCredentials(String userId) {
        // TODO: Implement this method to work with your database. Instantiate a new
        // Credential instance with stored accessToken and refreshToken.
        throw new UnsupportedOperationException();
      }

      /**
       * Store OAuth 2.0 credentials in the application's database.
       *
       * @param userId User's ID.
       * @param credentials The OAuth 2.0 credentials to store.
       */
      static void storeCredentials(String userId, Credential credentials) {
        // TODO: Implement this method to work with your database.
        // Store the credentials.getAccessToken() and credentials.getRefreshToken()
        // string values in your database.
          System.out.println("credentials are :    " + credentials.toString());
        throw new UnsupportedOperationException();
      }

      /**
       * Build an authorization flow and store it as a static class attribute.
       *
       * @return GoogleAuthorizationCodeFlow instance.
       * @throws IOException Unable to load client_secrets.json.
       */
      static GoogleAuthorizationCodeFlow getFlow() throws IOException {
        if (flow == null) {
          HttpTransport httpTransport = new NetHttpTransport();
          JacksonFactory jsonFactory = new JacksonFactory();    //...this was the original line....
        //  JsonFactory jsonFactory = new JacksonFactory();

         //my code....        
          Reader clientSecretReader = new InputStreamReader(MyClass.class.getResourceAsStream(CLIENTSECRETS_LOCATION));

          GoogleClientSecrets clientSecrets =
                  GoogleClientSecrets.load(jsonFactory,clientSecretReader);

          REDIRECT_URI =clientSecrets.getDetails().getRedirectUris().get(0);
          // my code ends...

    /*      GoogleClientSecrets clientSecrets =
              GoogleClientSecrets.load(jsonFactory,
                  MyClass.class.getResourceAsStream(CLIENTSECRETS_LOCATION));
      */
          flow =
              new GoogleAuthorizationCodeFlow.Builder(httpTransport, jsonFactory, clientSecrets, SCOPES)
                  .setAccessType("offline").setApprovalPrompt("force").build();
        }
        return flow;
      }

      /**
       * Exchange an authorization code for OAuth 2.0 credentials.
       *
       * @param authorizationCode Authorization code to exchange for OAuth 2.0
       *        credentials.
       * @return OAuth 2.0 credentials.
       * @throws CodeExchangeException An error occurred.
       */
      static Credential exchangeCode(String authorizationCode)
          throws CodeExchangeException {
        try {
          GoogleAuthorizationCodeFlow flow = getFlow();
          GoogleTokenResponse response =
              flow.newTokenRequest(authorizationCode).setRedirectUri(REDIRECT_URI).execute();
          return flow.createAndStoreCredential(response, null);
        } catch (IOException e) {
          System.err.println("An error occurred: " + e);
          throw new CodeExchangeException(null);
        }
      }

      /**
       * Send a request to the UserInfo API to retrieve the user's information.
       *
       * @param credentials OAuth 2.0 credentials to authorize the request.
       * @return User's information.
       * @throws NoUserIdException An error occurred.
       */
      static Userinfo getUserInfo(Credential credentials)
          throws NoUserIdException {
        Oauth2 userInfoService =
            new Oauth2.Builder(new NetHttpTransport(), new JacksonFactory(), credentials).build();
        Userinfo userInfo = null;
        try {
          userInfo = userInfoService.userinfo().get().execute();
        } catch (IOException e) {
          System.err.println("An error occurred: " + e);
        }
        if (userInfo != null && userInfo.getId() != null) {
          return userInfo;
        } else {
          throw new NoUserIdException();
        }
      }

      /**
       * Retrieve the authorization URL.
       *
       * @param emailAddress User's e-mail address.
       * @param state State for the authorization URL.
       * @return Authorization URL to redirect the user to.
       * @throws IOException Unable to load client_secrets.json.
       */
      public static String getAuthorizationUrl(String emailAddress, String state) throws IOException {
        GoogleAuthorizationCodeRequestUrl urlBuilder =
            getFlow().newAuthorizationUrl().setRedirectUri(REDIRECT_URI).setState(state);
        urlBuilder.set("user_id", emailAddress);
        return urlBuilder.build();
      }

      /**
       * Retrieve credentials using the provided authorization code.
       *
       * This function exchanges the authorization code for an access token and
       * queries the UserInfo API to retrieve the user's e-mail address. If a
       * refresh token has been retrieved along with an access token, it is stored
       * in the application database using the user's e-mail address as key. If no
       * refresh token has been retrieved, the function checks in the application
       * database for one and returns it if found or throws a NoRefreshTokenException
       * with the authorization URL to redirect the user to.
       *
       * @param authorizationCode Authorization code to use to retrieve an access
       *        token.
       * @param state State to set to the authorization URL in case of error.
       * @return OAuth 2.0 credentials instance containing an access and refresh
       *         token.
       * @throws NoRefreshTokenException No refresh token could be retrieved from
       *         the available sources.
       * @throws IOException Unable to load client_secrets.json.
       */
      public static Credential getCredentials(String authorizationCode, String state)
          throws CodeExchangeException, NoRefreshTokenException, IOException {
        String emailAddress = "";
        try {
          Credential credentials = exchangeCode(authorizationCode);
          Userinfo userInfo = getUserInfo(credentials);
          String userId = userInfo.getId();
          emailAddress = userInfo.getEmail();
          if (credentials.getRefreshToken() != null) {
            storeCredentials(userId, credentials);
            return credentials;
          } else {
            credentials = getStoredCredentials(userId);
            if (credentials != null && credentials.getRefreshToken() != null) {
              return credentials;
            }
          }
        } catch (CodeExchangeException e) {
          e.printStackTrace();
          // Drive apps should try to retrieve the user and credentials for the current
          // session.
          // If none is available, redirect the user to the authorization URL.
          e.setAuthorizationUrl(getAuthorizationUrl(emailAddress, state));
          throw e;
        } catch (NoUserIdException e) {
          e.printStackTrace();
        }
        // No refresh token has been retrieved.
        String authorizationUrl = getAuthorizationUrl(emailAddress, state);
        throw new NoRefreshTokenException(authorizationUrl);
      }


}

另外,我是否在我的服务器端代码(在 MyClass 中)中传递了正确的 client_secret.json 文件——这是 Android 客户端的。

请帮忙!!! 提前致谢。


从这里使用:

import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson.JacksonFactory;


private final val TRANSPORT: HttpTransport = new NetHttpTransport()
    private final val JSON_FACTORY: JacksonFactory = new JacksonFactory()


GoogleTokenResponse tokenResponse = new GoogleAuthorizationCodeTokenRequest(TRANSPORT, JSON_FACTORY,
                CLIENT_ID, CLIENT_SECRET, code, "postmessage").execute();

GoogleIdToken idToken = tokenResponse.parseIdToken();
String gplusId = idToken.getPayload().getSubject();

您必须将 client_id、client_secret 和 code 的值替换为上述相关变量。

更多信息位于以下链接中:https://github.com/googleplus/gplus-quickstart-java/blob/master/src/com/google/plus/samples/quickstart/Signin.java https://github.com/googleplus/gplus-quickstart-java/blob/master/src/com/google/plus/samples/quickstart/Signin.java

您还可以从此链接获取 Google API 库:

http://repo1.maven.org/maven2/com/google/ http://repo1.maven.org/maven2/com/google/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

无法在跨客户端google oauth2.0中交换访问令牌和刷新令牌的授权代码 的相关文章

  • 如何为 Android 创建我们自己的 PDF 查看器?

    我想构建一个可在我的 Android 应用程序中使用的 PDF 阅读器 查看器 但我无法使用 Google 文档来阅读我的内容 我无法使用我的设备中已安装的任何 PDF 阅读器 它应该位于我的应用程序内 并且不会通过互联网公开我的安全内容
  • Android:java.lang.OutOfMemoryError:

    我在 Android 上开发了一个使用大量图像的应用程序 可绘制文件夹中有很多图像 比如说超过 100 张 我正在开发图像动画应用程序 我使用 imageview 来显示 GIF 图像 我使用了将 gif 图像分割成多个 PNG 格式图像的
  • 在android Gridview中合并行和列

    我正在android中做一个图像查看页面 我需要在某些地方合并行 在某些地方合并列 我们可以在gridview中做到这一点吗 如果我们选择任何合并图像 则应选择整个图像视图 请任何人告诉我一个建议 提前致谢 Try 非对称网格视图 http
  • 如何检查 Android 设备是否在线

    我的服务器不断检查我的 Android 应用程序是否在线 请问我可以在我的android应用程序上执行哪些操作 创建一个名为 isNetworkAvailable 的帮助器方法 该方法将根据网络是否可用返回 true 或 false 它看起
  • 为什么我的地图视图上的叠加层没有显示?

    我按照 google hellomapview 教程中的说明进行操作 我得到了一个工作地图视图等 但是添加到地图中的两个项目没有显示 它们似乎在某个地方 因为点击指定位置会显示添加到项目中的消息 Edit 这是我的源代码 应该和google
  • Android 和 Honeycomb - 如何使用 SDK 13 拥有菜单图标而不需要“操作栏”

    我想最大限度地利用 Honeycomb 应用程序的屏幕 由于屏幕底部已经被 始终打开 的项目所困 我想在该空间中添加一个菜单按钮 而不是牺牲更多的屏幕空间 在顶部放置一个 操作栏 我怎样才能做到这一点without降级到 API 10 或更
  • Android 上的 SQLite JDBC 驱动程序

    我正在尝试使用xerial sqlite jdbc在 Android 中管理我的数据库没有成功 我得到了java lang NoClassDefFoundError org sqlite SQLiteConnection异常 我已经导入了这
  • 如何去掉android状态栏的电池图标?

    我通过去掉背景图像来删除 Android 中显示网络 电池和时间信息的状态栏 但图标仍然存在 我也想知道如何删除电池图标 不是用于应用程序 而是用于框架开发 提前致谢 你试过打电话吗 getWindow setFlags WindowMan
  • 绘制平滑曲线

    我想创建更平滑的曲线 而不仅仅是线角 这是我现在画的图 这是我的代码 case FREEHAND float pts float ptk ptk new float 2 imageMatrix invert inv if mCurrentS
  • 作为 ViewPager 的一部分更新 ListFragment 中的数据

    我在 Android 中使用 v4 兼容性 ViewPager 我的 FragmentActivity 有一堆数据 这些数据将以不同的方式显示在我的 ViewPager 的不同页面上 到目前为止 我只有同一个 ListFragment 的
  • 如何告诉 OkHttpClient 忽略缓存并强制从服务器刷新?

    在我的 Android 应用程序中 我将 Retrofit 与 OkHttpClient 结合使用 并启用缓存来访问某些 API 我们的一些 API 有时会返回空数据 我们在应用程序中提供了一个 刷新 按钮 供客户端从特定 API 重新加载
  • Google Wallet for Digital Goods API 与 Google Play 应用内结算

    想知道 Google 电子钱包结算 API 和 Google Play 应用内结算之间有什么区别 与 Google 电子钱包结算 API 相比 使用 GooglePlay 应用内购买结算服务有何优势 我看到 Wallet API 也支持 A
  • Android 导航组件 - 从“任何地方”/基本片段导航?

    我正在开发一个应用程序 它有一个奇怪的花招 可以在设备旋转时打开特定的片段 在实现 android 的导航组件之前 所需要的只是对当前活动的引用 并且可以在特定时刻向用户显示的任何内容之上执行手动片段事务 但是在转移到导航组件之后 我发现很
  • 通过 Google 帐户从 Google Play 安装的应用程序列表

    以下是我的问题 是否可以通过使用任何 api 以编程方式通过 Google Play 获取用户已安装的应用程序列表 请注意 我并不是询问设备中当前安装的应用程序列表 而是询问在某个时刻已安装的应用程序列表 我需要解决上述问题 因为我正在考虑
  • Firebase:用户注册后如何进行电话号码验证?

    所以我知道我可以使用电子邮件验证或电话号码验证 但我想做的是在用户注册或登录后进行电话号码验证 如何连接这两种身份验证方法 最后 Firebase中是否有一个函数可以检查用户是否通过电话号码验证 谢谢 即使用户已通过身份验证 您仍然可以使用
  • 具有隐式授权的 OAuth 应用程序中的客户端模拟

    来自 OAuth 草案 隐式section https datatracker ietf org doc html draft ietf oauth v2 31 section 1 3 2 在隐式授权流程期间发出访问令牌时 授权服务器不对客
  • 如何在android中将文本放在单选按钮的左侧

    我想将单选按钮的文本放在左侧而不是右侧 我找到了这个解决方案
  • 从 Dropbox 下载文件并将其保存到 SDCARD

    现在我真的很沮丧 我想从 Dropbox 下载一个文件并将该文件保存到 SD 卡中 我得到的代码为 private boolean downloadDropboxFile String dbPath File localFile throw
  • PhoneGap Build Android 不显示闪屏

    这是我的 config xml 中与启动屏幕相关的代码
  • 连接到具有相同 SSID 的最强接入点(信号最强的接入点)

    我正在编写一个程序来始终连接到最强的接入点 我的意思是信号最强的接入点 首先 我扫描所有可用的 WiFi 网络 然后限制它们仅查看具有相同 SSID 的网络 这样我就可以看到一个网络的所有AP 当我连接到该网络时 它没有连接到最强的信号 但

随机推荐

  • “允许从任何地方访问”MongoDB Atlas

    我正在构建一个网站 并使用 MongoDB Atlas 作为我的数据库 在 MongoDB 网络访问部分中 我必须指定要连接的 IP 地址才能建立数据库连接 并且由于我使用云服务来运行我的服务器 所以我必须选择 允许从任何地方访问 选项 将
  • 单元测试反应动作 - browserHistory 未定义

    我为我的行为编写测试 使用 browserHistory from react router 当我运行测试时 由于未知原因 导入的 browserHistory 未定义 因此 测试会抛出错误 无法读取未定义的属性 push 我不知道为什么
  • 网站或应用程序上的数据泄露暴露了您的密码。 Chrome 建议更改您的密码 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我有一个 login从 mongoose 获取特定用户配置文件的路由 我有 select password 工作排除密码 但我仍然从谷歌浏
  • 想要从其他活动更改 TextView 的文本吗?

    我目前正在设计一个电子书阅读器应用程序作为我的项目 我在更改文本时遇到问题textview来自其他活动 我的项目内容 活动1包含两个按钮 当button1单击 某些文本 应该出现 何时button2单击 其他文本 应该出现在文本视图1这是在
  • HTML5 Canvas 无法在外部 JavaScript 文件中工作

    我已经用 JavaScript 编写了这段代码 当我将其包含在我的 index html 页面上时 它工作得非常好
  • 什么是“覆盖条件”?

    的来源Statemtl 中的变压器 http hackage haskell org packages archive mtl 2 1 2 doc html src Control Monad State Class html states
  • Sqlite 中的多线程

    我正在使用 System data sqlite 连接到 Sqlite 数据库 按照SQLite 文档 http www sqlite org threadsafe html 用户可以通过使用启用多线程SQLITE OPEN NOMUTEX
  • tkinter treeview单击所选项目的事件[重复]

    这个问题在这里已经有答案了 在我的小型 tkinter 应用程序中 我的树具有如下图所示的结构 我只想在用户双击树的最后一个项目 Amount1 或 Amount2 等 时才创建单击事件 不幸的是 当我单击树的任何项目时 单击事件会起作用
  • Node-gyp 和自定义依赖/库/头安装路径

    我有一个构建环境 其中我的库 和标头 安装到自定义位置 从 npm 安装软件包时 使用 node gyp 的模块会失败 因为它们找不到我已安装的库 或标头 如何让 node gyp 知道我的自定义安装位置 linux 如果你设置CXXFLA
  • 无法连接到服务器 127.0.0.1 shell/mongo.js

    当我在 ubuntu 中设置 mongodb 时 我尝试 mongo 它显示此错误 couldn t connect to server 127 0 0 1 shell mongo js 那么我能做什么 thanks 手动删除锁定文件 su
  • 将对象传递给 PowerShell 函数

    我试图将 SQL 适配器对象传递给 PowerShell 函数 但收到此错误 executeQueryAndFillTable 无法处理参数转换 参数 da 无法转换类型的 System Object 值 System Object 以键入
  • 如何使用Vue登录后渲染标题和侧边栏

    我有一个 Vue js 应用程序 目前我使用不同的页面渲染它 我遇到了一个问题 当我第一次登录时 它只会渲染单个主要组件 即根据 vue 路由器的页面 我正在寻找一种方法来运行我的登录功能 然后转到 dashboard但我希望它重新渲染我的
  • 选择最高薪水

    假设工资表 name lowhours highhours wage Default 0 0 40 0 100 Default 40 0 50 0 150 Default 50 0 70 5 154 Default 70 5 100 0 2
  • 从 Perforce 恢复已删除的文件

    上个月我从 Perforce 中删除了一个文件 有办法从 P4 中检索它吗 如果是这样 我可以使用什么命令 注意 我不是 p4 的管理员 我不希望该文件返回到 P4 但我只想将其保留在我的本地工作区中 另外 我不知道上个月删除它的确切时间范
  • 如何获得unix中每列的最大长度?

    假设 我有一个这样的源文件 ID NAME ADDRESS 1 ABC PUNE 2 XYZA MUMBAI 12 VB NAGPUR 我想获取每列的最大长度 不包括标题名称 输出应该是这样的 2 4 6 我已经尝试过这样的命令 尾部 2
  • 相对于batch的查询成本是100%

    我不确定如何解释这一点 但我在 sql server 2005 中运行的所有查询都有 100 的 查询成本 相对于批处理 有什么办法可以降低成本吗 如果您的批次 您在给定调用中执行的操作 有一个查询 那么relative对于该批次 该查询占
  • 如何在android中获取用户定义的“设备名称”?

    我正在尝试获取在设置中设置的用户定义的设备名称 我已经尝试了几种选择 但到目前为止还没有任何结果 如果它有帮助或有害 我需要在广播接收器中使用它 Thanks 这让我得到了我所需要的 http cmanios wordpress com 2
  • 如何从 Google Apps 脚本上的“doPost”请求获取原始 URL

    我一直在尝试识别对 Google Apps 脚本发出的 POST 请求的来源doPost 内容服务 function doPost request Something like this var originURL request head
  • 如何为列表框中的每个项目设置不同的工具提示文本?

    我有一个与对象集合进行数据绑定的列表框 列表框被配置为显示每个对象的标识符属性 我想显示一个工具提示 其中包含悬停在 列表框中的项目的特定信息 而不是整个列表框的一个工具提示 我正在 WinForms 中工作 感谢一些有用的博客文章 整理了
  • 无法在跨客户端google oauth2.0中交换访问令牌和刷新令牌的授权代码

    我在 Android 应用程序上实现 Google Play 服务登录并将授权代码传递到后端服务器时遇到问题 因此服务器将交换访问令牌和刷新令牌的代码 首先让我写几行已经尝试过 读过的内容 在 code google com apis co