Prog.Lang. or Query/R Statistics

tomcat + eclipse + R + jsp 연동

천정현 2009. 10. 15. 16:51
Java/JSP를 이용하여 통계로직을 작성할 경우

환경 : java 1.6, tomcat, MyEclipse, R-2.6.2

1. R을 다운받아 설치한다.
 

R 설치 파일 다운로드 : http://bibs.snu.ac.kr/R/bin/windows/base/old/2.6.2/
jsp와 연동시에는 2.9.2 버전과 2.4.0 버전을 설치해서 해보았으나 모두 실패하고 2.6.2버전만 성공했다.
(다른 버전을 사용했을 경우에는 Handshake failed 나 다른 에러가 발생하였음 )


설치야 뭐 다음... URL 참고 (사실 여기보고 한거임..)
http://tong.nate.com/asamaru/45743796

* 환경변수 추가 :
 PATH = %PATH%; c:\Program Files\R\R-2.6.2\bin
 R_HOME = c:\Program Files\R\R-2.6.2

2. R을 실행한다.
필요한 라이브러리 설치
> install.packages(“xlsReadWrite”) # 엑셀파일을 읽고 쓰기 위한 라이브러리
> install.packages("Rserve") # java와 연동을 하기위한 라이브러리
> install.packages(“Rcmdr”) # R 스크립트 툴로 보다 쉽게 개발할수 있도록 구현 되어 있다. R commander
> library(Rcmdr) # R commander 실행

3. R script 생성 
 
 
test.R
# 다중 선형 회귀모형
library(xlsReadWrite) # windows only!
xls <- read.xls(file = "C:\\source.xls", sheet = 1,
                type = "data.frame", from = 1, colNames = TRUE);
datainfo =xls[,2];
curjoin =xls[,3];
newjoin =xls[,4];
library(lattice)
prod.lm = lm(datainfo ~ curjoin + newjoin)       # 다중 회귀 선형모형
print(prod.lm$coef)

            -- 설명 : 엑셀에서 데이터를 불러서 다중 회귀선형분석 값을 가짐

4. JRclient 등록

 J2EE 용 이클립스를 이용하여 웹애플리케이션을 작성하는 경우 웹애플리케이션 폴더에서 WEB-INF 폴더에 lib폴더에 JRclient-RF503.jar 추가
  - 요게 연결하는 함수 있음.

5. 코드작성

PlotFactory.java

package s2c.stat.rserver;
 
import java.awt.*;
import java.io.IOException;
import java.util.*;
import org.rosuda.JRclient.*;
 
public class PlotFactory {
 public static Object executeR(){
  try {
   Object result = null;
   Object tmp = null;
   Rconnection c = localRconnection();
   c.voidEval("library(xlsReadWrite)");
   c.voidEval("xls <- read.xls(file = \"C:/freezone/20091014/source.xls\", sheet = 1, type = \"data.frame\", from = 1, colNames = TRUE)");
   c.voidEval("datainfo =xls[,2]");
   c.voidEval("curjoin =xls[,3]");
   c.voidEval("newjoin =xls[,4]");
   /*
   c.voidEval("datainfo =c(1,2,3)");
   c.voidEval("curjoin =c(4,5,6)");
   c.voidEval("newjoin =c(7,8,9)");
   */
   c.voidEval("all = cbind(datainfo, curjoin, newjoin)");
   c.voidEval("library(lattice)");
   c.eval("prod.lm = lm(datainfo ~ curjoin + newjoin)"); 
   result = c.eval("show(prod.lm$coef)");
   ArrayList arrlist = new ArrayList();
   String str = result.toString();
   str = str.substring(str.lastIndexOf("("));
   while(!str.equals("")){
    if(str.startsWith("("))
     str = str.substring(1,str.length()-2);
    arrlist.add(str.substring(0, (str.indexOf(",")!=-1)?str.indexOf(","):str.length()));
    str = str.substring((str.indexOf(",")!=-1)?str.indexOf(", ")+2:str.length());
    System.out.println(arrlist);   }
   // 값 저장
   while(!str.equals("")){
    if(str.startsWith("("))
     str = str.substring(1,str.length()-2);
    arrlist.add(str.substring(0, (str.indexOf(",")!=-1)?str.indexOf(","):str.length()));
    str = str.substring((str.indexOf(",")!=-1)?str.indexOf(", ")+2:str.length());
    System.out.println(arrlist);
   }
         c.close();     //반드시 처리해야 하는 코드           
   return arrlist;
  } catch (RSrvException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  return null;
 }
 private static Rconnection localRconnection() throws RSrvException {
  Rconnection c = new Rconnection();
  System.out.println("c = "+c);
  return c;
 }
}



index.jsp

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%@page import="s2c.stat.rserver.PlotFactory"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>RServer Demo Application - Normal Distribution</title>
</head>
<body>
<h1><u>Standard Normal Distribution</u></h1>
         <%=PlotFactory.executeR()%>
</body>
</html>


6. Rserve실행 (두가지 방법중 아무거나)
 - R 실행 후 
       > library(Rserve)
       > Rserve()
 - R 폴더에서 
       Rserve.EXE  실행
7. 실행


중간에 여러 종류의 오류로 성공하지 못할 경우는 다음의 참고URL들을 이용해본다.

1. R: http://www.r-project.org/
2. Rserve : http://stats.math.uni-augsburg.de/Rserve/doc.shtml
3. JRclient Java API: http://stats.math.uni-augsburg.de/Rserve/dist/JRclient/JavaDoc/
4. ACME: http://www.acme.com/java/software/Acme.JPM.Encoders.GifEncoder.html
5. JSP에서 동적 이미지 생성: http://okjsp.pe.kr/lecture/lec13/acmejsp01.xml
6. R 데이터 가져오기 : http://statcompute.spaces.live.com/blog/cns!39C8032DBD1321B7!419.entry
7. R 샘플 코드 : http://www.statmethods.net/
                       http://www.statwith.pe.kr/STAT_PRO/functions001.htm
8. R 학습 : http://infostat2.knou.ac.kr/Pre/실험실습코스웨어/웹문서(HTML)/intro/index.htm



참고 : 다음 방법은 command명렁을 사용해서 다이렉트로 jsp에서 실행하는 방법이다.
Copy index.jsp

<%@ page language="java" import="java.io.*,java.util.*;" pageEncoding="EUC-KR"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 <%   
 String command = "cmd.exe /C start C:\\\"Program Files\"\\R\\R-2.9.2\\bin\\R CMD BATCH C:\\freezone\\20091014\\run_1013.R"; 
 int lineCount = 0;
 String line="";
 
 Runtime rt = Runtime.getRuntime();
 Process ps = null; try{
  ps = rt.exec(command);
 }catch(Exception ie){
  ie.printStackTrace();
  out.println(ie.toString());
 } 
  
 File file = new File("C:\\out.txt");
 while(!file.exists());
 FileInputStream fis = null;
 BufferedInputStream bis = null;
    DataInputStream dis = null;    try {
  fis = new FileInputStream(file);
  // Here BufferedInputStream is added for fast reading.
  bis = new BufferedInputStream(fis);
  dis = new DataInputStream(bis);
  
  // dis.available() returns 0 if the file does not have more lines.
  while (dis.available() != 0) {  
   // this statement reads the line from the file and print it to
   // the console.
   out.println(dis.readLine());
  }
  
  // dispose all the resources after using them.
  fis.close();
  bis.close();
  dis.close();
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
   }
%>