Find class in jar files

Posted at 2018. 2. 19. 09:32 | Posted in Java+
반응형

linux 에서

- jar 파일 안에 들어있는 class 를 찾는 명령어이다.

- 원하는 class 가 들어있는 jar 파일을 찾는 명령어이다.


$ find foo/ -name "*.jar" | xargs grep Hello.class


https://www.google.co.kr/search?q=linux+find+class+in+jar

https://stackoverflow.com/questions/14373788/linux-cmd-to-search-for-a-class-file-among-jars-irrespective-of-jar-path

반응형

'Java+' 카테고리의 다른 글

web.xml 서블릿 버전별 DTD  (1) 2013.03.03
Maven Repository for Oracle Library  (0) 2012.12.18
<jsp:forward page="url" /><jsp:include /> <%@ include %>  (0) 2010.04.25
TortoiseSVN 사용하기  (2) 2009.11.16
썸네일(Thumbnail) 만들기  (1) 2009.08.09
Java2Html  (0) 2009.07.19
Jad + JadClipse  (6) 2009.07.11
Java with SQLite  (1) 2009.06.29
Java Database Connectivity  (0) 2009.02.25
//
반응형

https://github.com/antop-dev/example/tree/master/mybatis-rowbounds-example

 

Mybatis에 RowBounds 클래스를 이용해서 페이징 처리를 할 수 있다.

package org.antop.mybatis.mapper;
import org.antop.mybatis.model.Employee;
import org.apache.ibatis.session.RowBounds;
import java.util.List;

public interface EmployeeMapper {
	List<Employee> select(RowBounds rowBounds);
}

 

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.antop.mybatis.mapper.EmployeeMapper">
	<resultMap id="BaseResultMap" type="org.antop.mybatis.model.Employee">
    	<id property="no" column="emp_no" />
        <result property="gender" column="gender" typeHandler="org.antop.mybatis.handler.GenderTypeHandler" />
        <association property="name" javaType="org.antop.mybatis.model.Name">
        	<result property="first" column="first_name" />
            <result property="last" column="last_name" />
		</association>
	</resultMap>
    
    <select id="select" resultMap="BaseResultMap">
    	select
        	*
		from
        	employees
		order by
        	emp_no asc
	</select>
</mapper>

 

위와 같이 맵퍼와 XML 이 있다.

RowBounds rowBounds = new RowBounds(5, 10);
// 15건을 가져와서 앞에 5건 건너띔
List select = mapper.select(rowBounds);

결과는 10건이 나왔지만 어떻게 동작할까?

여기저기 찾아보고 소스도 대충(?) 보면 offset + limit 만큼 가져와서 offset 만큼 건너띤다.

페이징이 뒤로 갈 수록 느려지게 된다.

RowBounds rowBounds = new RowBounds(29990, 10);
// 30000건을 가져와서 앞에 29990건 건너띔
List select = mapper.select(rowBounds);

데이터의 양이 적다면 쿼리에서 페이징을 하지 않고 RowBouns를 이용하면 빠르게 개발할 수 있을 것이다.

하긴 요즘 수천만건의 데이터를 페이징에서 마지막 페이지를 볼 일이 많을까? -_-/

 

XML 쿼리문에 페이징을 넣지 않고 RowBounds 클래스를 사용하면 자동으로 페이징 쿼리가 실행되게 할 수 없을까?

방법이 있다! Mybatis Intercepter를 이용하면 된다. (인터셉터의 자세한 사용법은 다루지 않겠다 ㅠㅠ)

  1. Mybatis에서 쿼리를 날리기 전에 가로챈다.
  2. RowBounds가 있으면 쿼리에 페이징 문장를 적용한다.
  3. RowBounds를 제거하여 Mybatis에서 페이징 처리를 하지 않도록 한다.

아래 소스는 쿼리에 MySQL용으로 limit 문을 붙여준다.

package org.antop.mybatis.intercepter;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.ReflectorFactory;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.Connection;
import java.util.Properties;

@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class MysqlRowBoundsInterceptor implements Interceptor {
	private static final Logger logger = LoggerFactory.getLogger(MysqlRowBoundsInterceptor.class);
    private static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();
    private static final ObjectWrapperFactory DEFAULT_OBJECT_WRAPPER_FACTORY = new DefaultObjectWrapperFactory();
    private static final ReflectorFactory DEFAULT_REFLECTOR_FACTORY = new DefaultReflectorFactory();
    
    public Object intercept(Invocation invocation) throws Throwable {
    	StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        MetaObject metaStatementHandler = MetaObject.forObject(statementHandler, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY, DEFAULT_REFLECTOR_FACTORY);
        String originalSql = (String) metaStatementHandler.getValue("delegate.boundSql.sql");
        RowBounds rb = (RowBounds) metaStatementHandler.getValue("delegate.rowBounds");
        logger.debug("originalSql = {}", originalSql);
        logger.debug("RowBounds = {}", rb);
        if (rb == null || rb == RowBounds.DEFAULT) { // RowBounds가 없으면 그냥 실행
        	return invocation.proceed();
		}
        
        // RowBounds가 있다!
        // 원래 쿼리에 limit 문을 붙여준다.
        StringBuffer sb = new StringBuffer();
        sb.append(originalSql);
        sb.append(" limit ");
        sb.append(rb.getOffset());
        sb.append(", ");
        sb.append(rb.getLimit());
        
        logger.debug("sql = {}", sb.toString());
        // RowBounds 정보 제거
        metaStatementHandler.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET);
        metaStatementHandler.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT);
        // 변경된 쿼리로 바꿔치기
        metaStatementHandler.setValue("delegate.boundSql.sql", sb.toString());
        
        return invocation.proceed();
	}
    
    public Object plugin(Object target) {
    	return Plugin.wrap(target, this);
	}
    
    public void setProperties(Properties properties) {
    }
    
}

SqlSessionFactory 설정하는 부분에 인터셉터를 적용하면 된다.

 

<?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:mybatis="http://mybatis.org/schema/mybatis-spring"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd">
	
    <mybatis:scan base-package="org.antop.mybatis"/>
    
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    	<property name="dataSource" ref="dataSource"/>
        <property name="mapperLocations" value="classpath*:mybatis/*.xml"/>
        <property name="plugins">
        	<list>
            	<!-- 인터셉터 설정 -->
                <bean class="org.antop.mybatis.intercepter.MysqlRowBoundsInterceptor"/>
			</list>
		</property>
	</bean>
    
    <bean id="dataSource" ... />
</beans>

 

실행시켜 보면 쿼리문에 페이징이 적용되서 쿼리가 날라가는 것을 확인할 수 있다.

 

select * from employees order by emp_no asc limit 29990, 10

 

 

출처

http://www.programering.com/a/MTM5gTNwATQ.html

http://hjw1456.tistory.com/10

반응형
//

Installing Hadoop 1 on Ubuntu 14.04

Posted at 2015. 11. 12. 03:37 | Posted in Study/Hadoop
반응형

Introduction


시작하세요! 하둡 프로그래밍
국내도서
저자 : 정재화
출판 : 위키북스 2014.12.31
상세보기


거침없이 배우는 하둡
국내도서
저자 : 척 램(Chuck Lam) / 강택현,이현남역
출판 : 지앤선(지&선) 2012.07.17
상세보기


하둡을 공부하기 위하여 설치해보자.


연습을 실전 같이! 완전분산(Fully distributed) 모드로 설치한다.


 호스트

 아이피

 역할

 코어/메모리

 hadoop-01

 192.168.153.10

 NameNode

 1 코어 / 1 GB

 hadoop-02

 192.168.153.11

 Secondary NameNode / DataNooe

 1 코어 / 1 GB

 hadoop-03

 192.168.153.12

 DataNode 1 코어 / 1 GB

 hadoop-04

 192.168.153.xxx DataNode 1 코어 / 1 GB




하둡 실행 계정 생성


하둡 실행 계정은 하둡 클러스터를 구성하는 모든 서버에 동일하게 생성해야 한단다. (정말? 실화야?)


"hadoop" 계정을 사용하도록하겠다. 각 서버에 생성하자.


root@hadoop-01:~# adduser hadoop

root@hadoop-02:~# adduser hadoop

root@hadoop-03:~# adduser hadoop




호스트 파일 수정


IP를 직접 사용해도 되지만 호스트명을 사용하자. 각 서버에서 /etc/hosts 파일을 아래와 같이 수정한다.


※ 물론 이 작업을 수행하는 나의 컴퓨터에도 호스트 파일 수정 작업이 되어 있어야 한다.


root@hadoop-01:~# vi /etc/hosts


127.0.0.1       localhost

192.168.153.10  hadoop-01

192.168.153.11  hadoop-02

192.168.153.12  hadoop-03


root@hadoop-02:~# vi /etc/hosts

root@hadoop-03:~# vi /etc/hosts




인코딩 방식 설정


하둡은 인코딩 방식으로 UTF-8을 사용한단다... 다행이 우분투는 기본적으로 UTF-8 사용해서 천만 다행 -_-/




방화벽 해제


어차피 내부통신에다 연습용이니 다 해제!


root@hadoop-01:~# ufw disable

root@hadoop-02:~# ufw disable

root@hadoop-03:~# ufw disable




자바 설치


Oracle JDK 1.7 을 설치 하도록 하겠다.


http://ubuntuhandbook.org/index.php/2014/02/install-oracle-java-6-7-or-8-ubuntu-14-04/


Oracle JDK 7 을 설치 했을 시에 설치되는 위치는 "/usr/lib/jvm/java-7-oracle" 이다.




하둡 클러스터를 위한 SSH 설정


마스터 노드는 클러스터에 위치한 다른 모든 노드들에 접근할 수 있어야 한다. 하둡은 이러한 접근을 위해 SSH를 사용한다.


마스터 노드(hadoop-01)에서 쌍으로 이루어진 SSH 키를 생성한다.


hadoop@hadoop-01:~$ pwd

/home/hadoop


hadoop@hadoop-01:~$ ssh-keygen -t rsa

Generating public/private rsa key pair.
Enter file in which to save the key (/home/hadoop/.ssh/id_rsa): [Enter]
Created directory '/home/hadoop/.ssh'.
Enter passphrase (empty for no passphrase): [Enter]
Enter same passphrase again: [Enter]
Your identification has been saved in /home/hadoop/.ssh/id_rsa.
Your public key has been saved in /home/hadoop/.ssh/id_rsa.pub.
The key fingerprint is:
c5:f5:5b:3a:83:13:1b:9b:07:2c:dc:11:34:3d:a9:41 hadoop@hadoop-01
The key's randomart image is:
...


생성된 공개키를 다른 서버에 복사한다.


ssh-copy-id -i [복사할 공개키 경로] [대상 서버 계정]@[대상 서버]


hadoop@hadoop-01:~$ ssh-copy-id -i /home/hadoop/.ssh/id_rsa.pub hadoop@hadoop-02

The authenticity of host 'hadoop-02 (192.168.153.11)' can't be established.

ECDSA key fingerprint is 28:1a:ab:fa:2d:a8:e0:c8:5b:ef:f7:ff:74:69:45:96.

Are you sure you want to continue connecting (yes/no)? yes

/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed

/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys

hadoop@hadoop-02's password: [SSH 비밀번호 입력]


Number of key(s) added: 1


Now try logging into the machine, with:   "ssh 'hadoop@hadoop-02'"

and check to make sure that only the key(s) you wanted were added.


hadoop@hadoop-01:~$ ssh-copy-id -i /home/hadoop/.ssh/id_rsa.pub hadoop@hadoop-03

hadoop@hadoop-01:~$ ssh-copy-id -i /home/hadoop/.ssh/id_rsa.pub hadoop@hadoop-01




하둡 다운로드 및 압축 해제


현재 최신 버전은 1.2.1 이다.


hadoop@hadoop-01:~$ pwd

/home/hadoop


hadoop@hadoop-01:~$ wget https://archive.apache.org/dist/hadoop/common/hadoop-1.2.1/hadoop-1.2.1.tar.gz


압축 해제!


hadoop@hadoop-01:~$ tar xvfz hadoop-1.2.1.tar.gz




hadoop-env 수정


이것 저것....


hadoop@hadoop-01:~/hadoop-1.2.1/conf$ pwd

/home/hadoop/hadoop-1.2.1/conf


hadoop@hadoop-01:~/hadoop-1.2.1/conf$ vi hadoop-env.sh


# The java implementation to use.  Required.

# 현재 우분투 14에 Oracle JDK 7을 설치하면 아래와 같은 경로에 설치된다.

export JAVA_HOME=/usr/lib/jvm/java-7-oracle


# The maximum amount of heap to use, in MB. Default is 1000.

export HADOOP_HEAPSIZE=768


# The directory where pid files are stored. /tmp by default.
# NOTE: this should be set to a directory that can only be written to by
#       the users that are going to run the hadoop daemons.  Otherwise there is
#       the potential for a symlink attack.
export HADOOP_PID_DIR=/home/hadoop/hadoop-1.2.1/pids




masters 수정


masters 파일에는 보조네임 노드를 실행할 서버를 설정한다. (여러개 가능)


hadoop@hadoop-01:~/hadoop-1.2.1/conf$ vi masters


hadoop-02




slaves 수정


slaves 파일에는 데이터 노드를 실행할 서버를 설정한다.


hadoop@hadoop-01:~/hadoop-1.2.1/conf$ vi slaves


hadoop-02

hadoop-03




core-site.xml 수정


이것 저것... ㅠㅠ


hadoop@hadoop-01:~/hadoop-1.2.1/conf$ vi core-site.xml


<?xml version="1.0"?>

<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>


<!-- Put site-specific property overrides in this file. -->

<configuration>

        <property>

                <name>fs.default.name</name>

                <value>hdfs://hadoop-01:9000</value>

        </property>

        <property>

                <name>hadoop.tmp.dir</name>

                <value>/home/hadoop/hadoop-data</value>

        </property>

</configuration>




hdfs-site.xml 수정


...


hadoop@hadoop-01:~/hadoop-1.2.1/conf$ vi hdfs-site.xml


<?xml version="1.0"?>

<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>


<!-- Put site-specific property overrides in this file. -->

<configuration>

        <property>

                <name>dfs.replication</name>

                <value>3</value>

        </property>

        <property>

                <name>dfs.http.address</name>

                <value>hadoop-01:50070</value>

        </property>

        <property>

                <name>dfs.secondary.http.address</name>

                <value>hadoop-02:50090</value>

        </property>

</configuration>




mapred-site.xml 수정


..


hadoop@hadoop-01:~/hadoop-1.2.1/conf$ vi mapred-site.xml


<?xml version="1.0"?>

<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>


<!-- Put site-specific property overrides in this file. -->

<configuration>

        <property>

                <name>mapred.job.tracker</name>

                <value>hadoop-01:9001</value>

        </property>

</configuration>




하둡 환경설정 복사


네임노드에서 모든 수정 작업이 완료되면 다른 데이터노드 서버로 파일을 복사한다.


hadoop@hadoop-01:~$ cd ~

hadoop@hadoop-01:~$ tar zcvf hadoop.tar.gz hadoop-1.2.1

hadoop@hadoop-01:~$ scp hadoop.tar.gz hadoop@hadoop-02:/home/hadoop

hadoop@hadoop-01:~$ scp hadoop.tar.gz hadoop@hadoop-03:/home/hadoop


각각 서버로 전송된 파일 압축 해제


hadoop@hadoop-02:~$ tar xvfz hadoop.tar.gz

hadoop@hadoop-03:~$ tar xvfz hadoop.tar.gz




하둡 실행


네임노드를 초기화한다.


hadoop@hadoop-01:~/hadoop-1.2.1/bin$ ./hadoop namenode -format


INFO namenode.NameNode: STARTUP_MSG: /************************************************************ STARTUP_MSG: Starting NameNode STARTUP_MSG: host = hadoop-01/192.168.153.10 STARTUP_MSG: args = [-format] STARTUP_MSG: version = 1.2.1 STARTUP_MSG: build = https://svn.apache.org/repos/asf/hadoop/common/branches/branch-1.2 -r 1503152; compiled by 'mattf' on ... STARTUP_MSG: java = 1.7.0_80 ************************************************************/ INFO util.GSet: Computing capacity for map BlocksMap INFO util.GSet: VM type = 64-bit INFO util.GSet: 2.0% max memory = 778502144 INFO util.GSet: capacity = 2^21 = 2097152 entries INFO util.GSet: recommended=2097152, actual=2097152 INFO namenode.FSNamesystem: fsOwner=hadoop INFO namenode.FSNamesystem: supergroup=supergroup INFO namenode.FSNamesystem: isPermissionEnabled=true INFO namenode.FSNamesystem: dfs.block.invalidate.limit=100 INFO namenode.FSNamesystem: isAccessTokenEnabled=false accessKeyUpdateInterval=0 min(s), accessTokenLifetime=0 min(s) INFO namenode.FSEditLog: dfs.namenode.edits.toleration.length = 0 INFO namenode.NameNode: Caching file names occuring more than 10 times INFO common.Storage: Image file /home/hadoop/hadoop-data/dfs/name/current/fsimage of size 112 bytes saved in 0 seconds. INFO namenode.FSEditLog: closing edit log: position=4, editlog=/home/hadoop/hadoop-data/dfs/name/current/edits INFO namenode.FSEditLog: close success: truncate to 4, editlog=/home/hadoop/hadoop-data/dfs/name/current/edits INFO common.Storage: Storage directory /home/hadoop/hadoop-data/dfs/name has been successfully formatted. INFO namenode.NameNode: SHUTDOWN_MSG: /************************************************************ SHUTDOWN_MSG: Shutting down NameNode at hadoop-01/192.168.153.10 ************************************************************/


전부 실행


hadoop@hadoop-01:~/hadoop-1.2.1/bin$ ./start-all.sh


starting namenode, logging to /home/hadoop/hadoop-1.2.1/libexec/../logs/hadoop-hadoop-namenode-hadoop-01.out hadoop-03: starting datanode, logging to /home/hadoop/hadoop-1.2.1/libexec/../logs/hadoop-hadoop-datanode-hadoop-03.out hadoop-02: starting datanode, logging to /home/hadoop/hadoop-1.2.1/libexec/../logs/hadoop-hadoop-datanode-hadoop-02.out hadoop-01: starting secondarynamenode, logging to /home/hadoop/hadoop-1.2.1/libexec/../logs/hadoop-hadoop-secondarynamenode-hadoop-01.out starting jobtracker, logging to /home/hadoop/hadoop-1.2.1/libexec/../logs/hadoop-hadoop-jobtracker-hadoop-01.out hadoop-03: starting tasktracker, logging to /home/hadoop/hadoop-1.2.1/libexec/../logs/hadoop-hadoop-tasktracker-hadoop-03.out hadoop-02: starting tasktracker, logging to /home/hadoop/hadoop-1.2.1/libexec/../logs/hadoop-hadoop-tasktracker-hadoop-02.out




제대로 올라갔는지 확인하자


hadoop@hadoop-01:~$ jps

3050 JobTracker

2730 NameNode


hadoop@hadoop-02:~$ jps

3067 SecondaryNameNode

2951 DataNode

3190 TaskTracker


hadoop@hadoop-03:~$ jps

3087 TaskTracker

2949 DataNode


http://hadoop-01:50070




반응형

'Study > Hadoop' 카테고리의 다른 글

Install Ambari and Deploy HDP in CentOS  (1) 2016.06.05
Installing Hive(Hadoop 1) + MySQL on CentOS 6.7  (0) 2016.01.05
//

현지어로 언어명 보여주기

Posted at 2014. 2. 9. 15:34 | Posted in Java+/Example
반응형

Introduction


다국어를 지원하는 홈페이지에서 언어 선택하는 부분을 보면 대표하는 언어로 다국어명이 나오는 것을 볼 수 있다.



이거 따라해 보자 -_-;;




Locale 에서 getDisplayCountry() 뽑아낼 때 인자로 현재 Locale 을 넣어주면 자신의 Locale 언어 그대로 나온다.


for (Locale locale : Locale.getAvailableLocales()) { if (locale.getCountry().isEmpty() == false) { System.out.println("--"); System.out.println(locale.getCountry()); // 이거 System.out.println(locale.getDisplayCountry(locale)); } }


그리고 다국어 처리를 하려면 View 부분이 UTF-8 이어야 한다. 당연한건가? -_-;




Sample


locale.war


↑ 소스 포함 WAR 파일


locale.zip


↑ 메이븐 프로젝트 파일


Spring MVC 의 인터셉터 부분에서 Locale 부분을 처리하여 ModelAndView 에 넣어주는 방식으로 해봤다.



실행해 보면 아래와 같이 나온다.





반응형

'Java+ > Example' 카테고리의 다른 글

LOGBack Configurator with JMX  (0) 2014.07.20
2014년 도로명 주소 사용에 따른 우편번호 준비  (2) 2013.12.22
JSTL Custom Tag using Spring Beans  (0) 2013.12.01
Spring Message Source from Database  (1) 2013.03.03
Infinite Routing DataSource  (1) 2013.01.13
Mybatis Type Handler  (1) 2012.09.30
Using AUTO_INCREMENT keys  (0) 2011.03.01
//

Image Pyramid

Posted at 2014. 1. 30. 03:28 | Posted in Mini Project
반응형

Introduction


아주 오래 전 플렉스와 실버라이트가 난리를 쳤을 때 난 플렉스를 공부 했었다.


그 때 훈스닷넷에서 하는 실버라이트 세미나를 갔었는데(왜 플랙스 세미나를 안가고...) 그 때 발표자(?)가 발표를 했던게 실버라이트의 이미지 피라미드였다.


그 때.. 난 "아 참 조쿠나~" 라고 생각 해놨다가 꽤 오랜 시간이 지난 지금 생각이 났다. ㅋㅋㅋ




Fundamental


고용량의 큰 이미지가 있다. 이 이미지를 브라우저에서 본다고 하자.


그러면 실제로 화면에 보여지는 이미지의 영역은 얼마 안될 것이다.



하지만 큰 이미지를 한번에 가져오기 때문에 네트워크 낭비가 심하다.


이 문제를 해결하기 위해서 이미지를 잘게 자른 후 화면(브라우저)에 보이는 영역만 불러오는 것이다!



이것 저것 찾아보니까 이미지 피라미드에 대한 문서들이 있었다. 


Web Map Tile Services for Spatial Data.pdf


Pyramid methods in image processing.pdf



이미지 저장 시에 참고한 그림는 아래와 같다. 아래 그림에 영감을 받아서 만들어 보았다.





Project

 

데모 : http://antop.nerv.kr/image.pyramid/



데이터베이스가 서버에는 MySQL이고, 샘플은 Derby 이다.


pyramid.txp


01


이 ERD가 자바에서는 아래 그림과 같이 클래스 구조를 가진다. ORM!





jQuery Plugin


이미지를 저장하는 부분보다 보여주는 부분이 더 개발 비율이 많다. 화면에 보여주는데 사용한 제이쿼리 플러그인은 아래와 같다.


jQuery Form Plugin - AJAX 로 폼 전송이나 파일 업로드를 할 수 있는 플러그인


jQuery Upload File - jQuery Form Plugin 을 이용하여 파일 업로드를 하는데 상태바를 지원해준다.


jQuery Mouse Wheel Plugin - 마우스 휠이 굴러가는 이벤트를 감지할 수 있게 해준다.


jQuery Schedule - 스케쥴링을 가능하게 하는 해준다. (Quartz 같은거...)


jQuery Dragscrollable (jQuery 홈페이지 개편되면서 플러그인 링크 죽음) - 마우스를 끌면 화면을 스크롤 해줌.


perfect-scrollbar : 가상 스크롤바를 달아준다.


Element Onscreen Visibility - 선택한 태그(selector)가 화면에 보이고 있는 태그인지를 판별한다.




이제 힘들어서 못쓰겠네 후.... 알아서 ㄱㄱ 질문은 받음 -_-/


image.pyramid.src.zip


↑ 이클립스 프로젝트 소스 파일 (메이븐)


image.pyramid.war.zip.001


image.pyramid.war.zip.002


↑ WAR 파일 (7-zip 분할)


반응형

'Mini Project' 카테고리의 다른 글

Proftpd Manager  (0) 2012.12.10
게시판 2.0  (5) 2011.07.27
Sudoku  (0) 2011.06.09
간단한 JAVA 실행기(?)  (1) 2011.03.21
Forecast Repository  (8) 2010.11.30
Sales History API  (2) 2010.05.27
Order Entry API  (0) 2010.05.13
Human Resources API  (0) 2010.05.10
게시판 1.0  (1) 2010.03.11
비밀번호 생성기(Generate Password)  (1) 2010.02.10
//

"트리 메뉴 구성" 의뢰

Posted at 2014. 1. 23. 03:00 | Posted in Request Sample
반응형

Request


아래와 같은 트리 메뉴를 구성할 데이터가 들어있는 테이블이 있습니다.



path 칼럼에 상위 트리의 경로가 "/" 구분자로 들어 있습니다.


예를 들어 id가 7인 노드는 [루트 → 3 → 4 → 7] 의 경로를 가지게 됩니다.


이렇게 데이터가 들어있는 테이블을 조회해서 ul 과 li 태그의 조합으로 화면에 나타내고 싶습니다.


트리 깊이(depth)는 제한이 없습니다.


데이터베이스는 MySQL, 프레임워크는 Spring + iBatis를 사용합니다.




Response


재귀함수/재귀쿼리를 써야 한다.


MySQL 에는 기본적으로 재귀쿼리가 안된단다. -_-;


나 역시도 특정 데이터베이스에서만 있는 문법을 싫어하기 때문에 있어도 안쓸 생각이었다!


단순 select 쿼리로 아래 클래스에 만족하는 계층 클래스 구조를 만들었다.



iBatis는 MyBatis 처럼 <collection>에서 재귀 효과를 낼 수 없기 때문에 다른 곳(Service 영역)에서 이 역할을 해주었다.


아래 그림에서 PathTreeService 클래스의 findChildren() 메소드가 계속 재호출되는 부분이다.



또 이 재귀 부분이 쓰이는 부분은 화면에 <ul>과 <li>를 이용해서 출력하는 부분(JSTL Custom Tag)에서 쓰인다.


PathTreeTag 클래스의 printChildren() 메소드가 계속 재호출 되는 부분이다.



Spring + iBatis + HSQL 을 이용해 만든 샘플이다.


pathtree.war


↑ java 소스 포함 WAR 파일


pathtree.zip


↑ maven 프로젝트


아래와 같은 결과가 나오게 된다.




반응형
//

MySql Password Encoder

Posted at 2013. 9. 21. 19:24 | Posted in Framework/Spring Security
반응형
개인적으로 자주 사용하는 Spring Security Password Encoder 입니다.

MySql 의 password() 펑션 알고리즘 사용합니다.

import java.security.GeneralSecurityException; import java.security.MessageDigest; import org.springframework.security.crypto.password.PasswordEncoder; public class MySqlPasswordEncoder implements PasswordEncoder { @Override public String encode(CharSequence rawPassword) { if (rawPassword == null) { throw new NullPointerException(); } byte[] bpara = new byte[rawPassword.length()]; byte[] rethash; int i; for (i = 0; i < rawPassword.length(); i++) bpara[i] = (byte) (rawPassword.charAt(i) & 0xff); try { MessageDigest sha1er = MessageDigest.getInstance("SHA1"); rethash = sha1er.digest(bpara); // stage1 rethash = sha1er.digest(rethash); // stage2 } catch (GeneralSecurityException e) { throw new RuntimeException(e); } StringBuffer r = new StringBuffer(41); r.append("*"); for (i = 0; i < rethash.length; i++) { String x = Integer.toHexString(rethash[i] & 0xff).toUpperCase(); if (x.length() < 2) r.append("0"); r.append(x); } return r.toString(); } @Override public boolean matches(CharSequence rawPassword, String encodedPassword) { if (encodedPassword == null || rawPassword == null) { return false; } if (!encodedPassword.equals(encode(rawPassword))) { return false; } return true; } }


적용 예시..

	<security:authentication-manager alias="authenticationManager">
		<security:authentication-provider user-service-ref="userService">
			<security:password-encoder ref="passwordEncoder" />
		</security:authentication-provider>
	</security:authentication-manager>

	<bean id="passwordEncoder" class="MySqlPasswordEncoder">


반응형

'Framework > Spring Security' 카테고리의 다른 글

AJAX Login with Spring Security  (7) 2013.12.12
Spring Security Session Destroy  (4) 2013.10.27
//

Spring Message Source from Database

Posted at 2013. 3. 3. 05:19 | Posted in Java+/Example
반응형

스프링을 이용한 다국어 처리를 데이터베이스를 이용해 어떻게 할까 이것저것 고민하다가 구현해 봤습니다.


개발 환경

 - Eclipse Indigo + Maven Integration (Sonatype, Inc.)

 - WebLogic 12c (Tomcat 7)


테이블은 아래와 같이 구성하였습니다.




특별한 것은 없고 여느 책에서나 나오는 스프링에서 MessageSource를 사용하여 다국어 메세지를 가져오는데 AbstractMessageSource 클래스를 상속 받아 따로 클래스를 만들어 봤습니다. (com.tistory.antop.framework.support.DatabaseMessageResource)




구동해 볼 수 있는 샘플을 만들어 봤습니다.


실제 메세지 리소스 부분만 구현하는 시간은 금방인데 하나의 완성품을 만들면서 더 많이 배우는군요~


Spring Framework 3.2.1

Mybatis 3.2 + Ehcache 2.6.3

Tiles 2.2.2 + Dynamic Tiles 1.2.1

HSQLDB 2.2.9

 

http://antop.nerv.kr/multi-lang/

 

데이터를 제외한 모든 부분을 다국어 처리 해봤습니다영어(기본), 한국어, 일어 데이터를 만들어 놨습니다. 구글 번역!


언어를 한글로 했을 때의 화면입니다.




아래는 언어를 영문으로 했을 때




자바스크립트 메세지 부분도 다국어 처리 해봤습니다. (/js/locale.js)






이클립스 프로젝트 파일입니다. 모든 파일 인코딩은 UTF-8 입니다.


multi-lang.zip


war 파일입니다. 16메가의 용량이 다 라이브러리군요... -_-/


multi-lang.zip.001

multi-lang.zip.002



반응형

'Java+ > Example' 카테고리의 다른 글

LOGBack Configurator with JMX  (0) 2014.07.20
현지어로 언어명 보여주기  (0) 2014.02.09
2014년 도로명 주소 사용에 따른 우편번호 준비  (2) 2013.12.22
JSTL Custom Tag using Spring Beans  (0) 2013.12.01
Infinite Routing DataSource  (1) 2013.01.13
Mybatis Type Handler  (1) 2012.09.30
Using AUTO_INCREMENT keys  (0) 2011.03.01
//