Swift 3.1

Programming/IOS 2017.04.26 09:34 Posted by 파란크리스마스

Swift 3.1

출처 : mozilla-mobile/firefox-ios
아이폰 Swift 개발 #6 Web Browser App - Machine Learning and ...
[iOS] WebKit API 알아보기. : 네이버 블로그

세로모드 고정

출처 : Swift 3 how to lock orientation - Stack Overflow

override var shouldAutorotate: Bool {
    return false
}

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.portrait
}

 override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
    return UIInterfaceOrientation.portrait
}

override func viewDidLoad() {
    super.viewDidLoad()
}

URL 주소의 이미지 가져오기

출처 : swift3 - Swift 3: Display Image from URL - Stack Overflow

                let url = URL(string: hostUrl + (share_url as! String))
                NSLog("url = \(url?.absoluteString)")

                var data = NSData(contentsOf: url as! URL)
                var image = UIImage(data : data as! Data)

문자열 내장 합수

출처 : How does String.Index work in Swift 3
Index of a substring in a string with Swift

JavaScript(Alert,Confirm,Prompt)

출처 : WKWebViewでJavaScript(Alert,Confirm,Prompt)の処理
WKWebView 사용 시 필수적으로 넣어줘야 하는Delegate 넷.

오류 해결 / This application is modifying the autolayout engine from a background thread, which can lead to engine corruption

출처 : This application is modifying the autolayout engine from a background thread, which can lead to engine corruption - Stack Overflow

    func alert(message : String) {
        let alertView = UIAlertController(title: "파란크리스마스", message: message, preferredStyle: .alert)
        alertView.addAction(UIAlertAction(title: "확인", style: .default, handler: { (alertAction) -> Void in
            //logUserIn()
        }))
        //alertView.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
        DispatchQueue.main.async {
            self.present(alertView, animated: true, completion: nil)
        }
    }

배포

출처 : 내가 만든 iOS앱을 앱스토어에 배포해보자 - xCode로 소스 업로드하기 ...

저작자 표시
신고
TAG

JsonConfig 사용

Programming/Java 2017.04.23 16:48 Posted by 파란크리스마스

JsonConfig 사용하기

출처 : 알팅스님의 개발 스토리 : Java Object(POJO) To JSON String

Mybatis XML

	<resultMap id="resultMapUserInfo" type="map">
		<result property="user_id" column="user_id" javaType="java.lang.String"/>
		<result property="email" column="email" javaType="java.lang.String"/>
		<result property="mobile" column="mobile" javaType="java.lang.String"/>
		<result property="name" column="name" javaType="java.lang.String"/>
		<result property="point" column="point" javaType="int"/>
		<result property="reg_date" column="reg_date" javaType="java.util.Date"/>
		<result property="service_start_date" column="service_start_date" javaType="java.util.Date"/>
		<result property="service_end_date" column="service_end_date" javaType="java.util.Date"/>
	</resultMap>

	<!-- listUser -->
	<select id="listUser" parameterType="map" resultMap="resultMapUserInfo">
		select a.*
		  FROM user_info a
		 WHERE a.delete_yn = 'N'
	</select>

Java

	JsonConfig jsonConfig = new JsonConfig();
	jsonConfig.registerJsonValueProcessor(java.util.Date.class, new JsonValueProcessor() {

		@Override
		public Object processArrayValue(Object value, JsonConfig jsonConfig) {
			
			java.util.Date[] dates = (java.util.Date[]) value;
			Long[] result = new Long[dates.length];
			for (int index = 0; index < dates.length; index++) {
				result[index] = dates[index].getTime();
			}
			return result;
		}

		@Override
		public Object processObjectValue(String key, Object value, JsonConfig jsonConfig) {
			java.util.Date date = (java.util.Date) value;
			return date.getTime();
		}
	});
	
	List<Map<String, Object>> listUser = service.listUser(null);
	jsonObjet.put("listUser", JSONArray.fromObject(listUser, jsonConfig));
저작자 표시
신고

Ubuntu 디스크 mount 하기

OS/Linux 2017.04.19 14:03 Posted by 파란크리스마스

Ubuntu 디스크 mount 하기

출처 : Mint & Latte_. :: 리눅스에서 하드디스크 mount 하기

추가된 디스트 Volume 확인

$ sudo fdisk -l
 
Disk /dev/vda: 42.9 GB, 42949672960 bytes
16 heads, 63 sectors/track, 83220 cylinders, total 83886080 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000648d6
 
   Device Boot      Start         End      Blocks   Id  System
/dev/vda1            2048     3905535     1951744   82  Linux swap / Solaris
/dev/vda2   *     3905536    83885759    39990112   83  Linux
 
Disk /dev/vdb: 214.7 GB, 214748364800 bytes
16 heads, 63 sectors/track, 416101 cylinders, total 419430400 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

Disk /dev/vdb doesn't contain a valid partition table

파일시스템 생성

$ sudo mkfs.ext4 /dev/vdb
mke2fs 1.42.9 (4-Feb-2014)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
13107200 inodes, 52428800 blocks
2621440 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=4294967296
1600 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 
        4096000, 7962624, 11239424, 20480000, 23887872
 
Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

mount 받을 디렉토리 생성

$ sudo mkdir /bluexmas_db

mount 하기

$ sudo mount /dev/vdb /bluexmas_db

mount 확인

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            2.0G   12K  2.0G   1% /dev
tmpfs           396M  364K  395M   1% /run
/dev/vda2        38G  1.6G   35G   5% /
none            4.0K     0  4.0K   0% /sys/fs/cgroup
none            5.0M     0  5.0M   0% /run/lock
none            2.0G     0  2.0G   0% /run/shm
none            100M     0  100M   0% /run/user
/dev/vdb        197G   60M  187G   1% /bluexmas_db

unmount 하기

$ sudo umount /bluexmas_db

unmount 확인

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            2.0G   12K  2.0G   1% /dev
tmpfs           396M  372K  395M   1% /run
/dev/vda2        38G  9.2G   27G  26% /
none            4.0K     0  4.0K   0% /sys/fs/cgroup
none            5.0M     0  5.0M   0% /run/lock
none            2.0G     0  2.0G   0% /run/shm
none            100M     0  100M   0% /run/user

자동 mount

출처 : Ubuntu 14.04에 새로운 하드디스크 추가 및 포맷후 자동 마운트 설정

UUID 확인

$ sudo blkid
/dev/vda1: UUID="4874a47d-f878-440c-95d0-297e6733abea" TYPE="swap" 
/dev/vda2: UUID="20c996fb-8c20-4e7f-958e-84b7581af70f" TYPE="ext4" 
/dev/vdb: UUID="6e0b7ac6-d17d-4829-839f-80662339cf6b" TYPE="ext4" 
저작자 표시
신고

Ubuntu 리눅스 서버에 MySQL 5.7.x 설치

Database 2017.04.18 13:01 Posted by 파란크리스마스

Ubuntu 리눅스 서버에 MySQL 5.7.x 설치

출처 : Ubuntu server에 mysql 5.5.x 설치하기 -pupustory@- - Tistory
[Linux/CentOS] Mysql을 컴파일해서 설치해보자 - AT BLOG

리눅스 정보 조회

출처 : 리눅스 종류 확인, 리눅스 버전 확인 - 제타위키

$ cat /etc/*-release | uniq
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.3 LTS"
NAME="Ubuntu"
VERSION="14.04.3 LTS, Trusty Tahr"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 14.04.3 LTS"
VERSION_ID="14.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"

리눅스 비트 확인

출처 : 리눅스 32비트 64비트 확인 - 제타위키

$ getconf LONG_BIT
64

관련패키지 설치

$ sudo apt-get update
$ sudo apt-get install gcc g++ libncurses5-dev libxml2-dev openssl libssl-dev curl libcurl4-openssl-dev libjpeg-dev libpng-dev libfreetype6-dev libsasl2-dev autoconf libncurses5-dev

MySQL 계정 만들기

$ sudo groupadd mysql
$ sudo useradd -g mysql -s /bin/bash -m mysql

cmake 설치

$ sudo apt-get install cmake

cmake 수동 설치(option)

$ wget http://www.cmake.org/files/v2.8/cmake-2.8.4.tar.gz
$ tar xvf cmake-2.8.4.tar.gz 
$ cd cmake-2.8.4
$ ./bootstrap
$ make all
$ sudo make install

MySQL 소스 다운로드

$ wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.19.tar.gz

MySQL 소스 압축풀기

$ tar xvf mysql-5.7.19.tar.gz

MySQL 컴파일 및 설치

$ cd mysql-5.7.19
$ sudo cmake \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYSQL_DATADIR=/usr/local/mysql/data \
-DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock \
-DSYSCONFDIR=/etc \
-DMYSQL_TCP_PORT=3306 \
-DMYSQL_USER=mysql \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_EXTRA_CHARSETS=all \
-DENABLED_LOCAL_INFILE=1 \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DDOWNLOAD_BOOST=1 -DWITH_BOOST=/usr/local/mysql/boost
$ sudo make
$ sudo make install

MySQL 데이터베이스 초기화

$ cd /usr/local/mysql
$ echo "./bin/mysql_install_db --user=mysql --datadir=/usr/local/mysql/data -v"
$ sudo ./bin/mysql_install_db --no-defaults --user=mysql --datadir=/usr/local/mysql/data --basedir=/usr/local/mysql -v
2017-09-20 20:17:58 [WARNING] mysql_install_db is deprecated. Please consider switching to mysqld --initialize
2017-09-20 20:17:58 [NOTE]    Using existing directory /usr/local/mysql/data
2017-09-20 20:17:58 [NOTE]    Generating random password to /root/.mysql_secret...done.
2017-09-20 20:17:58 [NOTE]    Setting file ownership to mysql
2017-09-20 20:17:58 [NOTE]    Executing /usr/local/mysql/bin/mysqld --no-defaults --bootstrap --datadir=/usr/local/mysql/data --lc-messages-dir=/usr/local/mysql/share --lc-messages=en_US --basedir=/usr/local/mysql
2017-09-20 20:18:00 [NOTE]    Creating system tables...done.
2017-09-20 20:18:00 [NOTE]    Filling system tables with data...done.
2017-09-20 20:18:01 [NOTE]    Filling help table with data...done.
2017-09-20 20:18:01 [NOTE]    Creating user for internal session service...done.
2017-09-20 20:18:01 [NOTE]    Creating default user root@localhost
2017-09-20 20:18:01 [NOTE]    Creating default proxy root@localhost
2017-09-20 20:18:01 [NOTE]    Creating sys schema
2017-09-20 20:18:02 [NOTE]    done.
2017-09-20 20:18:03 [WARNING] The bootstrap log isn't empty:
2017-09-20 20:18:03 [WARNING] 2017-09-20T11:17:58.125569Z 0 [Warning] --bootstrap is deprecated. Please consider using --initialize instead
2017-09-20T11:17:58.126616Z 0 [Warning] Changed limits: max_open_files: 1024 (requested 5000)
2017-09-20T11:17:58.126627Z 0 [Warning] Changed limits: table_open_cache: 431 (requested 2000)

2017-09-20 20:18:03 [NOTE]    Generating SSL Certificates

MySQL 설치 디렉토리 mysql 계정으로 권한 수정

$ sudo chown -R mysql:mysql /usr/local/mysql

환경설정

$ vi /usr/local/mysql/my.cnf

[mysqld]
# port=3306
# basedir=/usr/local/mysql
# datadir=/usr/local/mysql/data
# pid-file=/usr/local/mysql/mysqld.pid
# log_error=/usr/local/mysql/mysql_error.log
# lc-messages-dir=/usr/local/mysql/share

init_connect=SET collation_connection = utf8_general_ci
init_connect=SET NAMES utf8
character-set-server=utf8
collation-server=utf8_general_ci
# table_cache=1024
max_connections=2048
max_user_connections=500
max_connect_errors=10000
wait_timeout=300
query_cache_type = 1
query_cache_size = 128M
query_cache_limit = 5M
slow_query_log
long_query_time=3
max_allowed_packet=16M
sort_buffer_size = 2M
# skip-innodb
skip-name-resolve
sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

[mysql]
default-character-set=utf8

[client]
default-character-set=utf8

MySQL 서비스 등록

서비스 mysqld 파일 복사

$ sudo cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld

mysqld 수정

$ sudo vi /etc/init.d/mysqld

mysqld파일을 열어서 basedir에 mysql이 설치된 디렉토리와 데이터 디렉토리(datadir)를 설정한다.

basedir=/usr/local/mysql
datadir=/usr/local/mysql/data

mysqld 서비스 등록

$ sudo update-rc.d mysqld defaults
 Adding system startup for /etc/init.d/mysqld ...
   /etc/rc0.d/K20mysqld -> ../init.d/mysqld
   /etc/rc1.d/K20mysqld -> ../init.d/mysqld
   /etc/rc6.d/K20mysqld -> ../init.d/mysqld
   /etc/rc2.d/S20mysqld -> ../init.d/mysqld
   /etc/rc3.d/S20mysqld -> ../init.d/mysqld
   /etc/rc4.d/S20mysqld -> ../init.d/mysqld
   /etc/rc5.d/S20mysqld -> ../init.d/mysqld

mysqld 서비스 실행

$ sudo service mysqld start
Starting MySQL
. * 
$ sudo service mysqld status
 * MySQL running (29565)
$ sudo service mysqld stop
Shutting down MySQL
. * 

root 암호 초기화

$ sudo ./bin/mysqld_safe --skip-grant-tables &
[1] 31008
mysql@localhost:/usr/local/mysql$ 2017-04-18T09:21:34.035860Z mysqld_safe Logging to '/usr/local/mysql/data/localhost.err'.
2017-04-18T09:21:34.050764Z mysqld_safe Starting mysqld daemon with databases from /usr/local/mysql/data

mysql@localhost:/usr/local/mysql$ ./bin/mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.18-log Source distribution

Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> update user set authentication_string = password('sql') where user = 'root';

Query OK, 1 row affected, 1 warning (0.02 sec)
Rows matched: 1  Changed: 1  Warnings: 1

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql> quit
Bye

사용자 추가

mysql> create user 'user1'@'%' identified by 'userpw';
mysql> grant all privileges on *.* to 'user1'@'%';
mysql> flush privileges;

사용자 추가

create user 'terecal'@'%' identified by '****';
GRANT ALL privileges ON terecal_db.* TO 'terecal'@'%' identified by '****';
flush privileges;
저작자 표시
신고

MySQL 레코드 자동 생성

Database 2017.04.16 19:04 Posted by 파란크리스마스

MySQL 레코드 자동 생성

출처 : MySQL Row Generator - Use The Index, Luke
[MySQL] 무작위 샘플 데이터 만들기

View 생성

CREATE OR REPLACE VIEW generator_16
AS SELECT 0 n UNION ALL SELECT 1  UNION ALL SELECT 2  UNION ALL 
   SELECT 3   UNION ALL SELECT 4  UNION ALL SELECT 5  UNION ALL
   SELECT 6   UNION ALL SELECT 7  UNION ALL SELECT 8  UNION ALL
   SELECT 9   UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL
   SELECT 12  UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL 
   SELECT 15;

CREATE OR REPLACE VIEW generator_256
AS SELECT ( ( hi.n << 4 ) | lo.n ) AS n
     FROM generator_16 lo, generator_16 hi;

CREATE OR REPLACE VIEW generator_4k
AS SELECT ( ( hi.n << 8 ) | lo.n ) AS n
     FROM generator_256 lo, generator_16 hi;

CREATE OR REPLACE VIEW generator_64k
AS SELECT ( ( hi.n << 8 ) | lo.n ) AS n
     FROM generator_256 lo, generator_256 hi;

CREATE OR REPLACE VIEW generator_1m
AS SELECT ( ( hi.n << 16 ) | lo.n ) AS n
     FROM generator_64k lo, generator_16 hi;

0부터 30까지 레코드 만들기

select *
  from generator_256
 where n < 31;

해당 월의 마지막 날까지 레코드 생성

MySQL의 내장함수 current_date로 오늘날짜를 가져와서 날짜함수 LAST_DAY로 해당 월의 마지막 일을 얻어 오고, DATE_FORMAT 함수의 %d로 일수를 조회 한 후에 generator_256 뷰를 이용해서 일수만큼 레코드를 생성해서 INTERVAL 을 이용해서 마지막 일자에서 n 필드의 값으로 빼면서 해당 월의 일수 만큼 레코드를 생성한다.

SELECT LAST_DAY(current_date) - INTERVAL n DAY dt
  FROM generator_256
 WHERE n < DATE_FORMAT(LAST_DAY(current_date), '%d');

해당 월의 통계 데이터 생성

select a.dt, IFNULL(SUM(b.level_request), 0)
  from (  SELECT LAST_DAY(current_date) - INTERVAL n DAY dt
            FROM generator_256
           WHERE n < DATE_FORMAT(LAST_DAY(current_date), '%d')
       ) a LEFT OUTER JOIN group2 b
       ON a.dt = DATE(b.date_request)
 group by a.dt
 order by a.dt
저작자 표시
신고

JQuery UI - Datepicker

Programming/JavaScript, Sencha 2017.04.09 18:57 Posted by 파란크리스마스

JQuery UI - Datepicker

출처 : Datepicker | jQuery UI
JQuery UI datepicker 한국어 적용 - 제타위키

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!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=UTF-8">
<script type="text/javascript" src="<c:url value="/resources/js/jquery-1.12.0.js"/>"></script>
<script type="text/javascript" src="<c:url value="/resources/js/jquery-ui.js"/>"></script>
<link rel="stylesheet" href="<c:url value="/resources/css/jquery-ui.css"/>">
<title>Insert title here</title>
<script>
// Datepicker 오늘 날짜 설정
function setDatepickerToday(datepicker) {
	var d = new Date();
	datepicker.datepicker("setDate", new Date(d.getFullYear(), d.getMonth(), d.getDate()) );
}

// 한글화 설정
$.datepicker.setDefaults({
	dateFormat: 'yy-mm-dd',
	prevText: '이전 달',
	nextText: '다음 달',
	monthNames: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'],
	monthNamesShort: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'],
	dayNames: ['일', '월', '화', '수', '목', '금', '토'],
	dayNamesShort: ['일', '월', '화', '수', '목', '금', '토'],
	dayNamesMin: ['일', '월', '화', '수', '목', '금', '토'],
	showMonthAfterYear: true,
	yearSuffix: '년'
});

$( function() {
	// datepicker 생성
	$( "#datepicker" ).datepicker({
		// 날짜를 선택했을 경우 이벤트 발생
		onSelect: function (dateText, inst) {
			alert('날짜선택 = ' + dateText);
		}
	});
	
	// 오늘 날짜 설정
	setDatepickerToday($( "#datepicker" ));
});
</script>
</head>
<body>
 
<p>날짜 : <input type="text" id="datepicker"></p>

</body>
</html>
저작자 표시
신고

MySQL - 일별통계, 주간통계, 월간통계

Database/SQL 2017.04.09 18:11 Posted by 파란크리스마스

MySQL - 일별통계, 주간통계, 월간통계

출처 : Error related to only_full_group_by when executing a query in MySql - Stack Overflow
[Mysql] DB일간 주간 월간 년간 통계 | database

sample 테이블 생성

CREATE TABLE `test_st` (
  `reg_date` date NOT NULL,
  `value` int(11) NOT NULL
);

INSERT INTO `test_st` (`reg_date`, `value`) VALUES
  ('2017-03-01', 4),
  ('2017-03-08', 2),
  ('2017-03-15', 4),
  ('2017-03-22', 4),
  ('2017-04-01', 9),
  ('2017-04-02', 1),
  ('2017-04-04', 2),
  ('2017-04-09', 4),
  ('2017-04-11', 2),
  ('2017-04-16', 4),
  ('2017-04-18', 5),
  ('2017-04-23', 3),
  ('2017-04-25', 4),
  ('2017-04-30', 4),
  ('2017-04-01', 5);

MySQL - 일별통계

SELECT DATE(`reg_date`) AS `date`, 
       sum(`value`)
  FROM test_st
 GROUP BY `date`;

MySQL - 주간통계

SELECT DATE_FORMAT(DATE_SUB(`reg_date`, INTERVAL (DAYOFWEEK(`reg_date`)-1) DAY), '%Y/%m/%d') as start,
       DATE_FORMAT(DATE_SUB(`reg_date`, INTERVAL (DAYOFWEEK(`reg_date`)-7) DAY), '%Y/%m/%d') as end,
       DATE_FORMAT(`reg_date`, '%Y%U') AS `date`, 
       sum(`value`)
  FROM test_st
 GROUP BY date;

MySQL - 월간통계

SELECT MONTH(`reg_date`) AS `date`, 
       sum(`value`)
  FROM test_st
 GROUP BY `date`;

기간별 통계

SELECT DATE(`reg_date`) AS `date`,
       sum(`value`)
  FROM test_st
 WHERE DATE(`reg_date`) >= STR_TO_DATE('2017-04-01', '%Y-%m-%d')
   AND DATE(`reg_date`) <= STR_TO_DATE('2017-04-10', '%Y-%m-%d')
 GROUP BY `date`;
저작자 표시
신고

CKEditor 4.6

Programming/Java 2017.04.09 17:29 Posted by 파란크리스마스

CKEditor 4.6

출처 : CKEditor 4.6
CKEditor not working after opening jQuery UI Dialog - Stack Overflow

CKEditor - JQuery UI Dialog와 같이 사용하기

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!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=UTF-8">
<script type="text/javascript" src="<c:url value="/resources/js/jquery-1.12.0.js"/>"></script>
<script type="text/javascript" src="<c:url value="/resources/js/jquery-ui.js"/>"></script>
<script type="text/javascript" src="<c:url value="/resources/ckeditor/ckeditor.js"/>"></script>
<link rel="stylesheet" href="<c:url value="/resources/css/jquery-ui.css"/>">
<title>JQuery Dialog</title>
<script type="text/javascript">
// CKEditor 기본 경로 설정 - config.js의 경로 설정
window.CKEDITOR_BASEPATH = '<c:url value="/resources/ckeditor"/>';
//window.parent.CKEDITOR.tools.callFunction('콜백의 식별 ID 값', '파일의 URL', '전송완료 메시지')

// CKEditor 제거 함수 - CKEditor 생성 되어 있는지 확인 후 제거
function DestryoCKEditorInstances(textarea_name) {
	if (CKEDITOR.instances[textarea_name])	{
		CKEDITOR.instances[textarea_name].destroy();
	}
}

function insertPopUpForSubject(){
	// 팝업 다이얼로그
	$("#tabb_subject_insert").dialog({
		position : {
			my : 'center center',
			at : 'center top'
		},
		width : 800,
		//height : 800,
		modal : true,
		open: function( event, ui ) {
			// 팝업창 열릴때 CKEditor 설정
			CKEDITOR.replace( 'example_subject_insert' , {
				extraPlugins: 'uploadimage,image2',
				uploadUrl: '<c:url value="/dragdrop/fileUpload/ckeditor2.do"/>',
				filebrowserImageUploadUrl: '<c:url value="/dragdrop/fileUpload/ckeditor.do"/>'
			});
		},
		close: function () {
			// 반듯이 팝업창 닫힐때 제거 되어함
			DestryoCKEditorInstances('example_subject_insert');
		}
	});
}
</script>
</head>
<body>

<button class="button button2" onclick="javascript:insertPopUpForSubject();">문제 입력1</button>

<div id="tabb_subject_insert"  title="문제 입력!"  style="display:none">
	<table align="center" width="90%" border="0" cellspacing="0" cellpadding="0">
	<tr>
		 <td>seq</td>
		 <td><input type="text" size="20" id="seq_subject_insert" ></td>
	</tr>
	<tr>
		 <td>보기</td>
		 <td>
			<textarea id="example_subject_insert" name="example_subject_insert" form="usrform">Enter text here...</textarea>
		 </td>
	</tr>
	</table>
	<center>
		<button class="button button5" onclick="javascript:insert_subject1_complete(1);">입력 완료(과목1)</button>
		<button class="button button5" onclick="javascript:cancle_insert();">취 소</button>
	</center>
</div>

</body>
</html>


저작자 표시
신고

Spring MVC - 네이버 로그인 처리

Programming/Java 2017.04.03 16:05 Posted by 파란크리스마스

Spring MVC - 네이버 로그인 처리

네이버 로그인 API를 이용해서 네이버 계정으로 로그인 처리를 Spring 프레임웍에서 사용 할 수 있도록 간단하게 NaverLoginController를 작성해보았습니다. 임시로 로그인 결과값을 가지고 와서 tbluser2 테이블의 abcd 계정의 1111 암호를 사용하는 사용자로 로그인 되도록 고정했습니다. (authentication-provider 사용자가 제어 하는 부분은 따로 찾아서 적용필요)

bluexmas-security.xml

alias의 authenticationManager 이름은 NaverLoginController 에서 속성으로 사용

	<security:authentication-manager alias="authenticationManager">
		<security:authentication-provider>

			<security:jdbc-user-service
				data-source-ref="dataSource"
				users-by-username-query="select user_id username, pass password, 1 as enabled from tbluser2 where user_id = ?"
				authorities-by-username-query="select user_id username, 'ROLE_USER' authority from tbluser2 where user_id = ?" />

		</security:authentication-provider>
	</security:authentication-manager>

NaverLogInController.java

package com.bluexmas.controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.SecureRandom;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;

@Controller
public class NaverLogInController {
	
	private String naverClientId = "네이버API_Client_ID";
	
	private String naverClientSecret = "네이버API_Client_Secret";
	
	private String state = "";
	
	@Autowired
	@Qualifier("authenticationManager")
	protected AuthenticationManager authenticationManager;
	
	/**
	 * 네이버 로그인 요청
	 * 
	 * @param request
	 * @param uri
	 * @return
	 */
	@RequestMapping(value = "/naverLogin.do")
	public String makeNaverRequestStatement(
			HttpServletRequest request,
			@RequestParam(value = "uri", required = false) String uri) 
	{
		HashMap<String, String> naverUrl = this.makeRequestStatement(request, naverClientId);
		this.state = naverUrl.get("state");
		String returnUrl = request.getHeader("referer");
		
		return "redirect:" + naverUrl.get("url");
	}
	
	/**
	 * 네이버 로그인 요청에 대한 응답 처리
	 * 
	 * @param request
	 * @param response
	 * @param state
	 * @param code
	 * @param error
	 * @param error_description
	 * @return
	 */
	@RequestMapping(value = "/naverRequestKey.do")
	public String getNaverRequestKey(
			HttpServletRequest request,
			HttpServletResponse response,
			@RequestParam("state") String state, 
			@RequestParam(value = "code", required = false) String code, 
			@RequestParam(value = "error", required = false) String error, 
			@RequestParam(value = "error_description", required = false) String error_description) 
	{
		HttpSession session = request.getSession();
		
		System.out.print("state = " + this.state + "="+  state + "/code = " + code + "/error = " + error + "/error_description = " + error_description);
		
		if (state.equals(this.state)) {
			session.setAttribute("isLoged", true);
		} else {
			session.setAttribute("isLoged", false);
			//System.out.println("state key값 불일치. 인증에러");
			return "redirect:/index.html";
		}
		
		// 네이버에 token_type, access_token 요청
		HashMap<String, String> result1 = this.getRequestKey(request, state, code, naverClientId, naverClientSecret);
		
		//
		String access_token = result1.get("access_token");
		String refresh_token = result1.get("refresh_token");
		String token_type = result1.get("token_type");
		
		System.out.println("access_token = " + access_token + "," + refresh_token + "," + token_type);

		// 사용자 정보 조회 요청
		HashMap<String, Object> result2 = this.requestUserInfo(token_type, access_token);
		System.out.println("result=" + result2);

		String email = (String)result2.get("email");
		
		if (email==null) {
			System.out.println("email = " + email);
			session.setAttribute("isLoged", false);
			return "redirect:/index.html";
		}
		
		String user_id = (String)result2.get("email");
		
		// 수동 로그인(spring security manual login) 처리
		try {
			// 
			UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken("abcd", "1111");
			
			// Authenticate the user
			Authentication authentication = authenticationManager.authenticate(authRequest);
			SecurityContext securityContext = SecurityContextHolder.getContext();
			securityContext.setAuthentication(authentication);
		} catch (Exception e) {
			e.printStackTrace();
			SecurityContextHolder.getContext().setAuthentication(null);
		}
		
		//return "redirect:" + returnUrl;
		return "redirect:/index.html";
	}
	
	/**
	 * 호스트이름 반환
	 * 
	 * @param request
	 * @return
	 */
	public static String getHostname(HttpServletRequest request) {
		String port_str = (request.getServerPort()==80 ? "" : ":" + request.getServerPort());
		return "http://" + request.getServerName() + port_str + request.getContextPath();
	}
	
	/**
	 * state 값 생성
	 * 
	 * @return
	 */
	public String generateState() {
		SecureRandom random = new SecureRandom();
		return new BigInteger(130, random).toString(32);
	}
	
	/**
	 * 네이버 로그인 요청 (Redirect URL 생성)
	 * 
	 * 1. redirect 생성 - 네이버 로그인 요청 완료 후 응답 받는 url 생성
	 * 2. state 생성 - Ramdom 함수로 생성
	 * 3. 요청 URL 생성 반환
	 * 
	 * @param request
	 * @param clientId
	 * @return
	 */
	private HashMap<String, String> makeRequestStatement(HttpServletRequest request, String clientId) {
		//String redirectUri = "http://127.0.0.1:8080/naverRequestKey.cmx";
		String redirectUri = getHostname(request) + "/naverRequestKey.do";
		String state = generateState();
		String url = "https://nid.naver.com/oauth2.0/authorize?" + "response_type=code&client_id=" + clientId + "&redirect_uri=" + redirectUri + "&state=" + state;
		
		HashMap<String, String> naverUrl = new HashMap<String, String>();
		naverUrl.put("state", state);
		naverUrl.put("url", url);
		return naverUrl;
	}
	
	/**
	 * 네이버에 token_type, access_token 요청(로그인 성공 이후)
	 * 
	 * @param request
	 * @param state
	 * @param code
	 * @param clientId
	 * @param naverClientSecret
	 * @return
	 */
	private HashMap<String, String> getRequestKey(HttpServletRequest request, String state, String code, String clientId, String naverClientSecret) {
		String naverUrl = "https://nid.naver.com/oauth2.0/token?client_id=" + clientId + "&client_secret=" + naverClientSecret + "&grant_type=authorization_code" + "&state=" + state + "&code=" + code;
		String naverJsonKey = "";// null로 하니까 null이 json에 포함이 됨.
		HashMap<String, String> result = new HashMap<String, String>();

		try {
			HttpURLConnection conn = (HttpURLConnection) new URL(naverUrl).openConnection();
			BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
			String input;
			while ((input = reader.readLine()) != null) {
				naverJsonKey += input;
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		try {
			JSONParser parser = new JSONParser();
			JSONObject jsonObject = (JSONObject) parser.parse(naverJsonKey);
			
			result.put("access_token", (String) jsonObject.get("access_token"));
			result.put("refresh_token", (String) jsonObject.get("refresh_token"));
			result.put("token_type", (String) jsonObject.get("token_type"));
			
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 네이버에 로그인 사용자의 정보 요청
	 * 
	 * @param token_type
	 * @param access_token
	 * @return
	 */
	public HashMap<String, Object> requestUserInfo(String token_type, String access_token) {
		
		String url = "https://apis.naver.com/nidlogin/nid/getUserProfile.xml";
		String naverResult = "";
		try {
			HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
			conn.setRequestMethod("GET");
			conn.setRequestProperty("Authorization", token_type + " " + access_token);
			BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
			String input;
			while ((input = reader.readLine()) != null) {
				naverResult += input;
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		HashMap<String, Object> result = new HashMap<String, Object>();

		try {
			InputSource is = new InputSource(new StringReader(naverResult));
			Document xml = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
			XPath xpath = XPathFactory.newInstance().newXPath();
			Node email = (Node) xpath.evaluate("//data/response/email", xml, XPathConstants.NODE);
			Node nickname = (Node) xpath.evaluate("//data/response/nickname", xml, XPathConstants.NODE);
			Node profile_image = (Node) xpath.evaluate("//data/response/profile_image", xml, XPathConstants.NODE);
			Node age = (Node) xpath.evaluate("//data/response/age", xml, XPathConstants.NODE);
			Node gender = (Node) xpath.evaluate("//data/response/gender", xml, XPathConstants.NODE);
			Node id = (Node) xpath.evaluate("//data/response/id", xml, XPathConstants.NODE);
			Node birthday = (Node) xpath.evaluate("//data/response/birthday", xml, XPathConstants.NODE);
			if (email!=null) result.put("email", email.getTextContent());
			if (nickname!=null) result.put("nickname", nickname.getTextContent());
			if (profile_image!=null) result.put("profile_image", profile_image.getTextContent());
			if (age!=null) result.put("age", age.getTextContent());
			if (gender!=null) result.put("gender", gender.getTextContent());
			if (id!=null) result.put("id", id.getTextContent());
			if (birthday!=null) result.put("birthday", birthday.getTextContent());

		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

}


저작자 표시
신고

NanoPi M1 Plus - DHT11 control with pi4j

OS/NanoPi 2017.04.02 09:57 Posted by 파란크리스마스

NanoPi M1 Plus - DHT11 control with pi4j

출처 : Java Native Interface (JNI) - Java Programming Tutorial
Use arrays (JNI) - Real's Java How-to - Rgagnon
android - How to return an array from JNI to Java? - Stack Overflow

NanoPi M1 Plus에서 pi4j로만으로 DHT11센서의 값을 읽을 수 없어 pi4j의 native 코드를 추가해서 온도 값을 가지고 오도록 수정하였습니다. 첨부한 jar을 적용해서 사용하세요.

pi4j-core.jar

핀배열

 DHT11  BCM  GPIO  Name  Pin
 VCC      3.3v  1
 GND  0v  9
 Sensor  3  22  CTS2  15

dht11.h

int* read_dht11_dat(int pin);

dht11.c

/*
 *  dht11.c:
 *      Simple test program to test the wiringPi functions
 *      DHT11 test
 */
  
#include <wiringPi.h>
  
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <dht11.h>

#define MAXTIMINGS      85
#define DHTPIN    3
int dht11_dat[5] = { 0, 0, 0, 0, 0 };
  
int* read_dht11_dat(int pin) {
    uint8_t laststate       = HIGH;
    uint8_t counter  = 0;
    uint8_t j          = 0, i;
    float   f; /* fahrenheit */
  
    dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;
  
    /* pull pin down for 18 milliseconds */
    pinMode( pin, OUTPUT );
    digitalWrite( pin, LOW );
    delay( 18 );
    /* then pull it up for 40 microseconds */
    digitalWrite( pin, HIGH );
    delayMicroseconds( 40 );
    /* prepare to read the pin */
    pinMode( pin, INPUT );
  
    /* detect change and read data */
    for ( i = 0; i < MAXTIMINGS; i++ ) {
        counter = 0;
        while ( digitalRead( pin ) == laststate ) {
            counter++;
            delayMicroseconds( 1 );
            if ( counter == 255 ) {
                break;
            }
        }
        laststate = digitalRead( pin );
  
        if ( counter == 255 )
            break;

// printf("i = %d, j = %d\n", i, j);
  
        /* ignore first 3 transitions */
        if ( (i >= 4) && (i % 2 == 0) ) {
            /* shove each bit into the storage bytes */
            dht11_dat[j / 8] <<= 1;
            if ( counter > 16 )
                dht11_dat[j / 8] |= 1;
            j++;
        }
    }
  
    /*
     * check we read 40 bits (8bit x 5 ) + verify checksum in the last byte
     * print it out if data is good
     */
    if ( (j >= 40) && (dht11_dat[4] == ( (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF) ) ) {
        f = dht11_dat[2] * 9. / 5. + 32;
        //printf( "Humidity = %d.%d %% Temperature = %d.%d *C (%.1f *F)\n",
        //    dht11_dat[0], dht11_dat[1], dht11_dat[2], dht11_dat[3], f );
    } else {
        //printf( "Data not good, skip\n" );
    }
    
    return dht11_dat;    
}

com_pi4j_wiringpi_Gpio.h 내용 추가

/*
 * Class:     com_pi4j_wiringpi_Gpio
 * Method:    readDHT11Data
 * Signature: (II)V
 */
JNIEXPORT jintArray JNICALL Java_com_pi4j_wiringpi_Gpio_readDHT11Data
  (JNIEnv *, jclass, jint);

com_pi4j_wiringpi_Gpio.c 내용 추가

#include <dht11.h>

/*
 * Class:     com_pi4j_wiringpi_Gpio
 * Method:    readDHT11Data
 * Signature: (II)V
 */
JNIEXPORT jintArray JNICALL Java_com_pi4j_wiringpi_Gpio_readDHT11Data
  (JNIEnv *env, jclass obj, jint pin)
{
    // return (jintArray) read_dht11_dat(pin);
    int size = 5;
    jintArray result;
    result = (*env)->NewIntArray(env, size);
    if (result == NULL) {
    	return NULL; /* out of memory error thrown */
    }
    
    int *a1 = read_dht11_dat(pin);
    
    int i;
    // fill a temp structure to use to populate the java int array
    jint fill[size];
    for (i = 0; i < size; i++) {
    	 fill[i] = a1[i]; // put whatever logic you want to populate the values here.
    }
    // move from the temp structure to the java structure
    (*env)->SetIntArrayRegion(env, result, 0, size, fill);
    return result;
}

Gpio 클래스 함수 추가

package com.pi4j.wiringpi;

public class Gpio {
    
    public static native int[] readDHT11Data(int pin);
}

DHT11_native.java

import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.NanoPiM1PlusGpioProvider;
import com.pi4j.wiringpi.Gpio;
 
public class DHT11_native {
    private static final int MAXTIMINGS = 85;
    private int[] dht11_dat = { 0, 0, 0, 0, 0 };
    
    private final static int DHTPIN = 3; // 3;
 
    public float getTemperature() {
    	float f = 0;
    	dht11_dat = Gpio.readDHT11Data(DHTPIN);
    	
       if ( (dht11_dat[4] == ( (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF) ) ) {
      	 f = (float) (dht11_dat[2] * 9. / 5. + 32);
         System.out.println(String.format( "Humidity = %d.%d %% Temperature = %d.%d *C (%.1f *F)" , dht11_dat[0], dht11_dat[1], dht11_dat[2], dht11_dat[3], f) );
     } else {
    	 System.out.println( "Data not good, skip" );
     }
       
        return f;
 
    }
 
    private boolean checkParity() {
      return (dht11_dat[4] == ((dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF));
    }
 
    public static void main (String ars[]) throws Exception {
    	
    	GpioFactory.setDefaultProvider(new NanoPiM1PlusGpioProvider());
 
    	DHT11_native dht = new DHT11_native();
 
        for (int i=0; i<10; i++) {
           Thread.sleep(1000);
           dht.getTemperature();
        }
 
        System.out.println("Done!!");
 
    }
}

실행

# java -cp .:pi4j-core.jar DHT11_native
Data not good, skip
Humidity = 31.0 % Temperature = 23.0 *C (73.4 *F)
Humidity = 30.0 % Temperature = 23.0 *C (73.4 *F)
Humidity = 30.0 % Temperature = 23.0 *C (73.4 *F)

실행결과

저작자 표시
신고


 

티스토리 툴바