Parameter sent from android app by posting always be empty on backend server written in Go language

huangapple go评论106阅读模式
英文:

Parameter sent from android app by posting always be empty on backend server written in Go language

问题

我正在尝试在Android应用程序中使用SendUserIdTokenToBackend()方法发布一个令牌。

private class SendUserIdTokenToBackend extends AsyncTask<String, Void, String> {

    private Exception exception;

    @Override
    protected String doInBackground(String... idToken) {
        Log.d(TAG, "idToken" + idToken);
        try {
            List<Pair> params = new ArrayList<Pair>();
            Pair<String, String> pair = Pair.create("idToken", idToken[0]);
            params.add(pair);
            String paramString = getQuery(params);

            URL url = new URL("http://itforhr.com/webservice/android-sign-in");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");

            conn.setDoOutput(true);
            OutputStream os = conn.getOutputStream();

            BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(os, "UTF-8"));

            writer.write(paramString);

            writer.flush();
            writer.close();
            os.close();

            Log.d(TAG, "getQuery:" + paramString);


            conn.connect();

            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuilder stringBuilder = new StringBuilder();

            String line = null;
            while ((line = reader.readLine()) != null)
            {
                stringBuilder.append(line + "\n");
            }

            return stringBuilder.toString();


        } catch (Exception e) {

            return  "Error sending ID token to backend. " + e.toString();
        }
    }

    @Override
    protected void onPostExecute(String result) {


        mIdTokenTextView.setText(getString(R.string.id_token_fmt, result));
    }
}


private String getQuery(List<Pair> params) throws UnsupportedEncodingException
{
    StringBuilder result = new StringBuilder();
    boolean first = true;

    for (Pair pair : params)
    {
        if (first)
            first = false;
        else
            result.append("&");

        result.append(URLEncoder.encode(pair.first.toString(), "UTF-8"));
        result.append("=");
        result.append(URLEncoder.encode(pair.second.toString(), "UTF-8"));
    }

    return result.toString();
}

Log.d的结果是正确的。我在日志中正确地看到了令牌ID的打印输出。

然而,在服务器端,我无法获取idToken参数。

func init() {
    http.HandleFunc("/webservice/android-sign-in/", androidSignInHandler)
}

func androidSignInHandler(w http.ResponseWriter, r *http.Request) {

    log.Println("(-------- Entering androidSignInHandler --------)")

    ctx := appengine.NewContext(r)

    idToken := r.FormValue("idToken")

    client := urlfetch.Client(ctx)
    _, err := client.Get("https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=" + idToken)

    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    } else {

        w.Header().Set("Content-Type", "text/html")

        fmt.Fprintf(w, "%v and %v", r.PostForm, idToken)

    }

    log.Println("(-------- Exiting androidSignInHandler --------)")

}

fmt打印出"map[] and", idToken为空。我尝试在获取idToken参数之前调用parseForm(),但没有起作用。我在这里卡了两个晚上。请帮帮我。

英文:

I am trying to post a token by using SendUserIdTokenToBackend() method in an android app.

private class SendUserIdTokenToBackend extends AsyncTask&lt;String, Void, String&gt; {
private Exception exception;
@Override
protected String doInBackground(String... idToken) {
Log.d(TAG, &quot;idToken&quot; + idToken);
try {
List&lt;Pair&gt; params = new ArrayList&lt;Pair&gt;();
Pair&lt;String, String&gt; pair = Pair.create(&quot;idToken&quot;, idToken[0]);
params.add(pair);
String paramString = getQuery(params);
URL url = new URL(&quot;http://itforhr.com/webservice/android-sign-in&quot;);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod(&quot;POST&quot;);
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, &quot;UTF-8&quot;));
writer.write(paramString);
writer.flush();
writer.close();
os.close();
Log.d(TAG, &quot;getQuery:&quot; + paramString);
conn.connect();
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder stringBuilder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
{
stringBuilder.append(line + &quot;\n&quot;);
}
return stringBuilder.toString();
} catch (Exception e) {
return  &quot;Error sending ID token to backend. &quot; + e.toString();
}
}
@Override
protected void onPostExecute(String result) {
mIdTokenTextView.setText(getString(R.string.id_token_fmt, result));
}
}
private String getQuery(List&lt;Pair&gt; params) throws UnsupportedEncodingException
{
StringBuilder result = new StringBuilder();
boolean first = true;
for (Pair pair : params)
{
if (first)
first = false;
else
result.append(&quot;&amp;&quot;);
result.append(URLEncoder.encode(pair.first.toString(), &quot;UTF-8&quot;));
result.append(&quot;=&quot;);
result.append(URLEncoder.encode(pair.second.toString(), &quot;UTF-8&quot;));
}
return result.toString();
}

Log.d results are ok. I see token id printed correctly in the log.

However on the server side, I can't get idToken parameter

	func init() {
http.HandleFunc(&quot;/webservice/android-sign-in/&quot;, androidSignInHandler)
}
func androidSignInHandler(w http.ResponseWriter, r *http.Request) {
log.Println(&quot;(-------- Entering androidSignInHandler --------)&quot;)
ctx := appengine.NewContext(r)
idToken := r.FormValue(&quot;idToken&quot;)
client := urlfetch.Client(ctx)
_, err := client.Get(&quot;https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=&quot; + idToken)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
} else {
w.Header().Set(&quot;Content-Type&quot;, &quot;text/html&quot;)
fmt.Fprintf(w, &quot;%v and %v&quot;, r.PostForm, idToken)
}
log.Println(&quot;(-------- Exiting androidSignInHandler --------)&quot;)
}

fmt printed out "map[] and",idToken is empty. I tried calling parseForm() before getting idToken parameter but it didn't work. I have been stuck here for two nights. Please help.

答案1

得分: 1

看起来Go语言中的处理程序应该可以工作,而且Java代码应该发送正确的请求。通常在这种情况下,将部分进行分开测试是有用的。

测试服务器的一种方法是使用curl发送请求到服务器,例如:

curl -v --data "idToken=theToken" http://itforhr.com/webservice/android-sign-in

然后检查是否正常工作。如果正常工作,那么问题可能在客户端;如果不正常工作,那么问题可能在服务器端。

你还可以通过读取请求体而不解析它来进一步检查服务器实际接收到的内容:

b, _ := ioutil.ReadAll(r.Body)
fmt.Print(string(b))

或者在解析后将其转储出来:

r.ParseForm()
fmt.Printf("%#v", r.Form)

希望这能帮助你理解问题出在哪里。

英文:

It looks like the handler in go should work, and also that the java code should send a proper request. Usually in these cases, it is useful to test the parts separately.

One way to test the server is to use curl to send a request to the server, as in

curl -v --data &quot;idToken=theToken&quot; http://itforhr.com/webservice/android-sign-in

and check if that works. If it works, then you know the problem is on the client side, if not, it is probably on the server side.

You could further check what the server is actually receiving by reading the body without parsing it:

b, _ := ioutil.ReadAll(r.Body)
fmt.Print(string(b))

Or dump it after parsing:

r.ParseForm()
fmt.Printf(&quot;%#v&quot;, r.Form)

I hope this should help you understand where the problem is.

huangapple
  • 本文由 发表于 2016年4月26日 00:23:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/36846002.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定