2014年4月17日木曜日

Android Spring Security ログイン

ログイン状態(Cookie)を保持する為、HttpClient を Singleton で取得する。
保持している static が初期化された場合、再度ログインが必要。

jp.s6131.sampleApp.SampleHttpClient.java
public class SampleHttpClient {
    private static DefaultHttpClient httpClient = new DefaultHttpClient();
    private SampleHttpClient() {}
    public static DefaultHttpClient getInstance() {
        return httpClient;
    }
}

メイン画面にテキストボックスとボタンを配置、クリックで AsyncHttpRequest 実行、
同クラスから呼び出す setResult メソッドで GridView に結果を表示。

jp.s6131.sampleApp.HelloAndroidActivity.java
public class HelloAndroidActivity extends Activity {
    private static String TAG = "sampleApp";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, "onCreate");
        setContentView(R.layout.main);
    }
    public void onClick(View v) {
        EditText searchText = (EditText) findViewById(id.search_text);
        Uri.Builder builder = new Uri.Builder();
        AsyncHttpRequest task = new AsyncHttpRequest(
                this,
                searchText.getText().toString()
                );
        task.execute(builder);
    }
    public void setResult(Code[] resList) {
        if (resList != null && resList.length != 0) {
            List<String> resultList = new ArrayList<String>();
            for (Code res : resList) {
                resultList.add((res.id == null ? "null" : res.id));
                resultList.add((res.code == null ? "null" : res.code));
                resultList.add((res.name == null ? "null" : res.name));
            }
            ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, R.layout.rowdata, resultList);
            GridView gridTable = (GridView) findViewById(id.grid_table);
            gridTable.setAdapter(arrayAdapter);
        }
    }
}

Spring Security 未ログインの場合、LoginActivity へ遷移。

jp.s6131.sampleApp.AsyncHttpRequest.java
public class AsyncHttpRequest extends AsyncTask<Uri.Builder, Void, Code[]> {
    private HelloAndroidActivity mainActivity;
    private String searchText;
    public AsyncHttpRequest(HelloAndroidActivity activity, String searchText) {
        this.mainActivity = activity;
        this.searchText = searchText;
    }
    @Override
    protected Code[] doInBackground(Uri.Builder... builder) {
        RestTemplate template = new RestTemplate();
        template.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
        DefaultHttpClient httpClient = SampleHttpClient.getInstance();
        template.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient));
        String url = "http://10.0.2.2/sample/sampleList?cd=" + searchText;
        try {
            ResponseEntity<Code[]> responseEntity = template.exchange(url, HttpMethod.GET, null, Code[].class);
            Code[] resList = responseEntity.getBody();
            return resList;
        } catch (Exception e) {
            Log.d("Error", e.toString());
        }
        return null;
    }
    @Override
    protected void onPostExecute(Code[] resList) {
        if (resList != null && resList.length != 0) {
            if ("-1".equals(resList[0].getId())) {
                Intent intent = new Intent(mainActivity.getApplicationContext(), LoginActivity.class);
                mainActivity.startActivity(intent);
                return;
            }
        }
        mainActivity.setResult(resList);
    }
}

ログイン画面にユーザー、パスワードのテキストボックスとボタンを配置、クリックで AsyncLoginRequest 実行。

jp.s6131.sampleApp.LoginActivity.java
public class LoginActivity extends Activity {
    private static String TAG = "sampleApp";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, "onCreate");
        setContentView(R.layout.login);
    }
    public void onClick(View v) {
        EditText useridText = (EditText) findViewById(id.userid_text);
        EditText passwordText = (EditText) findViewById(id.password_text);
        Uri.Builder builder = new Uri.Builder();
        AsyncLoginRequest task = new AsyncLoginRequest(
                this,
                useridText.getText().toString(),
                passwordText.getText().toString()
                );
        task.execute(builder);
    }
}

とりあえず無条件に HelloAndroidActivity に遷移

jp.s6131.sampleApp.AsyncLoginRequest.java
public class AsyncLoginRequest extends AsyncTask<Uri.Builder, Void, String> {
    private LoginActivity mainActivity;
    String userId;
    String password;
    public AsyncLoginRequest(LoginActivity mainActivity, String userId, String password) {
        this.mainActivity = mainActivity;
        this.userId = userId;
        this.password = password;
    }
    @Override
    protected String doInBackground(Uri.Builder... builder) {
        try {
            URI url = new URI( "http://10.0.2.2/sample/j_spring_security_check" );
            HttpPost request = new HttpPost( url );
            List<NameValuePair> post_params = new ArrayList<NameValuePair>();
            post_params.add(new BasicNameValuePair("j_username", userId));
            post_params.add(new BasicNameValuePair("j_password", password));
            request.setEntity(new UrlEncodedFormEntity(post_params, "UTF-8"));
            DefaultHttpClient httpClient = SampleHttpClient.getInstance();
            HttpResponse response = httpClient.execute(request);
            return null;
        }catch (Exception e){
            Log.d("Error", e.toString());
        }
        return null;
    }
    @Override
    protected void onPostExecute(String result) {
        Intent intent = new Intent(mainActivity.getApplicationContext(), HelloAndroidActivity.class);
        mainActivity.startActivity(intent);
    }
}

メイン画面

res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <EditText
        android:id="@+id/search_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="text">
        <requestFocus />
    </EditText>
    <Button
        android:id="@+id/get_json_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="@string/json" />
    <GridView
        android:id="@+id/grid_table"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:numColumns="3" >
    </GridView>
</LinearLayout>

GridView の TextView を別ファイルで定義。

res/layout/rowdata.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
</TextView>

ログイン画面

res/layout/login.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/userid"
    />
    <EditText
        android:id="@+id/userid_text"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:inputType="textPersonName"
        >
        <requestFocus />
    </EditText>
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/password"
    />
    <EditText
        android:id="@+id/password_text"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:inputType="textPassword"
    />
    <Button
        android:id="@+id/login_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="@string/login"
    />
</LinearLayout>

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="jp.s6131.sampleApp" android:versionCode="1" android:versionName="0.0.1-SNAPSHOT">
  <uses-sdk android:minSdkVersion="11"
            android:targetSdkVersion="19" />
  <uses-permission android:name="android.permission.INTERNET" />
  <application android:icon="@drawable/icon" android:label="@string/app_name">
    <activity android:name=".HelloAndroidActivity">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
    <activity android:name=".LoginActivity"
        android:label="@string/app_name"
        android:launchMode="singleTask"
        android:noHistory="true">
    </activity>
  </application>
</manifest>


人気ブログランキングへ