2013년 11월 22일 금요일

ubuntu tomcat 기본설치 후 실행 노트

출처: http://stackoverflow.com/questions/10259738/how-to-restart-tomcat-6-in-ubuntu

/etc/init.d/tomcat7 start
/etc/init.d/tomcat7 stop
/etc/init.d/tomcat7 restart
우분투에 apt-get install tomcat7 으로 설치한 톰캣을 실행.

출처: http://askubuntu.com/questions/135824/what-is-the-tomcat-installation-directory

apt-get으로 설치한 후 폴더 구조이다.
/etc/tomcat6/
├── Catalina
│   └── localhost
│       ├── ROOT.xml
│       └── solr.xml -> ../../../solr/solr-tomcat.xml
├── catalina.properties
├── context.xml
├── logging.properties
├── policy.d
│   ├── 01system.policy
│   ├── 02debian.policy
│   ├── 03catalina.policy
│   ├── 04webapps.policy
│   ├── 05solr.policy -> /etc/solr/tomcat.policy
│   └── 50local.policy
├── server.xml
├── tomcat-users.xml
└── web.xml
/usr/share/tomcat6
/usr/share/tomcat6
├── bin
│   ├── bootstrap.jar
│   ├── catalina.sh
│   ├── catalina-tasks.xml
│   ├── digest.sh
│   ├── setclasspath.sh
│   ├── shutdown.sh
│   ├── startup.sh
│   ├── tomcat-juli.jar -> ../../java/tomcat-juli.jar
│   ├── tool-wrapper.sh
│   └── version.sh
├── defaults.md5sum
├── defaults.template
└── lib
    ├── annotations-api.jar -> ../../java/annotations-api-6.0.35.jar
    ├── catalina-ant.jar -> ../../java/catalina-ant-6.0.35.jar
    ├── catalina-ha.jar -> ../../java/catalina-ha-6.0.35.jar
    ├── catalina.jar -> ../../java/catalina-6.0.35.jar
    ├── catalina-tribes.jar -> ../../java/catalina-tribes-6.0.35.jar
    ├── commons-dbcp.jar -> ../../java/commons-dbcp.jar
    ├── commons-pool.jar -> ../../java/commons-pool.jar
    ├── el-api.jar -> ../../java/el-api-2.1.jar
    ├── jasper-el.jar -> ../../java/jasper-el-6.0.35.jar
    ├── jasper.jar -> ../../java/jasper-6.0.35.jar
    ├── jasper-jdt.jar -> ../../java/ecj.jar
    ├── jsp-api.jar -> ../../java/jsp-api-2.1.jar
    ├── servlet-api.jar -> ../../java/servlet-api-2.5.jar
    ├── tomcat-coyote.jar -> ../../java/tomcat-coyote-6.0.35.jar
    ├── tomcat-i18n-es.jar -> ../../java/tomcat-i18n-es-6.0.35.jar
    ├── tomcat-i18n-fr.jar -> ../../java/tomcat-i18n-fr-6.0.35.jar
    └── tomcat-i18n-ja.jar -> ../../java/tomcat-i18n-ja-6.0.35.jar
/usr/share/tomcat6-root/
/usr/share/tomcat6-root/
└── default_root
    ├── index.html
    └── META-INF
        └── context.xml
/usr/share/doc/tomcat6
/usr/share/doc/tomcat6
├── changelog.Debian.gz -> ../libtomcat6-java/changelog.Debian.gz
├── copyright
└── README.Debian.gz -> ../tomcat6-common/README.Debian.gz
/var/cache/tomcat6
/var/cache/tomcat6
├── Catalina
│   └── localhost
│       ├── _
│       └── solr
│           └── org
│               └── apache
│                   └── jsp
│                       ├── admin
│                       │   ├── form_jsp.class
│                       │   ├── form_jsp.java
│                       │   ├── get_002dproperties_jsp.class
│                       │   ├── get_002dproperties_jsp.java
│                       │   ├── index_jsp.class
│                       │   ├── index_jsp.java
│                       │   ├── schema_jsp.class
│                       │   ├── schema_jsp.java
│                       │   ├── stats_jsp.class
│                       │   ├── stats_jsp.java
│                       │   ├── threaddump_jsp.class
│                       │   └── threaddump_jsp.java
│                       ├── index_jsp.class
│                       └── index_jsp.java
└── catalina.policy
/var/lib/tomcat6
/var/lib/tomcat6
├── common
│   └── classes
├── conf -> /etc/tomcat6
├── logs -> ../../log/tomcat6
├── server
│   └── classes
├── shared
│   └── classes
├── webapps
│   └── ROOT
│       ├── index.html
│       └── META-INF
│           └── context.xml
└── work -> ../../cache/tomcat6
/var/log/tomcat6
/var/log/tomcat6
├── catalina.out
톰캣 외부 접속 설정
출처: http://asm0628.tistory.com/176
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" address="0.0.0.0" /> 

git hub 몇가지 노트

간단한 명령어 소개 링크 : http://unikys.tistory.com/323
-> 명령어를 잘 정리해 놓은 링크
내가 사용하는 몇가지 명령어 참조: http://chriskr7.blog.me/60203914580
1. 우선 깃헙에 리파지토리를 만든다.
2. 내 로컬에 git폴더를 만들고 리파지토리와 동일한 이름의 폴더를 만든다.
3. 커맨드 창에서 'git init' 명령어로 초기화 한다.
4. git remote add origin https://github.com..... 을 통해서 나의 리파지토리 url을 origin으로 설정
(git remote set-url origin https://UserID@github.com/UserID/repository.git 을 통해 변경가능)
5. git add . (or git commit -a) 명령어로 파일들을 더한다.
6. git commit 명령어로 커밋한다. (리눅스에서 커밋 코멘트를 다는 화면으로 이동한다)
7. git push -u origin master 명령어로 origin의 master 브랜치로 푸시한다.
8. git pull origin 명령어로 origin의 변경 내용을 내려받을 수 있다.


머지하기
출처: http://yaku.tistory.com/334
출처: http://gitref.org/branching/

git branch
-> 현재 브랜치를 확인한다.
git merge target
-> 타겟 브랜치를 현재 브랜치에 머지한다.
(git checkout -b change_class
Switched to a new branch 'change_class')
컨플릭트가 발생하면
git diff
-> 다른 항목들의 (컨플릭트가 발생한 항목) 내용을 확인 할 수 있다.
에디터로 해당 항목을 연 후
(git merge fix_readme
Auto-merging README
CONFLICT (content): Merge conflict in README
Automatic merge failed; fix conflicts and then commit the result.
$ cat README 
<<<<<<< HEAD
Many Hello World Examples
=======
Hello World Lang Examples
>>>>>>> fix_readme

This project has examples of hello world in 
nearly every programming language.)
>>>>>>>> 와 ======= 또는 <<<<<<<< 로 이루어진 항목을 찾아가서 해당 컨플릭트를 해결하면 된다. 현재까진 직접 중복 결과값을 수정해도 문제 없었다.
$ git status -s
UU README
$ git add README 
$ git status -s
M  README
$ git commit 
[master 8d585ea] Merge branch 'fix_readme'
위에 상태 확인을 했을 때 UU 항목이 컨플릭트 등에 의해서 머지가 제대로 안된 항목
컨플릭트를 해결한 후 add시키면 된다.
그 후에 커밋하면 끝.

Ignore 설정하기
출처: http://rapapa.net/?p=85
어느 소스폴더에서 "git init"를 한 폴더 전체가 소스관리 대상에 포함된다.
(git init 는 git로 현재폴더를 소스관리 하겠다는 명령어)
.git이 있는 최상위폴더 (git init을 한 폴더)에서
.gitignore 파일을 만든다
내용은 커밋을 제외하는 내용을 적으면 된다. (출처 참조)
글로빙 규칙에 맞춰서 적으면 된다.
이미 커밋이 되어 있던(사용중이던) 폴더라면
제외 시켜주면 되는데
출처에 나온 git rm 명령을 쓰면 된다.
제외 시킬 파일을 미리 확인하고 싶으면
git rm --dry-run *.log(제외시킬 파일 글로빙)
이렇게 하면 된다.

2013년 11월 19일 화요일

Facebook example을 사용하면서 생기는 에러 - Android

conversion to dalvik format failed unable to execute dex...
dex loader unable to execute dex buffer overflow....

-> 개인적으로 가장 이해가 안되는 에러였다. 이것저것 다 해봤지만 결국  버전의 다운그레이드가 정답이었다. 이 에러는 사람들마다 해결책이 다 다른것 같다.

unable to instantiate activity componentinfo

-> 전체적으로 페이스북 예제를 처음 만들어서 실행할 때 가장 큰 에러는 빌드 패스인것 같다.
출처2의 안드로이드 디펜던시를 제거했더니 실행이 된다는 내용은... 추천하지 않는다. 임시방편이고 단지 실행만 된다. 실제 런타임에서는 에러가 발생된다.

->  안드로이드 인증관련 문제인데... 해결책을 보면 볼수록 어렵다. 그냥 설치된 앱을 지우고 프로젝트 클린하고 재빌드해서 도전하는게 나을듯

가장 도움이 많이 되었던 링크 http://dakehosu.tistory.com/69
페이스북 SDK를 받아서 이클립스에서 라이브러리로 추가해야 한다는 내용이다.
가장 정확하고 도움이 많이 되었다.

실제 오랜시간 삽질을 하고 나니 대부분 빌드패스의 문제였다. 안드로이드 서포터 jar파일이 나의 프로젝트에도 있고 페이스북 SDK 프로젝트에도 있어서 생기는 문제가 가장 날 힘들게 했다. ㅠ

2013년 11월 18일 월요일

layout inflater

- 레이아웃 인플레이터(Layout Inflater)
: 레이아웃 인플레이터는 레이아웃 xml 파일에 상응하는 뷰 객체를 반환받는 데 사용한다. 자바 프로그램 코드상에서는 레이아웃 인플레이터에 직접 접근하지 못하고 getLayoutInflater() 메소드를 이용하거나 getSystemService(String) 메소드를 호출해 반환값으로 LayoutInflater 객체를 받아야 한다. 

2013년 10월 13일 일요일

AssertionError: write() argument must be string | 구글 앱 엔진

파이선으로 구글 앱 엔진 예제를 동작 시키던 중
위와 같은 에러가 생기면서 동작이 안되었다.

많은 내용들을 보니 유니코드로 바꾸면 된다는 결론
하지만 유니코드로 바꿀 때 안되는 부분이 있었다.
self.response.out.write(content.encode('utf-8'))
이 부분은 제대로 동작하지 않는듯 하다.
self.response.out.write(unicode(template.render('main.html', {})))
다시 찾다보니 위와 같이 바꾸니까 된다.

출처:
1. 동작안했던 유니코드 변환 부분
http://stackoverflow.com/questions/8558323/error-in-deployed-gae-requesthandler-using-webapp2
2. 동작하는 유니코드 변환부분
http://chrislee.kr/wp/tag/wsgirefhandlers-py-assertionerror-write-argument-must-be-string-python/

2013년 9월 25일 수요일

Android - display | getWidth(), getHeight()

Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
윈도우 매니저의 getDefaultDisplay() 메소드를 통해 Display 객체를 얻은 후 이 객체의 getWidth(), getHeight() 함수를 사용해 현재 화면의 가로, 세로 해상도를 추출한 코드이다.
하지만 이 코드들은 deprecated 되었다.

다른 방법을 찾아서 노트로 남겨 놓는다.
Point pOutSize = new Point();
getWindowManager().getDefaultDisplay().getSize(pOutSize);
int width = pOutSize.x;
int height = pOutSize.y;

EditText et1 = (EditText)findViewById(R.id.et1);
et1.setWidth(width -100);


코드 출처: 노규남, Q&A로 배우는 안드로이드 프로그래밍, WellBook, Q36(330page)
내용 출처: http://sshioi.tistory.com/125, 안드로이드 The method getWidth() from the type Display is deprecated :: 프잡 파트

2013년 8월 27일 화요일

Spring Batch | Tasklet 옵션

Copied from : http://stackoverflow.com/questions/11119036/spring-batch-how-to-limit-the-no-of-executions-of-a-chunk

<batch:step id="mig-chain-data">
<batch:tasklet allow-start-if-complete="false" start-limit="1">
<batch:chunk commit-interval="1" reader="reader" writer="writer"></batch:chunk>
</batch:tasklet>
</batch:step>


 start-limit controls the number of times a Step may be started, not the chunk configured for this step.

From : http://www.codeproject.com/Articles/445856/Getting-Started-With-Spring-Batch-Part-Two

commit-interval 은 한번에 수행할 청크의 갯수를 지정 (processes 'N'  chunk at a time as indicated by the commit-interval)

Copied from : http://springsource.tistory.com/93
Tasklet
Tasklet 은 Step 내부의 트랜잭션 또는 반복될 수 있는 처리작업을 의미한다. 개발자들은 Tasklet 인터페이스를 직접 구현해서 사용하거나 스프링 배치가 제공하는 구현체를 사용할 수도 있다. 압축파일을 해제한다거나 특정 디렉토리를 정리하는 등의 특정 작업에는 직접 구현한 Tasklet 이 유용하다. 스프링 배치는 시스템 명령을 호출한다거나 chunk 기반(chunk-oriented) 처리를 수행할 수 있도록 좀더 일반화된 Tasklet 구현체를 제공한다. 
tasklet 엘리먼트가 제공하는 어트리뷰트는 다음과 같다.
ref : Tasklet 인터페이스를 구현한 스프링 빈의 id 를 의미한다. 커스텀 tasklet 을 사용하려면 이 어트리뷰트를 설정해 줘야 한다.
transaction-manager : Tasklet 에서 트랜젝션처리 시에 사용할 스프링 트랜젝션 매니저를 설정한다. tasklet 에서는 기본적으로 트랜잭션 처리가 가능하다. 디폴트 값은 transactionManager 이다.
allow-start-if-complete : Tasklet 의 실행이 성공했을 경우라도 스프링 배치가 이 Tasklet 을 재실행 가능한지 여부를 설정한다.

Reference : http://www.pfl-cepia.inra.fr/uploads/gdp_docs/spring-batch-2.0.pdf

Hadoop mode - 하둡 모드, 각 요소 노트

하둡은 Stand alone, Pseudo-distributed, Fully-distributed 총 3가지 모드로 설치할 수 있다.
(설치 후 설정 파일을 어떻게 설정하냐에 따라서)

Stand alone mode와 Pseudo-distributed mode의 공통점은 하나의 머신에서 실행된다는 것이다.
하지만 stand alone 모드는 tasktacker와 namenode, datanode, jobtracker 모두 하나의 JVM에서 실행된다는 것이 다르다. (Pseudo-distributed mode는 각각의 JVM에서 실행된다)
그래서 stand alone 모드에서는 데이터의 직렬화가 크게 중요한 문제는 아니다. 하지만 가상 분산 모드에서는 맵퍼와 리듀서간에 직렬화된 데이터를 주고 받으므로 직렬화가 중요하다.
(그렇다는 내용을 StackOverflow에서 봤었다)

하둡은 마스터와 슬레이브 구조로 이루어져 있는데
마스터는 Namenode, Jobtracker (추가적으로 SecondaryNamenode) 로 이루어져 있고
슬레이브는 Datanode, Tasktracker로 이루어져 있다.
마스터/슬레이브의 설정, Namenode, Datanode 설정 Job/Task tracker 설정 등 모두 하둡의 conf 폴더에서 직접 설정 해 줄 수 있다.



각 요소들의 기능
Copy From : http://amalgjose.wordpress.com/2012/12/08/making-a-pseudo-distributed-hadoop-cluster/
NameNodes
Name node is the master server of the cluster. It  doesnot store any file but knows where the blocks are stored in the child nodes and can give pointers and can re-assemble .Namenodes  comes up with  two  features  say Fsimage  and the edit log.FSImage   and edit log
Features
  1. Highly memory intensive
  2. Keeping it safe and isolated is necessary
  3. Manages the file system namespaces
DataNodes
Child nodes are attached to the main node.
Features:
  1. Data node  has  a configuration file to make itself  available in the cluster .Again they stores  data regarding storage capacity(Ex:5 out f 10 is available) of   that  particular data  node.
  2. Data nodes are independent ,since they are not pointing to any other data nodes.
  3. Manages the storage  attached to the  node.
  4. There  will be  multiple data nodes  in a cluster.
Job Tracker
  1. Schedules and assign task to the different datanodes.
  2. Work Flow
  3. Takes  the request.
  4. Assign the  task.
  5. Validate the requested work.
  6. Checks  whether  all the  data nodes  are working properly.
  7. If not, reschedule the tasks.
Task Tracker
Job Tracker and  task tracker   works   in  a master slave model. Every  datanode has got a  task tracker which  actually performs  the  task  which ever  assigned to it by the Job tracker.
Secondary Name Node
Secondaryname node  is not  a redundant  namenode but  this actually  provides  the  check pointing  and  housekeeping tasks  periodically.

2013년 8월 26일 월요일

사진-링크|하둡 맵리듀스의 전반적인 과정 설명

하둡의 맵리듀스 과정에 대한 설명을 보기 좋게 정리한 내용이 있어서
나중에 참고하고자 담아왔다.

Please refer the following url

Original: http://grepalex.com/2012/09/24/map-partition-sort-spill/
http://develop.sunshiny.co.kr/897
 

Spring EL 사용하기

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<util:properties id="mySettings" location="classpath:my.properties"/>
<context:component-scan base-package="com.my.classes" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="#{mySettings['jdbc.driver']}" />
<property name="url" value="#{mySettings['jdbc.url']}" />
<property name="username" value="#{mySettings['jdbc.user']}" />
<property name="password" value="#{mySettings['jdbc.password']}" />

</bean>
</beans>

자바에서 Spring EL을 사용해서 Annotation으로 기본 변수 값을 지정하려 하니 null 값이 반환되서 원인을 찾다보니 내가 사용할 클래스의 패키지를 스프링이 알게 해야 한다는것을 알았다.
진하게 표시된 부분을 통해서 Annotation을 찾을 수 있도록 해줬다.
java에서 사용 
  1. @Value("#{db['db.driverclassname']}")  
  2. private String defaultString;  


jsp 에서 사용 
  1. <spring:eval expression="@db['db.username']" />  


출처: http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/expressions.html
http://stackoverflow.com/questions/12977484/null-pointer-when-calling-pre-instantiated-bean-from-spring-container-with-jsf
http://devkkaok.tistory.com/90
http://whiteship.tistory.com/2201
http://tazz009.tistory.com/507

2013년 8월 25일 일요일

fieldSetMapper 사용 - 스프링 배치

플랫 파일을 읽고 쓸 때 자신이 만든 클래스에 매핑시켜 읽어 들이면 편하다.
이떄 BeanWrapperFieldSetMapper를 사용하면 편리하다.

<bean id="myDataReader"
  class="org.springframework.batch.item.file.FlatFileItemReader" scope="step">
  <property name="resource" value="file:/home/output/data/#{jobParameters['myfolder']}.txt"/>
  <property name="lineMapper">
  <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
<property name="lineTokenizer">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
<property name="names" value="number,dataTime,data1,data2,data3"/>
<property name="delimiter">
<util:constant static-field="org.springframework.batch.item.file.transform.DelimitedLineTokenizer.DELIMITER_TAB"/>
<!-- 탭으로 구분 -->
</property>
</bean>
</property>
<property name="fieldSetMapper">
<bean class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
<property name="targetType"
value="com.my.data.myDao"/>
    <!-- myDao는 파란색글씨와 똑같은 이름의 변수들을 갖고 있고 setter와 getter도 갖고있다-->
    <!-- filedSetMapper를 만들어서 사용해도 관계없다 -->
    <!--bean class="com.my.data.ReportFieldSetMapper" /-->
</bean>
</property>
  </bean>
  </property>
  </bean>
  <bean id="myDataWriter"
  class="org.springframework.batch.item.database.JdbcBatchItemWriter" scope="step">
  <property name="assertUpdates" value="true"/>
  <property name="dataSource" ref="dataSource"/>
  <property name="itemSqlParameterSourceProvider">
<bean class="org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider" />
</property>
  <property name="sql"
  value="INSERT INTO MY_DATA_TB (MY_ID,DATA_TM,DATA_1,DATA_2,DATA_3)
  VALUES (:number,:dataTime,:data1,:data2,:data3)">
  </property>
  </bean>



참조 :http://blog.naver.com/yesql?Redirect=Log&logNo=70173668117
http://static.springsource.org/spring-batch/reference/html/readersAndWriters.html

2013년 8월 22일 목요일

Hadoop multiple mapper | reducer

하나의 하둡 잡에는 여러개의 맵퍼는 가능하지만 리듀서는 하나만 가능하다.
From : http://stackoverflow.com/questions/11122832/hadoop-mapreduce-possible-to-define-two-mappers-and-reducers-in-one-hadoop-job
You can have multiple mappers, but in one job, you can only have one reducer. And the features you need are MultipleInputMultipleOutput and GenericWritable.
Using MultipleInput, you can set the mapper and the corresponding inputFormat. Here is my post about how to use it.
Using GenericWritable, you can separate different input classes in the reducer. Here is my post about how to use it.
Using MultipleOutput, you can output different classes in the same reducer.

여러개의 리듀서를 사용하고 싶다면 잡을 연결시키면 된다. (다른 방법도 있을지도)
먼저 하둡 잡을 잘 설명한 내용이 있어서 가져와봤다.
From: http://stackoverflow.com/questions/12872590/hadoop-streaming-chaining-jobs
                            hadoopJob
                               /\
                              /  \
                             /    \
                            /      \
                           /        \
                Configuration       Execution
                     /\                 |
                    /  \                |
                   /    \   executable or script files
                  /      \
                 /        \
                /          \
  hadoopEnvironment     userEnvironment
           |                   /\
           |                  /  \
           |                 /    \ 
    $HADOOP_HOME/conf       /      \
                           /        \   
                genericOptions   streamingOptions
                      |                 |
                      |                 | 
            GenericOptionsParser StreamJob 

From : http://hadoop.apache.org/docs/current/api/org/apache/hadoop/mapred/lib/IdentityMapper.html
From: http://stackoverflow.com/questions/9749655/map-map-reduce-reduce-final-output
send the result of this job to another job, and set the mapper to IdentityMapper and the reducer to the second phase reducer that you have.
두개의 잡을 이어줄 때 IdentityMapper를 이용해서 결과값을 전달해 줄 수 있다고 한다.


참조: 하둡소개-http://www.slideshare.net/KeeyongHan/hadoop-introduction-10
맵리듀스 체이닝-http://gandhigeet.dinstudio.com/blog_1_7.html
야후 맵리듀스 예제-http://developer.yahoo.com/hadoop/tutorial/module4.html

2013년 8월 19일 월요일

ajax post - spring mvc

getJSON(http://api.jquery.com/jQuery.getJSON/)을 사용하는 것과 .ajax를 사용할 때 약간 다른 부분이 있어서 노트삼아 남겨놓는다.


1. Java Script 부분
 var inData = "data = data for sending"; 
$.ajax({
type:"POST",
url:"mypage",
//dataType : "json",
data: inData,
error: function(data) {
alert("FAIL");
},
success: function(data) {
handling data part
}
});
2. Controller 부분
@RequestMapping(value = "/mypage", method=RequestMethod.POST)
@ResponseBody
public List<Object> makeReport(HttpServletRequest req) {
logger.info("Displaying Page is AD");
string data = new String(req.getParameter("data"));
List<Object> data = (new SelectByDate().findFromByDate(data));
return data;
}

그냥 여러 군데를 참조하면서 배운것은 type을 통일시키고, url을 맵핑시키면 ajax요청은 문제없다는 것이다.
그리고 요청의 반환값은 여기서는 @ResponseBody를 이용해 Object의 리스트를 바로 넘겨줬지만 @ResponseBody없이 String 값을 넘겨줘도 된다.
여기서는 Object의 리스트를 넘겨주면 servlet 설정 파일에서 MappingJacksonHttpMessageConverter를 이용해서 JSON형식으로 변환시키도록 했다.
String 값을 바로 넘기면 JSON형식으로 String을 만들어서 넘기면 된다.
그냥 String을 넘기면 나는 주소값처럼 매핑시키려는 오류가 났는데 아직 원인과 해결 방법은 모르겠다.. ㅠ
post형식으로 요청시에 데이터를 넘길때는 '데이터이름=데이터값' 형식으로 저장한 후 HttpServletRequest를 통해 접근하는게 편하다. 여러가지 방법이 많이 있었다.
.ajax의 문법을 알아두면 나중에 요긴할 것 같다.

참조:
http://static.springsource.org/spring/docs/3.2.x/javadoc-api/org/springframework/web/bind/annotation/RequestBody.html
http://babtingdev.tistory.com/194
http://static.springsource.org/spring/docs/4.0.x/spring-framework-reference/html/jdbc.html#jdbc-JdbcTemplate
http://freesora.tistory.com/91
http://nanstrong.tistory.com/182
http://api.jquery.com/jQuery.post/
http://windvoice.tistory.com/51
http://blog.naver.com/jaeik714?Redirect=Log&logNo=140192129518

2013년 8월 14일 수요일

Javascript - 사용한것 기록중

document.getElementById('element ID').innerHTML = "";
=> clean the element like <div> and so on


console.log(var data);
=> write the variable to console


function foo(bar) {
       return bar;
}
=> this function return variable


data.sort(function(a, b){
return a.Number < b.Number ? -1 : a.Number > b.Number ? 1 : 0;
});
//데이터 정렬 오름차순
=> Array 객체 data내부의 sort 메소드를 사용,
     data 내용 a와 b비교할 때 각각의 Number란을 대소 구별 기준으로 삼았다.
참조: http://programmingsummaries.tistory.com/150


for(var i=0;i<data.length;i++)
=>for(var i in data)
=>for문의 함축적 표현 방법


자바 스크립트는 항상 call by value
함수를 변수처럼 인식.
참조: http://emflant.tistory.com/64

String class match() 메소드
string1.match(string2)
=> if it is matched return true
참조: http://blog.naver.com/mecca0515?Redirect=Log&logNo=60107858100



2013년 8월 12일 월요일

메시지 컨버터 AJAX JSON sample

메시지 컨버터는 HTTP요청 메시지 본문과 HTTP 응답 메시지 본문을
통째로 메시지로 다루는 방식
파라미터의 @RequestBody와 메소드에 부여한 @ResponseBody를 이용해 쓸 수 있다.

메시지 방식의 컨트롤러를 사용하는 방법은 두가지
1. HTTP - GET 요청 메소드 : 요청정보가 URL, 쿼리 스트링으로 제한되므로 @RequestBody 대신 @RequestParam이나 @ModelAttribute로 요청 파라미터를 전달 받음
2. HTTP - POST 요청 메소드 : HTTP 요청 본문이 제공되므로 @RequestBody를 사용할 수 있다.

JSON 기반의 AJAX를 지원하려면 컨트롤러는 결과를 JSON 포멧으로 만들어서 돌려줘야 한다.


1. Controller part
@RequestMapping(value = "/page", method=RequestMethod.GET)
        //page라고 들어오는 JSON GET 요청을 처리할 것임
@ResponseBody
//JSON으로 변환해 클라이언트로 보내기 위해
public List<MyDao> makeReport(@RequestParam("startTime") int startTime,
@RequestParam("endTime") int endTime) {
        //시작, 종료 시간을 폼에서 입력받아 get으로 넘겨받음 MyDao라는 클래스 리스트를 리턴
logger.info("Displaying Page ");
List<MyDao> data = (new SelectByDate().findByDate(startTime, endTime));
                //DB에서 날짜를 기준으로 검색해서 데이터를 가져오는 메소드 부분
return data;
               //리스트를 리턴 -> JSON message converter가 처리할 내용
}

2. servlet part
<beans:bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<beans:property name="messageConverters">
<beans:list>
<beans:bean class=
"org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
<!-- 오브젝트를 JSON으로 변환시켜줄 메시지 컨버터 -->
</beans:list>
</beans:property>
</beans:bean>

3. Java Script part (page.js)
$(document).ready(
function() {
$('adpage').submit(
function() {
if (request) {
request.abort(); // abort any pending request
}

$.getJSON('adpage/', function(data) {
                                                  //make url (adpage), GET방식의 JSON요청을 보낸다
                                                 //function()은 받은 data를 처리할 부분
console.log(data);  //print data
});
});
});

4. View part
<html>
<head>
<title>Home</title>
<script type="text/javascript" src="resources/jquery-2.0.3.js"></script>
<script type="text/javascript" src="resources/page.js"></script>
</head>
<body>
<h1>
AJAX JSON Example
</h1>

<P>  The time on the server is ${serverTime}. </P>
<form action="adpage" method="get">
<P>  Start Time
<input type="text" name="startTime" value="20130728"/>
</P>
<P>  End Time
<input type="text" name="endTime" value="20130801"/>
</P>
<input id="adpage" type="submit" value="Show Result"/>
</form>

</body>
</html>

Spring MVC controller 사용

Spring MVC Controller

@Controller
public class OrderController {

private static final Logger logger = LoggerFactory.getLogger(OrderController.class);

@RequestMapping(value = "/report", method=RequestMethod.GET)
public String adForm(Model model) {
model.addAttribute("startTime", "Start Time");
model.addAttribute("endTime", "End Time");
return "home";
}
@RequestMapping(value = "/result", method=RequestMethod.GET)
public String makeReport(@RequestParam("startTime") int startTime,
@RequestParam("endTime") int endTime, Model model) {
logger.info("Displaying Page is AD");
List<AdDao> data = (new SelectAdByDate().findFromAdByDate(startTime, endTime));
model.addAttribute("data", data);
return "result";
}

}

View
1. home.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
<title>Home</title>
</head>
<body>
<h1>
AJAX JSON Example
</h1>

<P>  The time on the server is ${serverTime}. </P>
<form action="result" method="get">
<P>  Start Time 
<input type="text" name="startTime" value="20130728"/>
</P>
<P>  End Time
<input type="text" name="endTime" value="20130801"/>
</P>
<input type="submit" value="result" onclick="result"/>
</form>

</body>
</html>

2. result.jsp
<!-- Use this for the 'form' tag   -->
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>

<%@ page session="false" %>
<html>
<head>
</head>
<body onload="loadChart(${data})">
<script type="text/javascript">
    var chart1;

    function loadChart(data) {
                 내용
    };

</script>
</body>
</html>


참조: http://snoopy81.tistory.com/314
http://blog.naver.com/PostView.nhn?blogId=fourleaf0311&logNo=140117091984&categoryNo=0&parentCategoryNo=0&viewDate=&currentPage=1&postListTopCurrentPage=1&userTopListOpen=true&userTopListCount=30&userTopListManageOpen=false&userTopListCurrentPage=1
http://springsource.tistory.com/13
http://arawn.github.io/blog/2012/03/17/at-modelattributeyi-sseuimsaeneun-mueosingo/
http://www.kunner.com/997
http://blog.daum.net/aswip/8429416

2013년 8월 11일 일요일

maven에 tomcat plugin 설정하기

From : http://www.captaindebug.com/2012/03/configuring-maven-tomcat-plugin.html#.Ugg8yeYW2Kk

Copied from Captain Debug's Blog
1. Setup a Tomcat Manager Account
$TOMCAT_HOME/conf/tomcat_users.xml
<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users>
 <role rolename="manager-gui"/>
 <role rolename="manager-script"/>
    <user username="admin" password="password" roles="manager-gui, manager-script"/>
</tomcat-users>

2. Add the manager credentials to your settings.xml
$MAVEN_HOME/conf/settings.xml
    <server>
      <id>myserver</id>
      <username>admin</username>
      <password>password</password>
    </server>

3. Add the Maven Tomcat plug in to your POM file
Your projects/pom.xml
    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>tomcat-maven-plugin</artifactId>
        <version>1.1</version>
        <configuration>
            <server>myserver</server>
            <url>http://localhost:8080/manager/text</url>
        </configuration>
    </plugin>

You can now start your server and run a Maven build using the "mvn install tomcat:deploy" command. Once installed, switch to the "tomcat:redeploy" goal.

Updated Information - by kwonjae
now there is apache tomcat plugin
So you have to write the following configuration instead of the number 3.
        <plugin>
         <groupId>org.apache.tomcat.maven</groupId>
         <artifactId>tomcat6-maven-plugin</artifactId>
         <version>2.1</version>
         <configuration>
           <server>myserver</server>
           <url>http://localhost:8080/manager/text</url> 
       </configuration>
       </plugin>
       <plugin>
         <groupId>org.apache.tomcat.maven</groupId>
         <artifactId>tomcat7-maven-plugin</artifactId>
         <version>2.1</version>
   </plugin>
And Some goals are not yet available with the tomcat7.
You have to write on tomcat6 and your goal have to be 'tomcat6:deploy'
From tomcat plugin, not using '/manager/html' but using '/manager/text'

refer : http://tomcat.apache.org/maven-plugin-2.1/
http://stackoverflow.com/questions/11824365/deploy-with-maven-on-tomcat7
http://stackoverflow.com/questions/5410479/tomcat-maven-plugin-403-error

2013년 8월 8일 목요일

JDBC, JUnit - 테이블에서 데이터 읽어오기

NamedParameter 를 사용해서 쿼리를 하려고 하였다.
하지만 쿼리 결과를 custom class의 리스트 형태로 받으려고 하니 제대로 되지 않았다.
그래서 NamedParameterJdbcTemplate 를 사용하지 않고
JdbcTemplate를 사용해서 쿼리를 날렸다.

그래서 sql문에 ?를 사용해서 퀴리를 만들고 사용했다.
(NamedParameter를 쓴다면 ? 대신 :이름 을 사용했을 것)

InitializingBean 을 사용해서 xml에 설정한 dataSource의 세팅을 확인했다.
RowMapper를 구현한 MyMapper 클래스를 작성해서 내가 원하는 형태의 출력을 만들었다.


------------------------- 자바 소스 -------------------------
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import javax.sql.DataSource;

import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

import com.my.dao.MyDao;

public class SelectByDate implements InitializingBean{
private JdbcTemplate jdbcTemplate;
private String sql = "SELECT * from MY_CNT_TB WHERE TM >= ? AND TM <= ?";
@Autowired
private DataSource dataSource;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
@Override
public void afterPropertiesSet() throws Exception {
// TODO Auto-generated method stub
if(dataSource==null) {
throw new BeanCreationException("Must set dataSource!");
}
}
public List<MyDao> findFromByDate(int startTime, int endTime) {
Object[] args = new Object[] {startTime,endTime};
return jdbcTemplate.query(sql, args, new MyMapper());
}

private static final class MyMapper implements RowMapper<MyDao> {
@Override
public MyDao mapRow(ResultSet rs, int rowNum) throws SQLException {
// TODO Auto-generated method stub
MyDao tempMy = new MyDao();
tempMy.setNumber(rs.getInt("NM_ID"));
tempMy.setTime(rs.getInt("TM"));
tempMy.setVal1(rs.getInt("VAL1_CNT"));
tempMy.setVal2(rs.getInt("VAL2_CNT"));
tempMy.setVal3(rs.getInt("VAL3_CNT"));
return tempMy;
}

}
}

------------------------- xml  설정파일 -------------------------
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<context:property-placeholder location="./jdbc.properties" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>${jdbc.driver}</value>
</property>
<property name="url">
<value>${jdbc.url}</value>
</property>
<property name="username">
<value>${jdbc.user}</value>
</property>
<property name="password">
<value>${jdbc.password}</value>
</property>
</bean>
</beans>

jdbc.properties 파일
# Placeholders jdbc*
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/user
# use this one for a separate server process so you can inspect the results
# (or add it to system properties with -D to override at run time).
schema=
schema.script=classpath:/org/springframework/batch/core/schema-mysql.sql
jdbc.user=user
jdbc.password=


------------------------- JUnit 테스트 파일 -------------------------
import java.util.List;
import javax.sql.DataSource;
import junit.framework.TestCase;
import org.apache.log4j.Logger;
import org.junit.Before;
import org.junit.Test;
import org.junit.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.util.StopWatch;

import com.my.dao.MyDao;
import com.my.SelectByDate;


@Configuration(value = "./jdbc-config.xml")
public class testJdbc extends TestCase {
private final static Logger logger = Logger
.getLogger(testJdbc.class);
SelectByDate test1;
@Autowired
private DataSource dataSource;

@Before
public void setUp() {
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
ctx.load("./jdbc-config.xml");
ctx.refresh();
dataSource = (DataSource) ctx.getBean("dataSource");
}

@Test
public void testJdbcTask() throws Exception {
StopWatch sw = new StopWatch();
test1 = new SelectByDate();
List<MyDao> result = null;
test1.setDataSource(dataSource);
sw.start();
result = test1.findFromByDate(20130728, 20130801);
assertEquals(108, result.size());
//108은 내가 직접 쿼리를 돌려 얻은 예상 값
logger.info(result.size());
sw.stop();
logger.info(">>> TIME ELAPSED:" + sw.prettyPrint());
}
}


참조 : http://stackoverflow.com/questions/16359316/namedparameterjdbctemplate-vs-jdbctemplate
http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/jdbc/core/namedparam/NamedParameterJdbcTemplate.html#queryForObject(java.lang.String, org.springframework.jdbc.core.namedparam.SqlParameterSource, org.springframework.jdbc.core.RowMapper)
http://pirrip.tistory.com/entry/Spring-JDBC-Template-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0
http://julingks.tistory.com/entry/Spring-JDBC-support
http://loopypapa.tistory.com/entry/SQL-SELECT-%EC%A1%B0%EA%B1%B4