RoboGuice 2.x 사용 환경에서 ProGuard 설정에 추가해줄 내용입니다.

(참고 : http://code.google.com/p/roboguice/wiki/ProGuard)


# res/values/roboguice.xml 파일에 풀네임이 지정되는 클래스 보존

-keep class * extends com.google.inject.AbstractModule


# 참조할 수 없다는 경고 제거(can't find referenced method)

-dontwarn roboguice.**


# roboguice,guice 클래스 및 멤버 보존(필요에 따라 좀더 세밀하게 조정할 것)

-keep class roboguice.event.EventThread { *; }

#-keep public class roboguice.**

#-keep public class com.google.inject.**


# @Inject 붙은 생성자/필드/메소드 및 public 기본생성자 보존

-keepclassmembers class * {

    @com.google.inject.Inject <init>(...);

    @com.google.inject.Inject *;

    public <init>();

}


# There's no way to keep all @Observes methods, so use the On*Event convention to identify event handlers

-keepclassmembers class * {

    void *(**On*Event);

}

Posted by 에코지오
,

안드로이드 코딩시 도움이 되는 대표적 오픈소스 프레임워크/라이브러리인 RoboGuice와 AndroidAnnotations에 대한 비교 메모입니다.


1. RoboGuice (RG)

- Injection 대상 : View, Resource, 시스템서비스, POJO 등

- 향상된 유틸리티 클래스 제공 : RoboAsyncTask, Ln 등

- 액티비티 생명주기 Event 전달을 통한 모듈화 메커니즘 제공 : 액티비티에 대한 강한 커플링을 제거.

- Activity는 RoboActivity를 상속받아야 함

- Activity가 아닌 클래스에서도 안드로이드 컴포넌트 inject 가능

- 구글 Guice에 의존 : 강력하고 충실한 inject 기능 제공

- 런타임시에 inject 및 어노테이션을 처리하므로 성능하락 존재

- 용량 큼 : 590KB



2. AndroidAnnotations (AA)

- Injection 대상 : View, Resource, 시스템서비스, POJO(제한적) 등

- 다양한 유틸리티성 어노테이션 제공. inject외에 다양한 작업을 어노테이션을 통해 처리

 : 쓰레드작업(UiThread, Background,..), 이벤트처리(Click, ItemClick,...), REST통신 등

- 컴파일 타임에 inject 및 어노테이션 처리한 자식클래스를 생성 : 런타임 성능하락 없음

- 특정 Activity 상속 필요없음

- java annotation processing 설정 필요

- 새 액티비티 클래스 작성후 Android Manifest.xml 수정이 필요 => 액티비티 클래스명 끝에 언더바를 추가해줘야함

 : 예를들어 ".xxx.MyActivity" -> ".xxx.MyActivity_" 

- 명시적으로 액티비티 사용시에 언더바 붙은 액티비티를 사용해야 함

- 용량 작음 : 53KB



* 참고자료

http://blog.springsource.org/2011/08/26/clean-code-with-android/

http://blog.softwaregeeks.org/archives/647

Posted by 에코지오
,

안드로이드 앱 프로젝트가 AspectJ 클래스를 포함하고 있는 안드로이드 라이브러리 프로젝트를 참조하는 경우에, 라이브러리 프로젝트의 aspect는 예상과는 달리 앱 프로젝트에 적용되지 않습니다. 

그러니까 앱 프로젝트의 소스 컴파일시에 라이브러리 프로젝트의 aspect들과 함께 위빙되어 컴파일이 돼야하는데 그렇지 않다는 겁니다.

아래의 방법으로 해결할 수 있습니다.


1. Aspect Path 설정

앱 프로젝트 속성창 > AspectJ Build > Aspect Path 탭에서 "Add Project"를 통해 라이브러리 프로젝트를 추가해줍니다.

(아래 그림에서는 mobile-framework-android 프로젝트가 라이브러리 프로젝트입니다)




이렇게 하면 AspectJ 컴파일러가 앱 프로젝트 빌드시에 라이브러리 프로젝트에 포함된 aspect를 포함하여 함께 위빙시킵니다.

(라이브러리 프로젝트의 bin/xxx.jar 파일을 추가해도 되며, jar파일이 'Reference Libraries' 변수로 자동 추가됨)


2. Ant 빌드파일 설정

custom_rules.xml의 iajc 타스크에 아래 설정을 추가합니다.


      <aspectPath>

        <!-- 라이브러리 프로젝트에 속한 애스펙트도 적용 -->

        <path refid="project.libraries.jars" />

      </aspectPath>



Posted by 에코지오
,

최근에 Android SDK 버전을 r17로 업그레이드하고 나니 바뀐 점이 꽤 많더군요. 


1. 안드로이드 라이브러리 프로젝트

- bin 디렉토리에 R.class를 제외한 컴파일된 클래스를 포함하는 .jar 파일이 만들어짐.
  프로젝트이름이 my-library이면 my-library.jar 파일이 생성됨.


2. 안드로이드 앱 프로젝트

- libs 폴더의 모든 jar 파일이 'Android Dependencies' 라이브러리 변수에 자동으로 포함되어 빌드패스에 추가됨

- 라이브러리 프로젝트를 참조 라이브러리로 추가할 경우 라이브러리 프로젝트의 빌드 결과물 jar 파일이
  역시 'Android Dependencies' 라이브러리 변수에 자동으로 포함됨. 또한 라이브러리 프로젝트의 소스가 소스패스에 자동으로 추가됨.



* ADT를 통한 빌드시 자꾸 Dalvik 포맷 에러 발생하는 이슈 해결방법

- Conversion to Dalvik format failed with error 에러가 발생함

=> 앱 프로젝트에 자동으로 추가된 라이브러리 프로젝트의 소스폴더를 소스패스에서 제거해줌


* jar 파일과 소스 연결 이슈 해결방법

- 'Android Dependencies'에 포함된 jar 파일에 대해서 소스를 따로 attach할 수가 없음

=> jar 파일안에 .java 소스를 포함시키면 됨



3. ProGuard 설정

- 프로가드를 사용하려면 project.properties에서 아래 라인을 주석해제함.


proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt


- 설정파일이 proguard.cfg에서 proguard-project.txt로 변경되었으며, proguard-project.txt에는 프로젝트 specific한 내용만 작성.


4. Ant 빌드
- 여러가지 바뀜. 자세한 내용은 Android 사이트 참고.. -.-;;

* 참고하세요.

Posted by 에코지오
,

1. 우리가 작성한 코드에 대해서만 위빙이 가능

 AOP에서 위빙하는 방식은 시점에 따라 컴파일타임 위빙과 런타임 위빙으로 나눌 수 있습니다. 

안드로이드 Dalvik VM(.class 를 변형한 .dex 포맷을 사용)은 아직까지 런타임 바이트코드 생성을 지원하지 않습니다. 따라서 안드로이드에서는 런타임 위빙을 사용할 수 없고, 컴파일타임 위빙만 가능합니다(AspectJ는 컴파일 타임 위빙을 지원합니다).

우리가 작성한 소스코드에 대해서만 인터셉트할 수 있으며, 안드로이드 프레임워크나 그외 라이브러리에 대한 어드바이스는 작동하지 않습니다.


예들들어 Activity 클래스의 onCreate() 메소드에 대한 execution() 포인트컷은 작동하지만, 반면에 call() 포인트컷은 작동하지 않습니다. 왜냐면 onCreate() 메소드를 호출하는 클래스는 수정불가한 안드로이드 프레임워크에 속하기 때문입니다.


그리고 before나 after 같은 어드바이스를 통해 우리가 작성한 Activity 클래스의 예들들어 onResume() 라이프사이클 메소드에 로직을 추가하기  위해서는 반드시 해당 액티비티 클래스에 onResumE() 메소드 "코드"가 존재해야합니다. 비록 액티비티가 상속받은 android.app.Activity 클래스에 이미 onResume()  메소드가 존재하지만, 런타임이 아닌 컴파일 타임에 위빙이 수행되므로 어드바이스가 적용되기 바란다면 onResume() 메소드를 오버라이드 해주어야 합니다.



2. thisJointPoint 를 사용하기 위한 이클립스 설정

어드바이스 안에 thisJointPoint 키워드를 사용하는 코드가 존재하면 컴파일은 되지만 실제로 런타임에 아래와 같이 AspectJ 클래스를 못찾는다는 에러가 발생합니다.


Caused by: java.lang.NoClassDefFoundError: org.aspectj.runtime.reflect.Factory


이는 AJDT 플러그인에 의해 빌드패스에 추가된 'AspectJ Runtime Library' 라이브러리(aspectjrt.jar) 파일이 최종 dex 파일에 포함되지 않아 발생하는 문제입니다. 프로젝트 빌드패스 설정창의 "Order and Export" 탭에서 "AspectJ Runtime Library" 항목을 체크해주면 해결됩니다.


그러나 여전히 Ant 빌드(build.xml)를 통해 빌드를 시도하면 NoClassDefFoundError 에러가 발생합니다. build.xml을 수정해줄 수도 있지만 그냥 aspectjrt.jar를 libs 폴더에 넣어두면 간단히 해결됩니다. libs에 존재하는 jar 파일은 "Android Dependencies " 형태로 빌드패스에 자동으로 추가되므로 AJDT에 의해 추가된 'AspectJ Runtime Library'는 더이상 필요없습니다.


결론적으로  안드로이드 라이브러리('Android 2.3.x' 같은) 변수와 'Android Dependencies' 라이브러리 변수를 제외한 모든 외부 라이브러리 변수는 제거하고 필요한 모든 외부 jar 파일은 libs 폴더에 넣어두는 것이 좋습니다.


Posted by 에코지오
,

안드로이드에서 AspectJ를 사용하기 위해 이클립스 및 Ant빌드 환경을 구성하는 방법을 설명합니다.


1. AspectJ 설치

AspectJ 홈페이지(http://www.eclipse.org/aspectj/)에서 AspectJ 컴파일러를 다운로드 받아 설치합니다.

저는 개발버전인 AspectJ 1.7을 받아서 D:/Compiler/aspectj1.7 경로에 설치했습니다.

설치는 다운받은 jar 파일을 실행하면 됩니다. 


> java -jar aspectj-1.7.0.M1.jar


2. 이클립스 AJDT 플러그인 설치

이클립스 AspectJ 개발 플러그인인 AJDT를 설치합니다. http://www.eclipse.org/ajdt/downloads/ 

(이클립스 메뉴에서 Help > Install New Software... 를 선택한 후 설치 주소에 업데이트 주소 입력)

저는 개발버전인 AJDT 2.2.x를 설치했습니다. http://download.eclipse.org/tools/ajdt/37/dev/update


3. 클래스패스에 aspectrt.jar 파일 추가

aspectrt-1.7.jar 파일을 안드로이드 프로젝트의 libs 폴더에 넣어줍니다. ADT(저의 경우는 r17을 쓰고 있습니다)가 libs 폴더의 모든 jar 파일들을 자동으로 'Android Dependencies' 라이브러리에 추가해줍니다.


4. 프로젝트에 AspectJ 특성 추가

프로젝트 오른 클릭 >  Configures > Convert to AspectJ Project 를 선택하여 AspectJ 특성을 추가합니다. 그러면 프로젝트 빌더에 AspectJ Builder가 추가되고 Java Builder는 제거되며, 빌드패스에 'AspectJ Runtime Library'가 자동으로 추가됩니다.

그러나 Java Builder가 제거되면 이클립스 Problems 뷰 및 Tasks 뷰에 기존에 보였던 컴파일 에러라든가 TODO 목록이 안보이게 되므로 .project 파일에   아래와 같이 다시 Java Builder를 강제로 추가해줍니다.


  <buildSpec>

    <buildCommand>

      <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>

      <arguments>

      </arguments>

    </buildCommand>

    <buildCommand>

      <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>

      <arguments>

      </arguments>

    </buildCommand>

    <buildCommand>

      <name>org.eclipse.wst.common.project.facet.core.builder</name>

      <arguments>

      </arguments>

    </buildCommand>

    <buildCommand>

      <name>org.eclipse.jdt.core.javabuilder</name>

      <arguments>

      </arguments>

    </buildCommand>

    <buildCommand>

      <name>org.eclipse.ajdt.core.ajbuilder</name>

      <arguments>

      </arguments>

    </buildCommand>

    <buildCommand>

      <name>com.android.ide.eclipse.adt.ApkBuilder</name>

      <arguments>

      </arguments>

    </buildCommand>

  </buildSpec>


그리고  'AspectJ Runtime Library' 라이브러리 변수는 제거해줍니다.


5. aspect 작성

예를들어 src/my/app/aop/MyFirstAspect.aj 파일을 만들고 포인트컷과 어드바이스 등을 코딩해줍니다.


AspectJ 코딩 방법은 다음사이트를 참고합니다.


http://dev.anyframejava.org/anyframe/doc/core/3.2.1/corefw/guide/aop-based-aspectj.html

http://blog.daum.net/oraclejava/15858189



개발시점에서 aspect 소스 컴파일은 AJDT로 충분하지만 릴리스용 빌드생성 또는 자동빌드를 위해서는 Ant 빌드(build.xml)을 이용하는 것이 편리합니다. (이하 Android SDK r17 버전 기준 설명입니다)


AspectJ 사용을 위한 Ant 빌드 설정

(1) local.properties 파일에 아래내용을 추가합니다.


# AspectJ 컴파일러 홈

aspectj.home=D:\\Compiler\\aspectj1.7


(2) project.properties 파일에 아래내용을 추가합니다.


# AspectJ 소스 리스트 파일 경로

aspectj.src.list=aspect-list.txt


(3) custom_rules.xml 파일을 아래의 내용으로 새로 작성합니다.(기존에 파일이 존재한다면 내용을 추가)


<?xml version="1.0" encoding="UTF-8"?>

<project name="custom_rules" default="-post-compile">


  <!-- AspectJ 컴파일 추가 -->

  <taskdef resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties">

   <classpath>

     <pathelement location="${aspectj.home}/lib/aspectjtools.jar" />

   </classpath>

  </taskdef>

  <!-- iajc 타스크 설명 : http://www.eclipse.org/aspectj/doc/released/devguide/antTasks.html -->

  <!-- sourceRoots, inpath, aspectpath에 대한 설명 : http://www.jroller.com/tmjee/entry/iajc_usage -->

  <target name="-post-compile">

    <echo message="Weaving aspects to .class files before dex converts .class files to .dex file" />

   <!-- aspectpathref : 라이브러리에 속한 애스펙트도 적용할 경우 설정 -->

    <iajc destDir="${out.classes.absolute.dir}"

          bootclasspathref="android.target.classpath"

          classpathref="project.libraries.jars"

          classpath="${aspectj.home}/lib/aspectjrt.jar"

          sourceroots="${source.absolute.dir}"

          inpath="${out.classes.absolute.dir}"

          aspectpathref="project.libraries.jars"

          Xlintwarnings="true"

          showWeaveInfo="true"

          encoding="${java.encoding}"

          source="${java.source}"

          target="${java.target}">

    </iajc>

  </target>


</project>


만약 프로젝트 유형이 안드로이드 '라이브러리' 프로젝트라면 아래와 같이 -post-compile 타겟을 정의합니다.


    <echo message="Weaving aspects to .class..." />

    <iajc destDir="${out.classes.absolute.dir}"

          bootclasspathref="android.target.classpath"

          classpathref="project.libraries.jars"

          classpath="${aspectj.home}/lib/aspectjrt.jar"

          Xlintwarnings="true"

          showWeaveInfo="true"

          encoding="${java.encoding}"

          source="${java.source}"

          target="${java.target}">


      <sourceroots>

        <pathelement location="${source.absolute.dir}" />

        <pathelement location="${gen.absolute.dir}" />

      </sourceroots>


      <!--

       inpath="${out.classes.absolute.dir}"

       => 이 옵션을 적용하면 앱에서 라이브러리의 애스펙트도 적용하도록 

            설정한 경우 bad WeaverState.Kind: -115 에러 발생함

      -->

    </iajc>


    <!-- 라이브러리 프로젝트인 경우 -compile 타겟에서 생성된 classes.jar를 위빙된 클래스로 교체 -->

    <if condition="${project.is.library}">

      <then>

        <echo>Overwrite library output jar file with weaved classes...</echo>

        <jar destfile="${out.library.jar.file}" update="false">

          <fileset dir="${out.classes.absolute.dir}"

                   includes="**/*.class"

                   excludes="${manifest.package.path}/R.class ${manifest.package.path}/R$*.class ${manifest.package.path}/Manifest.class ${manifest.package.path}/Manifest$*.class ${manifest.package.path}/BuildConfig.class" />

          <fileset dir="${source.absolute.dir}"

                   excludes="**/*.java ${android.package.excludes}" />

        </jar>

      </then>

    </if>




(4) proguard-project.txt에 다음 내용을 추가합니다.


# aspect 클래스 및 aspect가 적용되는 클래스에서 AspectJ 라이브러리를 참조할 수 없다는 경고 제거

# (can't find referenced class)

-dontwarn org.aspectj.**


# 패키지 변경 금지(주석해제시 런타임에 java.lang.NoSuchMethodError 에러 발생)

#-repackageclasses ''

#-allowaccessmodification


# AspectJ 클래스 보존

-keep class org.aspectj.**


# Aspect 클래스 및 멤버 보존

-keep @org.aspectj.lang.annotation.Aspect class * { *; }

-keepclasseswithmembers class * {

    public static *** aspectOf();

}


# around 어드바이스가 적용되는 target 클래스에서 around 어드바이스 메소드를

# 참조할 수 없다는 경고 제거(can't find referenced method) : aspect 클래스를 지정

-dontwarn my.app.aop.**

(또는 -dontwarn my.app.**.*Aspect 식으로 설정)


(5) aspect 소스 리스트 파일 작성

aspectj.src.list 속성으로 정의한 aspect-list.txt 파일을 생성하고, aspect 소스 리스트를 한줄에 하나씩 나열합니다.

경로는 프로젝트 루트에 대한 상대경로입니다.


src/my/app/aop/MyFirstAspect.aj

src/my/app/aop/MySecondAspect.aj

...


Posted by 에코지오
,

안드로이드에 AOP를 적용할 수 있는지 구글 형님께 알아보니 가능하다는 답변이 나옵니다.

=> http://blog.punegtug.org/2010/11/adding-aspect-to-android.html


1. 그러나 안드로이드는 런타임 바이트코드 생성을 지원하지 않기 때문에 컴파일타임 위빙만 가능합니다.

=> http://stackoverflow.com/questions/3759232/aspect-oriented-programming-in-android

2. 구글 Guice는 메소드 인터셉터 같은 일부 AOP 기능을 제공하는데

  이는 런타임 바이트코드 생성 방법을 사용하므로 안드로이드에서는 사용할 수 없습니다.

=> http://code.google.com/p/google-guice/wiki/OptionalAOP

3. 어쨋든 안드로이드에서도 컴파일 타임 위빙을 통한 AOP는 가능하기 때문에

  AspectJ 라이브러리를 이용해 AOP 프로그래밍을 할 수 있습니다.

=> http://deansserver.co.uk/~dean/2011/07/18/aspect-oriented-android-development-tool-integration/
=> http://code.google.com/p/android-aspectj/


4. 그럼 안드로이드에서 AOP를 어디에 활용할수 있을까요?

(1) 공통 에러 처리

- 발생된 Exception을 잡아서 에러로그를 서버로 보내 앱 유지보수에 참고할 수 있습니다.

  (물론 에러정보를 서버로 전송할지 사용자에게 물어야겠죠).

- Exception 발생시 안드로이드는 안드로이드 고유의 에러 창과 함께 앱프로세스가 죽어버리는데,

  이렇게 하기보다는 좀더 우아한 메시지와 함께 에러창을 꾸밀 수 있습니다.

- 또한 앱프로세스가 종료되지 않게 하거나 에러가 발생한 Activity만 종료하게 할 수 있을 것입니다.

  (앱을 종료할지 말지는 에러정책에 따라 달라질 것입니다)


(2) 개발을 위한 로깅

- 개발시 편의를 위해 디버그용 로그를 모든 Activity의 라이프사이클 메소드에 추가할 수 있습니다.

- Activity의 UI 렌더링 속도를 측정하기 위해 onCreate() 실행 전과 onResume() 실행 후의 경과시간을 계산할 수 있습니다.


(3) 아키텍처 위반 체크

- 예를 들어 레이어링 아키텍처를 갖도록 설계된 앱에서 아키텍처를 깨는 호출이 존재하는 경우 아예 컴파일이 안되게 처리할 수 있습니다.


(4) Activity 라이프사이클 메소드에 기능 추가

- 예들들어(이건 정말 그저 예입니다) 로그인이 포함된 앱에서 앱 자체의 세션 타임아웃을 체크하여 세션이 만료된 경우 로그인 Activity로 이동하게 할 수 있습니다. AOP를 이용하여 로그인 Activity를 제외한 다른 모든 Activity의 onCreate()나 onResume() 메소드에 세션타임아웃 체크 로직을 추가하면 됩니다.  단 이 경우 반드시 해당 메소드 "코드"가 액티비티에 존재해야합니다(왜냐면 안드로이드에서는 컴파일타임 위빙만 가능하기 때문)

- 또다른 예로 카톡같은 화면잠금을 생각할 수 있습니다. 모든 Activity의 onResume()과 onPause()에 화면잠금 로직을 쉽게 추가할 수 있습니다.


(5) ... ...



Posted by 에코지오
,

아래는 안드로이드 개발시 AspectJ 라이브러리를 사용하는 경우 기본적인 ProGuard 설정에 추가해주어야 할 내용입니다.

# aspect 클래스 및 aspect가 적용되는 클래스에서 AspectJ 라이브러리를 참조할 수 없다는 경고 제거
# (can't find referenced class)
-dontwarn org.aspectj.**

# AspectJ 클래스 변경금지
-keep class org.aspectj.**

# Aspect 클래스 보존
-keep @org.aspectj.lang.annotation.Aspect class * { *; }
-keepclasseswithmembers class * {
  public static *** aspectOf();
}

# 패키지 변경 금지(주석해제시 런타임에 java.lang.NoSuchMethodError 에러 발생)
#-repackageclasses ''
#-allowaccessmodification

# around 어드바이스가 적용되는 target 클래스에서 around 어드바이스 메소드를
# 참조할 수 없다는 경고 제거(can't find referenced method) : aspect 클래스를 지정
-dontwarn my.app.aop.**
(또는 -dontwarn my.app.**.*Aspect 식으로 설정)


Posted by 에코지오
,

저같은 경우 안드로이드 앱 개발시 JSON 데이터 처리를 위해 주로 Codehaus의 jackson json 라이브러리 (jackson-core-asl-x.x.jar, jackson-mapper-asl-x.x.jar)를 사용합니다. 

이렇게 앱에서 Jackson JSON 라이브러리를 사용하는 경우 ProGuard 설정을 어떻게 해줘야하는지 제대로 정리된 자료가 별로 없더군요.

그동안은 릴리스 빌드시에 잘못된 proguard 설정때문에 발생하는 에러나, 앱 실행시에 잘못된 소스난독화로 인한 런타임 에러를 만날때마다

임시방편으로 설정의 의미도 모른채 설정을 조금씩 고쳐가면서 소뒷걸음질하다 운좋게 에러를 해결하곤 했습니다. 에러가 없게 설정했다고 해도 왜 그런 설정이 필요한지 자세한 이유를 알지는 못했죠.

미루고 미루다 이제야 ProGuard 홈페이지 문서 Gson에서 사용하는 proguard 설정을 참고하여 아래와 같이 정리해보았습니다.

실제로 제가 개인적으로 개발중인 앱에 적용해서 빌드하고 테스트해보니 이상이 없었습니다.

# 어노테이션 보존

-keepattributes *Annotation*,EnclosingMethod


# 제너릭 타입 정보 보존

-keepattributes Signature


# Jackson이 참조하는 다른 라이브러리(joda-time 등) 없다는 경고 제거

-dontwarn org.codehaus.jackson.**


# java.lang.NoSuchFieldError: PUBLIC_ONLY 에러 제거

-keepnames class org.codehaus.jackson.** { *; }


# Jackson에 의해 JSON데이터와 매핑(바인딩)되는 모델(POJO) 클래스 보존

-keep public class my.app.model.** { *; }


# 모델 클래스외에 getter/setter 보존이 필요한 경우

#-keep public class my.app.** {

#  public void set*(***);

#  public *** get();

#}



Posted by 에코지오
,
아래글에서는 WebView와 웹서버간의 HTTP 통신내용을 모니터링하는 방법을 설명했습니다. 이번에는 Spring-Android 라이브러리를 이용하여 앱과 웹서버간에 REST로 통신하는 경우에 통신 내용을 엿보는 방법입니다.

import org.apache.http.HttpHost;
import org.apache.http.conn.params.ConnRoutePNames;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
...

public class MyRestActivity extends Activity {

  public xxx someMethod() {
  
    RestTemplate restTemplate = new RestTemplate();
    ... ...
    
    if (isDebugMode(this.getApplicationContext())) { 
      HttpComponentsClientHttpRequestFactory factory =
                   (HttpComponentsClientHttpRequestFactory) restTemplate.getRequestFactory();
      HttpHost proxy = new HttpHost("본인로컬PC의 IP주소", 프록시포트, "http");
      factory.getHttpClient().getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
    }

    ... ...
    ResponseEntity<Xxx> result = 
restTemplate.exchange(url, HttpMethod.POST, requestEntity, Xxx.class);
    ... ...
 
  }
}  


아래글에서 지적했듯이 개발자 PC의 IP주소에 localhost나 127.0.0.1 루프백 주소를 쓰면 안됩니다.

이클립스 TCP/IP 모니터 뷰 설정하는 방법은 아래글과 동일합니다.


실제 앱 개발시에는 위와 같이 프록시를 설정한 RestTemplate 인스턴스를 공통모듈단에서 한개만 만들어놓고 재사용하면 됩니다.
 
Posted by 에코지오
,