在Android中使用HTTP客户端进行JSON的POST请求时出现问题。

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

Problem with POST requests in JSON using HTTP Client in Android

问题

I have a button in html file when it is pressed it call the postData function in MainActivity.java

<script>
document.getElementById("login-button").addEventListener("click", function(event) {
    event.preventDefault();

    var username = document.getElementById("username").value;
    var password = document.getElementById("password").value;
    var role = document.getElementById("role").value;
    var company = document.getElementById("company").value;

    Android.postData(username, password, role, company);
});
</script>

MainActivity.java:

public class MainActivity extends AppCompatActivity {
    private String username;
    private String password;
    private String role;
    private String company;
    private Retrofit retrofit;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        WebView webView = findViewById(R.id.webview);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.addJavascriptInterface(new WebAppInterface(), "Android");
        webView.loadUrl("file:///android_asset/index.html");
    }

    public class WebAppInterface {
        @JavascriptInterface
        public void postData(String username, String password, String role, String company) {
            try {
                //Test the data is fit with html input
                System.out.println("Username: " + username);
                System.out.println("Password: " + password);
                System.out.println("Role: " + role);
                System.out.println("Company: " + company);

                JSONObject jsonObject = new JSONObject();
                jsonObject.put("username", username);
                jsonObject.put("password", password);
                jsonObject.put("role", role);
                jsonObject.put("company", company);
                String jsonString = jsonObject.toString();
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P) {
                    new post().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, jsonString);
                } else {
                    new post().execute(jsonString);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    class post extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... strings) {
            try {
                // on below line creating a url to post the data.
                URL url = new URL("http://10.0.2.2:3000/login");

                // on below line opening the connection.
                HttpURLConnection client = (HttpURLConnection) url.openConnection();

                // on below line setting method as post.
                client.setRequestMethod("POST");

                // on below line setting content type and accept type.
                client.setRequestProperty("Content-Type", "application/json");
                client.setRequestProperty("Accept", "application/json");

                // on below line setting client.
                client.setDoOutput(true);

                // on below line we are creating an output stream and posting the data.
                try (OutputStream os = client.getOutputStream()) {
                    byte[] input = strings[0].getBytes("utf-8");
                    os.write(input, 0, input.length);
                }

                // on below line creating and initializing buffer reader.
                try (BufferedReader br = new BufferedReader(
                        new InputStreamReader(client.getInputStream(), "utf-8"))) {

                    // on below line creating a string builder.
                    StringBuilder response = new StringBuilder();

                    // on below line creating a variable for response line.
                    String responseLine = null;

                    // on below line writing the response
                    while ((responseLine = br.readLine()) != null) {
                        response.append(responseLine.trim());
                    }
                }

            } catch (Exception e) {
                // on below line handling the exception.
                e.printStackTrace();
            }
            return null;
        }
    }
}

After submit button Logcat show:

2023-06-15 05:21:08.684   505-505   AutofillManager         com.example.myapplication            V  requestHideFillUi(null): anchor = null
2023-06-15 05:21:08.763   505-2113  System.out              com.example.myapplication            I  Username: 1
2023-06-15 05:21:08.763   505-2113  System.out              com.example.myapplication            I  Password: 1
2023-06-15 05:21:08.763   505-2113  System.out              com.example.myapplication            I  Role: Company
2023-06-15 05:21:08.763   505-2113  System.out              com.example.myapplication            I  Company: Company 1

This is my server.js:

app.post('/login', (req, res) => {
    const { username, password, role, company } = req.body;
    // Perform your login logic here
    // For demonstration purposes, let's assume the username is "admin" and password is "password"
    console.log(username, password, role, company);

    if (role === 'Company' && company === 'Company 2' &&
        username === 'admin2' && password === 'password') {

        res.json({ success: true, message: 'org2CreateUser.html' });
    }
    if (role === 'Company' && company === 'Company 1' &&
        username === 'admin1' && password === 'password') {

        res.json({ success: true, message: 'org1CreateUser.html' });
    }
    if (role === 'Employer') {
        credentials.forEach(element => {
            if(element.username === username && element.password == password) {
                res.json({ success: true, message: 'upload.html' });
                return;
            }
        });
        res.status(401).json({ success: false, message: 'Invalid username or password' });
    }
});
app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

The problem is I don't see the console.log(username, password, role, company); response in the console.log of the server. When I use curl to test the server, it shows normally:

curl -X POST -H "Content-Type: application/json" -d '{
  "username": "admin",
  "password": "password",
  "role": "Company",
  "company": "Company 1"
}' http://localhost:3000/login

I don't know if the JSON is sent to the server or not. I use Android Studio in Ubuntu VMware and connect my phone with USB debug.

英文:

I have a button in html file when it is pressed it call the postData function in MainActivity.java

&lt;script&gt;
document.getElementById(&quot;login-button&quot;).addEventListener(&quot;click&quot;, function(event) {
event.preventDefault();
var username = document.getElementById(&quot;username&quot;).value;
var password = document.getElementById(&quot;password&quot;).value;
var role = document.getElementById(&quot;role&quot;).value;
var company = document.getElementById(&quot;company&quot;).value;
Android.postData(username, password, role, company);
});

</script>

MainActivity.java:

public class MainActivity extends AppCompatActivity {
private String username;
private String password;
private String role;
private String company;
private Retrofit retrofit;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView webView = findViewById(R.id.webview);
webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new WebAppInterface(), &quot;Android&quot;);
webView.loadUrl(&quot;file:///android_asset/index.html&quot;);
}
public class WebAppInterface {
@JavascriptInterface
public void postData(String username, String password, String role, String company) {
try {
//Test the data is fit with html input
System.out.println(&quot;Username: &quot; + username);
System.out.println(&quot;Password: &quot; + password);
System.out.println(&quot;Role: &quot; + role);
System.out.println(&quot;Company: &quot; + company);
JSONObject jsonObject = new JSONObject();
jsonObject.put(&quot;username&quot;, username);
jsonObject.put(&quot;password&quot;, password);
jsonObject.put(&quot;role&quot;, role);
jsonObject.put(&quot;company&quot;, company);
String jsonString = jsonObject.toString();
if (android.os.Build.VERSION.SDK_INT &gt;= android.os.Build.VERSION_CODES.P) {
new post().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, jsonString);
} else {
new post().execute(jsonString);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class post extends AsyncTask&lt;String, Void, String&gt; {
@Override
protected String doInBackground(String... strings) {
try {
// on below line creating a url to post the data.
URL url = new URL(&quot;http://10.0.2.2:3000/login&quot;);
// on below line opening the connection.
HttpURLConnection client = (HttpURLConnection) url.openConnection();
// on below line setting method as post.
client.setRequestMethod(&quot;POST&quot;);
// on below line setting content type and accept type.
client.setRequestProperty(&quot;Content-Type&quot;, &quot;application/json&quot;);
client.setRequestProperty(&quot;Accept&quot;, &quot;application/json&quot;);
// on below line setting client.
client.setDoOutput(true);
// on below line we are creating an output stream and posting the data.
try (OutputStream os = client.getOutputStream()) {
byte[] input = strings[0].getBytes(&quot;utf-8&quot;);
os.write(input, 0, input.length);
}
// on below line creating and initializing buffer reader.
try (BufferedReader br = new BufferedReader(
new InputStreamReader(client.getInputStream(), &quot;utf-8&quot;))) {
// on below line creating a string builder.
StringBuilder response = new StringBuilder();
// on below line creating a variable for response line.
String responseLine = null;
// on below line writing the response
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
}
} catch (Exception e) {
// on below line handling the exception.
e.printStackTrace();
}
return null;
}
}

}

After submit button Logcat show:

2023-06-15 05:21:08.684   505-505   AutofillManager         com.example.myapplication            V  requestHideFillUi(null): anchor = null
2023-06-15 05:21:08.763   505-2113  System.out              com.example.myapplication            I  Username: 1
2023-06-15 05:21:08.763   505-2113  System.out              com.example.myapplication            I  Password: 1
2023-06-15 05:21:08.763   505-2113  System.out              com.example.myapplication            I  Role: Company
2023-06-15 05:21:08.763   505-2113  System.out              com.example.myapplication            I  Company: Company 1

This is my server.js:

app.post(&#39;/login&#39;, (req, res) =&gt; {
const { username, password, role, company } = req.body;
// Perform your login logic here
// For demonstration purposes, let&#39;s assume the username is &quot;admin&quot; and password is &quot;password&quot;
console.log(username, password, role, company);
if (role === &#39;Company&#39; &amp;&amp; company === &#39;Company 2&#39; &amp;&amp;
username === &#39;admin2&#39; &amp;&amp; password === &#39;password&#39;) {
res.json({ success: true, message: &#39;org2CreateUser.html&#39; });
}
if (role === &#39;Company&#39; &amp;&amp; company === &#39;Company 1&#39; &amp;&amp;
username === &#39;admin1&#39; &amp;&amp; password === &#39;password&#39;) {
res.json({ success: true, message: &#39;org1CreateUser.html&#39; });
}
if (role === &#39;Employer&#39;) {
credentials.forEach(element =&gt; {
if(element.username === username &amp;&amp; element.password == password) {
res.json({ success: true, message: &#39;upload.html&#39; });
return;
}
});
res.status(401).json({ success: false, message: &#39;Invalid username or password&#39; });
}
});
app.listen(3000, () =&gt; {
console.log(&#39;Server is running on port 3000&#39;);
});

The problem is i dont see the console.log(username, password, role, company); respone in console.log of server.When i use curl to test server it show normally:

curl -X POST -H &quot;Content-Type: application/json&quot; -d &#39;{
&quot;username&quot;: &quot;admin&quot;,
&quot;password&quot;: &quot;password&quot;,
&quot;role&quot;: &quot;Company&quot;,
&quot;company&quot;: &quot;Company 1&quot;
}&#39; http://localhost:3000/login

I dont know the json is send to the server or not. I use Android Studio in ubuntu vmware and connect my phone with usb debug.

答案1

得分: 1

尝试检查您的Android应用与服务器之间的通信。

查看 AsyncTask 是否正常执行。

在您的 AndroidManifest.xml 文件中检查互联网权限:

<uses-permission android:name="android.permission.INTERNET" />

如果不是在本地主机上,请检查您的服务器是否可以从您的Android设备或模拟器访问。确保使用正确的IP地址或主机名以及端口号连接到服务器。

考虑使用 HttpURLConnectionOkHttp 或类似 RetrofitVolley 的库,而不是 AsyncTask

Retrofit 示例:

  • 在 build.gradle 中添加依赖:
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0' // 如果您使用JSON
  • 创建一个实例并定义用于您的API的接口:
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("http://10.0.2.2:3000/")
    .addConverterFactory(GsonConverterFactory.create()) 
    .build();

// API 接口
interface MyApi {
    @POST("login")
    Call<ResponseBody> login(@Body JsonObject body); // 替换为请求体类型
}

MyApi myApi = retrofit.create(MyApi.class);
  • 使用 Retrofit 在 postData 中调用 API:
public void postData(String username, String password, String role, String company) {
    try {
        JsonObject body = new JsonObject();
        body.addProperty("username", username);
        body.addProperty("password", password);
        body.addProperty("role", role);
        body.addProperty("company", company);

        Call<ResponseBody> call = myApi.login(body);
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                if (response.isSuccessful()) {
                    // 处理成功的响应
                    // ...
                } else {
                    // 处理不成功的响应
                    // ...
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                // 处理网络失败
                // ...
            }
        });
    } catch (Exception e) {
        e.printStackTrace();
    }
}
英文:

Try to check the communication between your Android application and the server.

See if the AsyncTask is being executing properly.

Check internet permissions in your AndroidManifest.xml file

&lt;uses-permission android:name=&quot;android.permission.INTERNET&quot; /&gt;

If its not in localhost, check if your server is accessible from your Android device or simulator. Make sure you're using the correct IP address or hostname and port number to connect to the server.

Instead of AsyncTask, consider using HttpURLConnection, OkHttp, or libraries like Retrofit or Volley.

Retrofit example:

  • Add dependency to your build.gradle:
implementation &#39;com.squareup.retrofit2:retrofit:2.9.0&#39;
implementation &#39;com.squareup.retrofit2:converter-gson:2.9.0&#39; // if you&#39;re using JSON
  • Create instance and define an interface for your API:
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl(&quot;http://10.0.2.2:3000/&quot;)
    .addConverterFactory(GsonConverterFactory.create()) 
    .build();

// API interface
interface MyApi {
    @POST(&quot;login&quot;)
    Call&lt;ResponseBody&gt; login(@Body JsonObject body); // replace with the request body type
}

MyApi myApi = retrofit.create(MyApi.class);
  • Use the Retrofit to call the API in postData:
public void postData(String username, String password, String role, String company) {
    try {
        JsonObject body = new JsonObject();
        body.addProperty(&quot;username&quot;, username);
        body.addProperty(&quot;password&quot;, password);
        body.addProperty(&quot;role&quot;, role);
        body.addProperty(&quot;company&quot;, company);

        Call&lt;ResponseBody&gt; call = myApi.login(body);
        call.enqueue(new Callback&lt;ResponseBody&gt;() {
            @Override
            public void onResponse(Call&lt;ResponseBody&gt; call, Response&lt;ResponseBody&gt; response) {
                if (response.isSuccessful()) {
                    // Handle successful response
                    // ...
                } else {
                    // Handle unsuccessful response
                    // ...
                }
            }

            @Override
            public void onFailure(Call&lt;ResponseBody&gt; call, Throwable t) {
                // Handle network failure
                // ...
            }
        });
    } catch (Exception e) {
        e.printStackTrace();
    }
}

huangapple
  • 本文由 发表于 2023年6月15日 20:40:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/76482586.html
匿名

发表评论

匿名网友

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

确定