Android - 形成一个指定端口号的 URL 对象

Android - Forming an URL object specifying a port number

我正在为 Android 应用编写登录表单机制。登录 activity 将连接到数据库并验证最终用户提供的用户名和密码确实存在于数据库中。

我是通过调用名为 "login" 的服务器端方法来完成此操作的。服务器的端点是:example.us.es:3456/login/(机构url地址)。

当尝试使用 java.net 库提供的 URL class 来构建这个 URL 时,问题就来了。我是这样做的,但肯定有问题:

public static final String ENDPOINT_LOGIN = "example.us.es:3456/login/"
URL url = new URL(ENDPOINT_LOGIN);

我不确定如何构成这个 URL,因为它包含一个端口号。在 Android 开发者网页中,他们建议这样形成 URL:

http://username:password@host:8080/directory/file?query#ref

但是我的 url 地址与那个地址一点都不相似。

调试我的代码后,我得到的错误是:

java.net.MalformedURLException: Protocol not found: example.us.es:3456/login/

为了以防万一,我登录 activity 时的代码如下所示:

package com.example.loginapp;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.method.PasswordTransformationMethod;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;

public class LoginActivity extends Activity {

    EditText mUser;
    EditText mPassword;
    Button mLoginButton;
    public static final String TAG = LoginActivity.class.getSimpleName();
    public static final String ENDPOINT_LOGIN = "example.us.es:3456/login/"

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_macceso);
        mUser = (EditText) findViewById(R.id.et_user);
        mPassword = (EditText)findViewById(R.id.et_password);
        mLoginButton = (Button)findViewById(R.id.b_signIn);

        mLoginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FetchLoginInfo fetchLogin = new FetchLoginInfo();
                fetchLogin.execute();
            }
        });
    }

    private void tryLogin(String username, String password)
    {
        HttpURLConnection connection = null;
        OutputStreamWriter request = null;
        BufferedReader reader = null;

        URL url = null;
        String response = null;
        String parameters = "user="+username+"&password="+password;

        try
        {
            url = new URL(ENDPOINT_LOGIN);
            connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            connection.setRequestMethod("POST");

            request = new OutputStreamWriter(connection.getOutputStream());
            request.write(parameters);
            request.flush();
            request.close();
            String line = "";
            InputStreamReader isr = new InputStreamReader(connection.getInputStream());
            reader = new BufferedReader(isr);
            StringBuilder sb = new StringBuilder();
            while ((line = reader.readLine()) != null)
            {
                sb.append(line + "\n");
            }
            // Respuesta del servidor se almacena en "response".
            response = sb.toString();
            isr.close();
            reader.close();
        } catch(IOException e) {
            // Error
            Log.e(TAG, "Error ", e);
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (final IOException e) {
                    Log.e(TAG, "Error closing stream", e);
                }
            }
        }
    }

    private class FetchLoginInfo extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... params) {
            tryLogin(mUser.getText().toString(), mPassword.getText().toString());
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
        //Check returned code from server
            Intent i = new Intent(MAccesoActivity.this, MCentralActivity.class);
            startActivity(i);
            super.onPostExecute(aVoid);
        }
    }
}

我想在更正URL地址后,tryLogin方法中仍然会出现其他错误,所以我把它附在上面以防万一任何好心人想快速浏览一下以寻找任何大的错误。

那么,如何构造我得到的URL?谢谢。


更新 (1)

正如 Rodrigo Henriques 所指出的,我忘记在 URL 的开头添加 "http" 方案。尽管这解决了问题(java.net.MalformedURLException),但现在我得到了一个新问题:

java.net.ConnectException: failed to connect to example.us.es/xxx.xxx.xxx.xx (port 3456): connect failed: ECONNREFUSED (Connection refused)

也许有人可以告诉我如何摆脱它。 (我不是服务器管理员,我应该联系她吗?)


更新 (2)

最终报错:

java.net.ConnectException: failed to connect to example.us.es/xxx.xxx.xxx.xx (port 3456): connect failed: ECONNREFUSED (Connection refused)

联系管理员后消失了。所有问题都解决了。

查看此异常消息,我注意到您忘记将 http 协议放在 URL 的开头。

此致。