Spring tiles

Programming/Java 2013.10.15 13:12 Posted by 파란크리스마스

aaplus-pc-tiles.xml

<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:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc 
		http://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context 
		http://www.springframework.org/schema/context/spring-context.xsd">
	

	<bean id="templateResolver"
		class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
		<property name="prefix" value="/WEB-INF/view/" />
		<property name="suffix" value=".html" />
		<property name="templateMode" value="HTML5" />
		<property name="cacheable" value="true" />
	</bean>
	<bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine">
		<property name="templateResolver" ref="templateResolver" />
	</bean>
	<bean class="org.thymeleaf.spring3.view.ThymeleafViewResolver">
		<property name="templateEngine" ref="templateEngine" />
		<property name="order" value="1" />
		<property name="viewNames" value="thymeleaf/*" />
	</bean>

	<!-- Resolves view names to Tiles definitions -->
	<beans profile="tiles3">
		<bean id="tilesViewResolver" class="org.springframework.web.servlet.view.tiles3.TilesViewResolver">
			<property name="order" value="0"/>
		</bean>
	
		<!-- Configures Tiles 3-->
		<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
			<property name="definitions">
				<list>
					<value>/WEB-INF/view/jsp/03-tiles/tiles.xml</value>
					<value>/WEB-INF/view/jsp/admin/tiles.xml</value>
				</list>
			</property>
		</bean>
	</beans>
	
	<beans profile="tiles2">
		<bean id="tilesViewResolver" class="org.springframework.web.servlet.view.tiles2.TilesViewResolver">
			<property name="order" value="0"/>
		</bean>
	
		<!-- Configures Tiles 2 -->
		<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
			<property name="definitions">
				<list>
					<value>/WEB-INF/view/jsp/03-tiles/tiles.xml</value>
					<value>/WEB-INF/view/jsp/admin/tiles.xml</value>
				</list>
			</property>
		</bean>
	</beans>

</beans>

/WEB-INF/view/jsp/03-tiles/tiles.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tiles-definitions PUBLIC 
	"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN" 
	"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">	

<tiles-definitions>

	<definition name="03-tiles/*" template="/WEB-INF/view/jsp/03-tiles/layout.jsp">
		<put-attribute name="main" value="/WEB-INF/view/jsp/03-tiles/{1}.jsp" />
	</definition>
	
</tiles-definitions>

/WEB-INF/view/jsp/03-tiles/layout.jsp

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>

<html>
<head>
	<meta charset="utf-8"/>
	<spring:url value="/common/style" var="styleUrl" />
	<link href="${styleUrl}/app.css" rel="stylesheet"/>
	<title><c:out value="${title}"/></title>
</head>

<body>
	<div class="container" style="padding-top: 50px;">
		<jsp:include page="/WEB-INF/view/jsp/menu.jsp"/>	
		<tiles:insertAttribute name="main" />
		<jsp:include page="/WEB-INF/view/jsp/footer.jsp"/>	
	</div>
</body>
</html>

Oracle Procedure - JDBC 배열(ARRAY 타입) 호출

Programming/Java 2013.04.11 15:24 Posted by 파란크리스마스

출처 : Passing Arrays between Java and Oracle Procedures
how to call procedure with out parameter as table type from a java class
Oracle procedure 'out' 'table of varchar2' type parameter
Oracle stored procedure using array as parameter for table insert
Jdbc array binding: character set encoding
Oracle Database 11g Release 2 JDBC Drivers

주의사항

1. Spring을 사용하는 경우 OracleConnection을 가지고 오기 위해서 <property name="accessToUnderlyingConnectionAllowed" value="true"/>

2. 인코딩 문제로 varchar2의 경우 orai18n.jar를 추가 해야 됨

oracle 배열 타입 생성

CREATE OR REPLACE TYPE ARRAY_V AS TABLE OF VARCHAR2(512);

oracle procedure

CREATE OR REPLACE PACKAGE XXX.PKG_TEST AS

  PROCEDURE SP_TERMINAL_SELECT
  ( 
    IN_TERMINAL_MAC  IN  ARRAY_V,
    OUT_TERMINAL_IP  OUT ARRAY_V   
  );

END PKG_TEST;
/

CREATE OR REPLACE PACKAGE BODY XXX.PKG_TEST IS

  PROCEDURE SP_TERMINAL_SELECT
  ( 
    IN_TERMINAL_MAC  IN  ARRAY_V,
    OUT_TERMINAL_IP  OUT ARRAY_V   
  ) IS
  BEGIN
    -- need to initialize the collection or it will fail if it is used
    OUT_TERMINAL_IP := ARRAY_V();
  
    FOR i IN 1 .. IN_TERMINAL_MAC.COUNT LOOP
    
        OUT_TERMINAL_IP.extend(1);
        
        SELECT TERMINAL_IP INTO OUT_TERMINAL_IP(i) 
          FROM TERMINAL
         WHERE TERMINAL_MAC = IN_TERMINAL_MAC(i); 
        
    END LOOP;
  
  END SP_TERMINAL_SELECT;

END PKG_TEST;
/

java 소스

package test;

import java.sql.Connection;
import java.sql.SQLException;

import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.OracleTypes;
import oracle.sql.ARRAY;
import oracle.sql.ArrayDescriptor;

import org.apache.commons.dbcp.DelegatingConnection;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import test.util.ConnectionManager;

public class SelectTerminal {
	
	public static ApplicationContext context;
	
	public static void main(String[] args) throws Exception {
		
		System.out.println("test");
        String[] configLocation = new String[] { "file:WebContent/WEB-INF/test-servlet.xml" };
        context = new ClassPathXmlApplicationContext(configLocation);
		
		Connection conn = null;
		try {
			conn = ConnectionManager.getConnection();

			//
			Connection oraConn = ((DelegatingConnection)conn).getDelegate();
			if ((oraConn instanceof DelegatingConnection) && !(oraConn instanceof oracle.jdbc.OracleConnection)) {
				oraConn = ((DelegatingConnection)oraConn).getDelegate();
			}
			
			// Create descriptors for each Oracle collection type required
			// CREATE OR REPLACE ARRAY_V AS TABLE OF VARCHAR2(512); 
			ArrayDescriptor oracleVarchar2Collection = ArrayDescriptor.createDescriptor("ARRAY_V", oraConn);

	        // JAVA arrays to hold the data.
	        String[] terminal_mac_array    = { "08:xx:xx:xx:xx:xx", "00:xx:xx:xx:xx:xx" };
	        ARRAY ora_terminal_mac    = new ARRAY(oracleVarchar2Collection, oraConn, terminal_mac_array);
	
	        show_array_info(ora_terminal_mac);
	        
	        // Bind the input arrays.
			OracleCallableStatement stmt = 
	        	(OracleCallableStatement) oraConn.prepareCall("{ call PKG_TEST.SP_TERMINAL_SELECT(?,?) }");	        

	        stmt.setArray(1, ora_terminal_mac);
	        stmt.registerOutParameter(2, OracleTypes.ARRAY, "ARRAY_V");
	        stmt.execute();

	        //
	        ARRAY ora_terminal_ip = stmt.getARRAY(2);
	        if (ora_terminal_ip!=null) {
	        	String[] terminal_ip_array = (String[])ora_terminal_ip.getArray();
	        	for (int i=0; i<terminal_ip_array.length; i++) {
	        		System.out.println(i + " / terminal_ip = " + terminal_ip_array[i]);
	        	}
	        }	        

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (conn!=null) try { conn.close(); } catch (SQLException e) { }
		}        
	}
	
	private static void show_array_info(oracle.sql.ARRAY p_in) throws SQLException {

		System.out.println("Array is of type      " + p_in.getSQLTypeName());
		System.out.println("Array is of type code " + p_in.getBaseType());
		System.out.println("Array is of length    " + p_in.length());

		String[] values = (String[]) p_in.getArray();

		for (int i = 0; i < p_in.length(); i++)
			System.out.println("p_in[" + i + "] = " + values[i]);
	}

}

결과

Array is of type      XXX.ARRAY_V
Array is of type code 12
Array is of length    2
p_in[0] = 08:xx:xx:xx:xx:xx
p_in[1] = 00:xx:xx:xx:xx:xx
0 / terminal_ip = 192.168.0.2
1 / terminal_ip = 192.168.0.3

Java - Get방식 Http 호출

Programming/Java 2013.04.01 21:17 Posted by 파란크리스마스
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;

public class HttpGetCall {

	public static void main(String[] args) throws Exception {
		URL url = new URL("http://naver.com");
		InputStream is = url.openStream();

		BufferedReader inFile = new BufferedReader(new InputStreamReader(is));
        String line = null;
        while( (line = inFile.readLine()) != null ) {
            System.out.println(line);
        }
		is.close();
	}
}
TAG GET, HTTP, Java, URL

NT Service로 기동할때 톰캣메모리설정

Programming/Java 2013.03.05 14:52 Posted by 파란크리스마스

출처 : NT Service로 기동할때 톰캣메모리설정

HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Tomcat7\Parameters

"JVM Option Number 4"="-Xms512m"
"JVM Option Number 5"="-Xmx1024m" 

log4j - 수동설정

Programming/Java 2013.02.04 17:41 Posted by 파란크리스마스

log4j - 수동설정

package com.server.servlet;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import org.apache.log4j.DailyRollingFileAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;

public class ServerInitServlet extends HttpServlet {
	
	public static String pattern = "%d{HH:mm:ss,SSS} (%p) [%F:%L] -> %m%n";
	
	Logger logger = Logger.getLogger(this.getClass());
	//Logger.getLogger(this.getClass());
	
	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public ServerInitServlet() {
		super();
	}
	
	public void init(ServletConfig cfg) throws ServletException {
		super.init(cfg);
        
        if (!Logger.getRootLogger().getAllAppenders().hasMoreElements()) {
        	
        	Logger.getRootLogger().getLoggerRepository().resetConfiguration();
        	
            // 로그 파일 대한 패턴을 정의
            PatternLayout layout = new PatternLayout(pattern); 
          
            // 생성될 로그 파일의 이름(조건에 따라 로그 파일이름을 따라 다르게...)
            String fileName = ServerConfig.getHome() + "/logs/application.log"; 
         
            // 날짜 패턴에 따라 추가될 파일 이름
            String datePattern = ".yyyyMMdd";
            
            /*
            ConsoleAppender consoleAppender = new ConsoleAppender(layout);
            Logger.getRootLogger().addAppender(consoleAppender);
            */  
        	
    		DailyRollingFileAppender appender = null;        
            try {
                appender = new DailyRollingFileAppender(layout, fileName, datePattern);
                appender.setAppend(true);
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }     
            
            //logger.addAppender(appender);
            //logger.getRootLogger().addAppender(appender);
            
            Logger.getRootLogger().addAppender(appender);
                        
            
            Logger.getRootLogger().setLevel(Level.INFO);
            Logger.getRootLogger().getLoggerRepository().getLogger("com.server.*").setLevel(Level.DEBUG);
            Logger.getRootLogger().getLoggerRepository().getLogger("com.opensymphony.*").setLevel(Level.WARN);
            Logger.getRootLogger().getLoggerRepository().getLogger("org.apache.*").setLevel(Level.WARN);
            Logger.getRootLogger().getLoggerRepository().getLogger("org.springframework.*").setLevel(Level.WARN);
            Logger.getRootLogger().getLoggerRepository().getLogger("com.ibatis.*").setLevel(Level.WARN);
            Logger.getRootLogger().getLoggerRepository().getLogger("java.sql.*").setLevel(Level.WARN);
        }		
    }
}


java - readLine

Programming/Java 2013.02.04 17:35 Posted by 파란크리스마스
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;

public class CommandExtractor {
	
	public static void main(String[] args) throws Exception {
		File file = new File(args[0]);
		if(file.exists())
		{
		    BufferedReader inFile = new BufferedReader(new InputStreamReader(new FileInputStream(file),"UTF-8"));
		    String sLine = null;
		    while( (sLine = inFile.readLine()) != null )
		    {
		    	if (sLine.indexOf("command") > 0) {
		    		System.out.println(sLine.substring(57));
		    	}
		    }
		}
	}
}




jstl

Programming/Java 2012.10.28 09:49 Posted by 파란크리스마스

출처 : Spring MVC Checkbox And Checkboxes Example

CodeData.java

public class CodeData {	
	private int itemValue;
	private String itemLabel;
	public CodeData(int itemValue, String itemLabel) {
		super();
		this.itemValue = itemValue;
		this.itemLabel = itemLabel;
	}
	public int getItemValue() {
		return itemValue;
	}
	public void setItemValue(int itemValue) {
		this.itemValue = itemValue;
	}
	public String getItemLabel() {
		return itemLabel;
	}
	public void setItemLabel(String itemLabel) {
		this.itemLabel = itemLabel;
	}	
}

라디오버튼

		List<CODEDATA> typeList = new ArrayList<CODEDATA>();
		typeList.add(new CodeData(1, "남자"));
		typeList.add(new CodeData(2, "여자"));
		modelMap.addObject("typeList", typeList);
<form:radiobuttons path="gender" items="${typeList}" itemValue="itemValue" itemLabel="itemLabel"/>

셀렉트박스

        <form:select path="template_id" style="width: 200px; display:none">
			<form:options items="${listTemplate}" itemLabel="name" itemValue="tid" />
		</form:select>

form action url

출처 : Spring MVC: Relative URL problems
<spring:url var = "action" value='/ruleManagement/save' ... />
<form:form action="${action}" method="post">

- end -

Tomcat / server.xml - Oracle Connection pool 설정

Programming/Java 2012.08.12 09:46 Posted by 파란크리스마스

Oracle Connection Pool

		<Resource auth="Container" 
              driverClassName="oracle.jdbc.driver.OracleDriver" 
              factory="org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory" 
              maxActive="100" 
              maxIdle="30" 
              maxWait="10000" 
              name="jdbc/testDS" 
              password="tiger" 
              type="javax.sql.DataSource" 
              url="jdbc:oracle:thin:@loclahost:1521:orcl" 
              username="scott"/>

Context 경로 추가

		<Context docBase="C:/workspace/images" path="images" reloadable="true"/>

URIEncoding

		<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" URIEncoding="UTF-8"/>

Spring 파일 업로드

Programming/Java 2012.07.31 15:44 Posted by 파란크리스마스

Spring Controller

@Controller
@RequestMapping(value = "/form/mfile_add")
public class CMXFileAddController {

	@RequestMapping(method = RequestMethod.GET)
	public String getUploadForm(Model model) {
		MFile mFile = new MFile ();
		model.addAttribute("mFile", mFile);
		return "/form/mfile_add";
	}

mfile_add.jsp

<form:form modelAttribute="mFile" method="post" enctype="multipart/form-data">

        <legend>자료 등록</legend>

        <table>
          <TR>
            <TD><form:label for="title" path="title">제목</form:label></TD>
            <TD><form:input path="title" type="text" size="85"/></TD>
          </TR>
          <TR>
            <TD><form:label for="file1" path="file1">파일1</form:label></TD>
            <TD><form:input path="file1" type="file" size="70"/></TD>
          </TR>
          <TR>
            <TD><form:label for="desc" path="desc">설명</form:label></TD>
            <TD><form:textarea path="desc" cols="84" rows="5" /></TD>
          </TR>
        </table>

        <input type="submit" value="등록"/>

</form:form>

Post 파일 업로드 처리

	@RequestMapping(method = RequestMethod.POST)
	public String create(MFile mFile, BindingResult result) {
		
		System.out.println(mFile);
		
		if (result.hasErrors()) {
			for (ObjectError error : result.getAllErrors()) {
				System.err.println("Error: " + error.getCode() + " - " + error.getDefaultMessage());
			}
			return "/form/mfile_add";
		}

		if (!mFile.getFile1().isEmpty()) {
			String filename = mFile.getFile1().getOriginalFilename();
			String imgExt = filename.substring(filename.lastIndexOf(".") + 1, filename.length());

			// upload 가능한 파일 타입 지정
			if (imgExt.equalsIgnoreCase("xls")) {
				byte[] bytes = mFile.getFile1().getBytes();
				try {
					File lOutFile = new File(fsResource.getPath() + filename  + "_temp.xls");
					FileOutputStream lFileOutputStream = new FileOutputStream(lOutFile);
					lFileOutputStream.write(bytes);
					lFileOutputStream.close();
				} catch (IOException ie) {
					// Exception 처리
					System.err.println("File writing error! ");
				}
				System.err.println("File upload success! ");
			} else {
				System.err.println("File type error! ");
			}
		
		}
		return "redirect:mfile_list.itg";
	}

 

JDBC 연결

Programming/Java 2012.06.24 10:08 Posted by 파란크리스마스

MySQL JDBC 연결

import java.sql.Connection;
import java.sql.DriverManager;

public class Test {
  public static void main(String[] args) throws Exception {
    Connection conn = null;
    try {
      Class.forName("org.gjt.mm.mysql.Driver"); 
      conn = DriverManager.getConnection("jdbc:mysql://localhost:5515/dbname?user=id&useUnicode=true&characterEncoding=UTF8", "id", "pw");
    } catch (Exception e) {
      e.printStackTrace();
      if (conn!=null) try { conn.close(); } catch (Exception e2) { }
    }
  }
}

Oracle thin

import java.sql.Connection;
import java.sql.DriverManager;

public class Test {
  public static void main(String[] args) throws Exception {
    Connection conn = null;
    try {
      Class.forName("oracle.jdbc.driver.OracleDriver"); 
      conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "scott", "tiger");
      
      System.out.println(conn);
      
    } catch (Exception e) {
      e.printStackTrace();
      if (conn!=null) try { conn.close(); } catch (Exception e2) { }
    }
  }
}

Oracle OCI

import java.sql.Connection;
import java.sql.DriverManager;

public class TestOCI {
  public static void main(String[] args) throws Exception {
    Connection conn = null;
    try {
      Class.forName("oracle.jdbc.driver.OracleDriver"); 
      conn = DriverManager.getConnection("jdbc:oracle:oci:@xe", "scott", "tiger");
      
      System.out.println(conn);
      
    } catch (Exception e) {
      e.printStackTrace();
      if (conn!=null) try { conn.close(); } catch (Exception e2) { }
    }
  }
}

Ubuntu 12.04 - Android NDK 설치

Programming/Java 2012.05.20 22:51 Posted by 파란크리스마스

출처 : http://inmist.tistory.com/entry/%EC%8A%A4%ED%81%AC%EB%9E%A9Android-NDK-%EC%82%AC%EC%9A%A9%EB%B2%95
http://www.kkaneko.com/rinkou/js/andk.html
http://darkryu.egloos.com/m/3299369

NDK 다운로드

http://developer.android.com/sdk/ndk/index.html

NDK 설치

cd 다운로드
tar xvjof android-ndk-r8-linux-x86.tar.bz2
mv android-ndk-r8 ~/dev

NDK 환경 설정

echo 'export ANDROID_NDK_ROOT=/home/user1/dev/android-ndk-r8' | tee -a ~/.bashrc
echo 'export ANDROID_SDK_ROOT=/home/user1/dev/android-sdks' | tee -a ~/.bashrc
echo 'export PATH=$PATH:$ANDROID_NDK_ROOT:$ANDROID_SDK_ROOT/tools:$ANDROID_SDK_ROOT/platform-tools' | tee -a ~/.bashrc

ToolChain 만들기

sudo ~/dev/android-ndk-r8/build/tools/make-standalone-toolchain.sh --ndk-dir=/home/user1/dev/android-ndk-r8 --platform=android-8 --install-dir=/opt/android-8-toolchain
sudo chown user1:user1 -hR /opt/android-8-toolchain

echo 'export TOOLCHAIN=/opt/android-8-toolchain' | tee -a ~/.bashrc
echo 'export PATH=$TOOLCHAIN/bin:$PATH' | tee -a ~/.bashrc
echo 'export CC=arm-linux-androideabi-gcc' | tee -a ~/.bashrc

cygwin (참조용)
./make-standalone-toolchain.sh --ndk-dir=/opt/android-ndk --platform=android-8 --install-dir=/opt/android-8-toolchain

NDK 테스트 빌드

cd ~/dev/android-ndk-r8/samples/hello-jni/jni
ndk-build

컴파일 확인

NDK Sample 만들기 

기본 Sample을 사용하는 것이라서 HelloJni 입력하고, [Next] 버튼 선택

Target SDK를 Android 2.1로 선택하고, [Next] 버튼 선택

Package Name : com.example.hellojni
Create Activity : HelloJni

HelloJni.java파일를 NDK Sample 폴더에서 복사하거나, 아래와 같이 입력 한다

package com.example.hellojni;

import android.app.Activity;
import android.widget.TextView;
import android.os.Bundle;


public class HelloJni extends Activity
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        /** 
         * Create a TextView and set its content.
         * the text is retrieved by calling a native
         * function.
         */
        TextView  tv = new TextView(this);
        tv.setText( stringFromJNI() );
        setContentView(tv);
    }

    /**
     * A native method that is implemented by the
     * 'hello-jni' native library, which is packaged
     * with this application.
     */
    public native String  stringFromJNI();

    /**
     * This is another native method declaration that is *not*
     * implemented by 'hello-jni'. This is simply to show that
     * you can declare as many native methods in your Java code
     * as you want, their implementation is searched in the
     * currently loaded native libraries only the first time
     * you call them.
     *
     * Trying to call this function will result in a
     * java.lang.UnsatisfiedLinkError exception !
     */
    public native String  unimplementedStringFromJNI();

    /**
     * this is used to load the 'hello-jni' library on application
     * startup. The library has already been unpacked into
     * /data/data/com.example.HelloJni/lib/libhello-jni.so at
     * installation time by the package manager.
     */
    static {
        System.loadLibrary("hello-jni");
    }
}

jni 폴더를 만들고, Android.mk, hello-jni.c NDK Sample 폴더에서 복사하거나, 아래와 같이 입력 한다.

Android.mk 파일

# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := hello-jni
LOCAL_SRC_FILES := hello-jni.c

include $(BUILD_SHARED_LIBRARY)

hello-jni.c 파일

/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
#include 
#include 

/* This is a trivial JNI example where we use a native method
 * to return a new VM String. See the corresponding Java source
 * file located at:
 *
 *   apps/samples/hello-jni/project/src/com/example/HelloJni/HelloJni.java
 */
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                                  jobject thiz )
{
    return (*env)->NewStringUTF(env, "Hello from JNI !");
}

NDK 빌드

cd ~/dev/workspace/HelloJni/jni
ndk-build

HelloJni 프로젝트를 refresh 해보면 libs/armeabi/libhello-jni.so 파일이 생성 된것을 확인 할 수 있다. 

실행

Tomcat + Spring + ActiveMQ

Programming/Java 2012.01.29 03:56 Posted by 파란크리스마스
출처 : http://dbin318.tistory.com/13

웹페이지 호출 후 오래 걸리는 작업을 실행하는 경우 응답을 바로 할 수 없어서
MQ 시스템을 적용하게 되었습니다.

MQ(Message Queue) 시스템은
Message를 Queue에 전달하고, MQ시스템은 다시 Queue에서 Message을 받아서
Message을 실행하는 것으로, 시스템에서 처리 가능한 용량 만큼만 Queue에 Message을 받아서
처리 하게 됩니다.

부하가 많이 걸리는 SMS 시스템과 같은 시스템에 적용하게 됩니다.

저의 경우는 부하가 많이 걸리는 작업은 아니지만
특정 작업이 1시간 이상 걸리는 작업을 웹페이지에서 호출하는데,
호출후 바로 응답을 받을 수 없는 문제로 MQ 시스템을 적용하게 되었습니다.
(Message을 Queue에 전달하고 바로 응답 페이지를 보여줄 수 있기때문에...비동기식 호출이 가능)

자세한 설명은 출처 페이지에서 보실수 있습니다.

적용환경

Tomcat 7
Spring 3.0.4
ActiveMQ 5.4.3

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

<beans 
  xmlns="http://www.springframework.org/schema/beans" 
  xmlns:amq="http://activemq.apache.org/schema/core"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
  http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">

	<!-- a pooling based JMS provider -->
	<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
		<property name="brokerURL">
			<value>vm://localhost</value>
		</property>
	</bean>

	<bean id="jmsFactory" class="org.apache.activemq.pool.PooledConnectionFactory"
		destroy-method="stop">
		<property name="connectionFactory" ref="connectionFactory" />
	</bean>

	<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
		<constructor-arg value="dbin.queue" />
	</bean>

	<bean id="msgConverter" class="test.dbin.MsgConverterImpl" />
	<bean id="msgMdp" class="test.dbin.MsgMDP" />

	<bean id="purePojoMdp"
		class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
		<property name="delegate" ref="msgMdp" />
		<property name="defaultListenerMethod" value="handleMessage" />
		<property name="messageConverter" ref="msgConverter" />
	</bean>
	
	<bean class="org.springframework.jms.listener.SimpleMessageListenerContainer">
		<property name="connectionFactory" ref="jmsFactory" />
		<property name="destination" ref="queueDestination" />
		<property name="messageListener" ref="purePojoMdp" />
	</bean>

	<!-- Spring JMS Template -->
	<bean id="producerJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
		<property name="connectionFactory" ref="jmsFactory" />
		<property name="defaultDestination" ref="queueDestination" />
		<property name="messageConverter" ref="msgConverter" />
	</bean>

	<bean id="producer" class="test.dbin.MsgProducerImpl">
		<property name="jmsTemplate" ref="producerJmsTemplate" />
	</bean>
</beans>

Msg.java
package test.dbin;

public class Msg {

	private String name;
	private String value;

	public void setName(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public String getValue() {
		return value;
	}

	public String toString() {
		return "name = " + name + ", value = " + value;
	}

}

MsgProducer.java
package test.dbin;

import org.springframework.jms.core.JmsTemplate;

public interface MsgProducer {
 
	public void send(final Msg map);
 
	public void setJmsTemplate(JmsTemplate jmsTemplate);
 
}

MsgProducerImpl.java
package test.dbin;

import org.springframework.jms.core.JmsTemplate;

public class MsgProducerImpl implements MsgProducer {

	private JmsTemplate jmsTemplate;
 
	public void setJmsTemplate(JmsTemplate jmsTemplate) {
 		this.jmsTemplate = jmsTemplate;
 	}
	
	public void send(final Msg msg) {		
 		jmsTemplate.convertAndSend(msg);
 	}	
 
}

MsgMDP.java
package test.dbin;

/**
 * Message Driven POJO
 *
 */
public class MsgMDP {
 
	public void handleMessage(Msg msg) {
		// handles the message
		System.out.println("handler called");
		System.out.println(msg);
	}
 
}

MsgConverterImpl.java
package test.dbin;
 
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.Session;

import org.springframework.jms.support.converter.MessageConversionException;
import org.springframework.jms.support.converter.MessageConverter;

/**
 * MapMessage로의 conversion을 담당하는 class
 * 
 *
 */
public class MsgConverterImpl implements MessageConverter {

	public MsgConverterImpl() {

	}

	public Object fromMessage(Message message) throws JMSException, MessageConversionException {
		if( !(message instanceof MapMessage)) {
			throw new MessageConversionException("not MapMessage");
		}
		
		System.out.println("MsgConverterImpl.fromMessage");
		
		MapMessage mapMessage = (MapMessage)message;
		Msg msg = new Msg();
		msg.setName(mapMessage.getString("name"));
		msg.setValue(mapMessage.getString("value"));

		return msg;
	}

	public Message toMessage(Object object, Session session)  throws JMSException, MessageConversionException {
		if ( !(object instanceof Msg) ) {
			throw new MessageConversionException("not Msg");
		}
		
		System.out.println("MsgConverterImpl.toMessage");
		
		Msg msg = (Msg)object;
		MapMessage mapMessage = session.createMapMessage();

		mapMessage.setString("name", msg.getName());
		mapMessage.setString("value", msg.getValue());
		
		return mapMessage;
	}
}

MQController.java
  @Override
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
		
		Msg msg = new Msg();
		msg.setName("daniel yoon");
		msg.setValue("lullaby");
 		
		// 전송 
		MsgProducer producer = (MsgProducer)BeanUtils.getBean("producer");
		producer.send(msg);
		System.out.println(msg + " sent");
		
		
		ModelAndView mv = new ModelAndView();
		mv.setViewName("/index");

		return mv;
	}
실행결과

MsgConverterImpl.toMessage
MsgConverterImpl.fromMessage
handler called
name = daniel yoon, value = lullaby
name = daniel yoon, value = lullaby sent