2018년 11월 29일 목요일

[EtC] Windows 에서 SocketTest 사용시


Windows 환경에서 SocketTest 사용시,
한글이 깨지는 경우 -Dfile.encoding=utf-8 을 주고 실행 하면 해결 된다.

매번 cmd 에서 옵션 주기는 귀찮으니, SocketTest.bat 파일을 열어 수정 한다.

그리고 TCP 회신 전문에 첫 문자열이 한자나 한글인 경우 문자열이 깨지는 
버그가 있어, 개발자에게 알렸으나 SocketTest V3.0.0 에서 해결 되지 않은 상태.

2018년 11월 5일 월요일

[JaVa] SFTP Upload

1. 필요 라이브러리

compile('com.jcraft:jsch:0.1.54') 

* 최신 버젼은 maven repository 에서 확인 가능.


2. 테스트 코드
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;

import com.jcraft.jsch.SftpException;


public class MyTest  {

/**
* SFTP Upload -> 게시물 원본 http://javacpro.tistory.com/22 참고
* */
public void sftpUploadTest() {

Session session = null;
Channel channel = null;
ChannelSftp channelSftp = null;

// SFTP 서버연결
String url = "192.168.0.100";
String user = "YOUR_SFTP_USER_ID";
String password = "YOUR_SFTP_USER_PASSWORD";
int port = 1234;
File uploadFile = new File("D:\\SFTP_UPLOAD_FILE.EXT");

// JSch 객체 생성
JSch jsch = new JSch();
try {
// 세션객체 생성 ( user , host, port )
session = jsch.getSession(user, url, port);
session.setPassword(password);

// 세션관련 설정정보 설정
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no"); // 호스트 정보 검사하지 않는다.
session.setConfig(config);
session.connect();

// sftp 채널 접속
channel = session.openChannel("sftp");
channel.connect();

} catch (JSchException e) {
// e.printStackTrace();
System.out.println(e.toString());
}

channelSftp = (ChannelSftp) channel;

// upload("./dat/", new File("C:\\Users\\jhkim1981\\Desktop\\20181102_TEST_UPLOAD.txt"));

FileInputStream in = null;
        try{ //파일을 가져와서 inputStream에 넣고 저장경로를 찾아 put
        in = new FileInputStream(uploadFile);
            channelSftp.cd("/home/freecatz/upload");
            channelSftp.put(in, uploadFile.getName());
        }catch(SftpException e){
// e.printStackTrace();
        System.out.println(e.toString());
        }catch(FileNotFoundException e){
// e.printStackTrace();
        System.out.println(e.toString());
        }finally{
            try{
                in.close();
            } catch(IOException e){
//    e.printStackTrace();
            System.out.println(e.toString());
            }
        }
   }


}

[JaAv] html parse


1. 필요 라이브러리.

compile('org.jsoup:jsoup:1.11.3')


최신버젼은 maven repository 에서  확인 가능.


2. 테스트 코드
package my.test.bed;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

public class MyTest {
/**
* html parse test
* */
public void htmlParseTest(String html) {
Document doc = Jsoup.parse(html); 
Elements imgs = doc.getElementsByTag("img");
int cnt = imgs.size();
if(cnt > 0) {
for(int i=0; i < cnt; i++) {
String imgSrc = imgs.get(i).attr("src").toString(); 
System.out.println("img src -> " + imgSrc);
}
}
}
}

2018년 11월 1일 목요일

[GraDle] org.eclipse.buildship.core.UnsupportedConfigurationException




무엇 때문에 그런건지 해결 방법을 알 수가 없다. 누가 좀 알ㄹ ㅕ주세요...ㅠㅠ




org.eclipse.buildship.core.UnsupportedConfigurationException: Project at 'C:\devel\workspace\sts\zTest' can't be named 'my.test.bed' because it's located directly under the workspace root. If such a project is renamed, Eclipse would move the container directory. To resolve this problem, move the project out of the workspace root or configure it to have the name 'zTest'.
at org.eclipse.buildship.core.workspace.internal.DefaultWorkspaceOperations.validateProjectName(DefaultWorkspaceOperations.java:183)
at org.eclipse.buildship.core.workspace.internal.ProjectNameUpdater.checkProjectName(ProjectNameUpdater.java:107)
at org.eclipse.buildship.core.workspace.internal.ProjectNameUpdater.ensureProjectNameIsFree(ProjectNameUpdater.java:71)
at org.eclipse.buildship.core.workspace.internal.SynchronizeGradleBuildOperation.addNewEclipseProjectToWorkspace(SynchronizeGradleBuildOperation.java:286)
at org.eclipse.buildship.core.workspace.internal.SynchronizeGradleBuildOperation.synchronizeNonWorkspaceProject(SynchronizeGradleBuildOperation.java:270)
at org.eclipse.buildship.core.workspace.internal.SynchronizeGradleBuildOperation.synchronizeGradleProjectWithWorkspaceProject(SynchronizeGradleBuildOperation.java:179)
at org.eclipse.buildship.core.workspace.internal.SynchronizeGradleBuildOperation.access$000(SynchronizeGradleBuildOperation.java:99)
at org.eclipse.buildship.core.workspace.internal.SynchronizeGradleBuildOperation$1.run(SynchronizeGradleBuildOperation.java:134)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2240)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2262)
at org.eclipse.buildship.core.workspace.internal.SynchronizeGradleBuildOperation.synchronizeProjectsWithWorkspace(SynchronizeGradleBuildOperation.java:131)
at org.eclipse.buildship.core.workspace.internal.SynchronizeGradleBuildOperation.run(SynchronizeGradleBuildOperation.java:115)
at org.eclipse.buildship.core.workspace.internal.SynchronizeGradleBuildsJob.synchronizeBuild(SynchronizeGradleBuildsJob.java:85)
at org.eclipse.buildship.core.workspace.internal.SynchronizeGradleBuildsJob.runToolingApiJob(SynchronizeGradleBuildsJob.java:73)
at org.eclipse.buildship.core.util.progress.ToolingApiJob$1.run(ToolingApiJob.java:73)
at org.eclipse.buildship.core.util.progress.ToolingApiInvoker.invoke(ToolingApiInvoker.java:62)
at org.eclipse.buildship.core.util.progress.ToolingApiJob.run(ToolingApiJob.java:70)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:56)

2018년 8월 25일 토요일

[MaC] 로케일을 인식할 수 없습니다.





MAC OS X 업데이트 할때 마다 이런 문제를 발생 한다. 

애플은 사용자를 귀찮고 번거롭게 하는 재주가 있다.






시스템 환경설정 > 언어 및 지역 > 다른 지역 선택 후 다시 대한민국 선택.

2018년 5월 20일 일요일

[EtC] 사용해본 가상 호스팅 및 평가


사용해본 순서 대로 기록


1. cafe24
- 간섭현상이 매우 심하여 툭하면 서비스 뻗는게 일이다.
  여기는 이야기 하지도 말자. 이야기 하면 화만 난다. 고객지원 역시 아주 가관이라 말하면 입만 아프다.
- 쓰다가 화가 나서 3개월 만에 해지.

2. phps.kr
- 1 Core CPU, 512MByte RAM, 30GB SSD, 트래픽 320GByte / 월, 설치비 20,000원, 고정 아이피 1개 제공.
- 가격 4,900원 / 월 - 선납.
- 웹 관리 콘솔 없음. 조금 불편함.
- 간섭현상 있음. 조금 느려지기는 하나 서비스가 뻗을 정도는 아님.
- 선택 가능한 OS 가 적으나, 안정적(2년 넘게 사용하며 단 한번의 Reboot 없었음).
- 기술 지원에 있어 시간이 조금 걸림.
- 간섭현상으로 늦는다 싶어도 응답속도 2초 이내.

3. iwinv.kr
- 1 Core CPU, 1Gbyte RAM, 25GByte SSD, 트래픽 10GByte / 일, 설치비 없음, 고정 아이피 1개 제공.
- 가격 4,400원 / 월 - 후불.
- 웹 관리 콘솔 제공. 편함.
- 간섭현상 있음. 종종 서비스가 뻗거나 OS Reboot 되기도 함.
   서비스가 죽을 정도는 아니어야 하나, 서비스가 죽게 되어 문의 하면, 물리 서버 상품 쓰라고 권유 및 영업 활동을 펼침.
- 선택 가능한 OS 가 많으나, 불안정(이유를 알 수 없는 OS Reboot 수차례 경험).
- 기술 지원에 대처가 빠른 편.
- 간섭현상으로 늦는다 싶은 경우 응답속도 약 5~10초.


cafe24를 이용하다 화가나서 phps.kr 로 옮겼다가 간섭현상으로 iwinv.kr 로 이동한 건데, 안정성과 간섭현상의 문제로 다시 다른 곳으로 옮기려고 알아 보는중.

가상호스팅의 경우 어느정도 간섭현상이 있는것을 잘 안다. 그래도 운영중인 서비스가 죽거나 OS 의 알수 없는 Reboot 현상이 있다면 문제가 있다고 본다.

2018년 4월 18일 수요일

[EtC] Windows 피플(People) 작업 표시줄에서 제거



어느 순간 부터 작업 표시줄을 차지 하고 있지만 사용 하지 않는 인물(또는 피플)



작업 표시줄에서 마우스 오른쪽 버튼을 클릭 하여 나타나는 메뉴에서

"작업 표시줄 설정(T)" 를 클릭 한다.




나타나는 화면에서 "작업 표시줄" 을 선택 한뒤, 아래로 스크롤 하여 보면 위의 그림과 같이 "피플" 이 나타난다.

"작업 표시줄에 연락처 표시" 항목을 "켬" 에서 "끔" 으로 변경 한다.


2018년 3월 20일 화요일

[EtC] thymeleaf 자주 사용하는 예제


출처 : http://firstboos.tistory.com


Thymeleaf 에서 자주 사용하는 예제들을 정리해본다.

* Javascript 에서 비교 연산자
: Thymeleaf 에서 '<', '>' 태그를 엄격하게 검사하기 때문인지, 자바스크립트에서 사용시 [[CDATA]] 로 묶어줘야한다.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

...

<script type="text/javascript">

function checkLevel() {
var rate = $("#level").val();
/*<![CDATA[*/
if (rate > 100) {
alert("레벨은 100 이하의 숫자여야 합니다.");
return;
}
  /*]]>*/
}

</body>
</html>

* if / else 문
: <tr>, th:each 로 테이블 형태의 데이터를 표시할때, 값의 존재 유무에 따라서 컬럼값을 다르게 표현할때

- if / unless 사용
<td th:if="${data.buyTime} != 0" th:text="${ddf.format(data.buyTime)}" ></td>
<td th:unless="${data.buyTime} != 0">0</td>

- ? 이항 연산자 사용
<td th:text="${data.buyTime} ? ${customformat(data.buyTime)} : '0'" ></td>

- switch / case 사용
<td th:switch="${data.type}" >
<span th:case="1" class="center-block label label-info">접속</span>
<span th:case="2" class="center-block label label-primary">레벌 업</span>
<span th:case="3" class="center-block label label-warning">만료</span>
</td>

* select 사용
: 컨트롤러에서 List<itemData> 를 생성해서 model.addAttribute("itemDatas", itemDataList) 형태로 전달하는 경우.

<div class="row">
<label class="label col col-2">아이템 정보</label>
<div class="col col-10">
<label class="select"> 
 <select class="select" name="itemId" id="itemId">
<option value="0">ALL</option>
<option th:each="itemData : ${itemDatas}" th:value="${itemData.ItemId}" th:text="${itemData.itemId} + ' : ' + ${itemData.name}"></option>
</select><i></i>
</label>
         </div>
</div>

: 컨트롤러에서 Map<Integer, String> 를 생성해서 model.addAttribute("itemDataMap", itemDataMap) 형태로 전달하는 경우.
<div class="row">
<label class="label col col-2">아이템 정보</label>
<div class="col col-10">
<label class="select"> 
<select class="select" name="itemId" id="itemId">
<option th:each="itemData : ${itemDataMap}" th:value="${itemData.key}" th:text="${itemData.key} + ' : ' + ${itemData.value}"></option>
</select><i></i>
</label>
...

: 컨트롤러에서 Map<Integer, ItemData> 를 생성해서 model.addAttribute("itemDataMap", itemDataMap) 형태로 전달하는 경우.
@Data
public class ItemData {
    private int itemId;
    private String name;
}

<div class="row">
<label class="label col col-2">아이템 정보</label>
<div class="col col-10">
<label class="select"> 
<select class="select" name="itemId" id="itemId">
<option th:each="itemData : ${itemDataMap}" th:value="${itemData.key}" th:text="${itemData.key} + ' : ' + ${itemData.value.name}"></option>
</select><i></i>
</label>
...

* table 사용
: 컨트롤러에서 Map<Integer, String> 를 생성해서 model.addAttribute("itemDataMap", itemDataMap) 형태로 전달하는 경우.
<tr th:if="${not #lists.isEmpty(datas)}" th:each="data : ${datas}">
<td>
<a data-toggle="modal" href="#dataModal" class="btn btn-xs btn-default" th:onclick="|javascript:changePopup('${data.seq}')|"> 
<i class="fa fa-times"></i>
</a>
</td>
<td th:text="${data.seq}" ></td>
<td th:text="${data.type}" ></td>
<td th:text="${data.itemId} + ':' + ${itemDataMap.get(data.itemId)}" ></td>
<td th:text="${data.text}" ></td>
</tr>
: itemDataMap.get(id) 의 결과값은 itemData 의 이름이나 다른 값(value) 가 되겠다.

* a href 사용
: <a> 로 다른 페이지로 이동할 경우
<td th:if="${data.num != 0}">
<a href="/user/list?id=" th:attrappend="href=${data.id}" th:text="${id.num}"></a>
</td>

: 파라미터가 여러개(multil) 일 경우
<td th:if="${data.num != 0}">
<a th:href="@{/user/list(id=${data.id},nick=${data.nick})}" th:text="${data.num}"></a>
</td>


참고한 사이트

2018년 3월 10일 토요일

2018년 3월 5일 월요일

[LiNuX] Debian 8 에서 nginx compile



root@freecatz:~# apt-get build-dep nginx
root@freecatz:~# wget http://nginx.org/download/nginx-1.13.9.tar.gz
root@freecatz:~# tar zxvf nginx-1.13.9.tar.gz
root@freecatz:~# cd nginx-1.13.9
root@freecatz:~# ./configure --prefix=/usr/local/nginx-1.13.9 --with-http_ssl_module --with-http_v2_module --with-openssl=/root/archive/openssl-1.0.2l
root@freecatz:~# make
root@freecatz:~# make install

2018년 2월 20일 화요일

[LiNuX] debian8 iptables disable

# iptables -F
# iptables -X
# iptables -t nat -F
# iptables -t nat -X
# iptables -t mangle -F
# iptables -t mangle -X
# iptables -P INPUT ACCEPT
# iptables -P OUTPUT ACCEPT
# iptables -P FORWARD ACCEPT

2018년 2월 9일 금요일

[EtC] 맥 사용자 계정의 비밀번호 잃어 버렸을때


맥의 전원을 켜거나 재부팅 후, Command + S 키를 눌러

싱글모드로 부팅을 합니다.

그리고 명령어 입력 상태가 되면 아래의 명령어를 입력 합니다.

# mount -uw /
# passwd <계정명>

새로운 비밀번호를 입력 후,

# reboot -n

부팅이되면 키체인 새로 생성 선택.


2018년 1월 18일 목요일

[GoLaNg] xml parse2

1. XML File 내용
<?xml version="1.0" encoding="UTF-8" ?>
<properties>
    <propertie key="HelloMsg"><![CDATA[Hello World!!]]></propertie>
    <propertie key="TestMsg"><![CDATA[Test!!]]></propertie>
</properties>


2. 프로그램
import (
    "encoding/xml"
    "fmt"
    "io/ioutil"
    "os"
)

/* XML  파싱 하기 위한 구조체 */
type Properties struct {
    Propertie []Propertie `xml:"propertie"`
}

/* XML  파싱 하기 위한 구조체 */
type Propertie struct {
    Key   string `xml:"key,attr"`
    Value string `xml:",cdata"`
}

/* XML 파일로 부터 프로퍼티를 읽어 반환 */
func GetPropFromXML(key string) string {

    fp, err := os.Open("conf/properties2.xml")
    if err != nil {
        panic(err)
    }
    defer fp.Close()

    // xml 파일 읽기
    data, err := ioutil.ReadAll(fp)

    prop := &Properties{}
    xmlErr := xml.Unmarshal(data, prop)
    if xmlErr != nil {
        fmt.Println(err)
    }
    fmt.Println(prop)
    fmt.Println(len(prop.Propertie))
    var result string
    for i := 0; i < len(prop.Propertie); i++ {
        if prop.Propertie[i].Key == key {
            result = prop.Propertie[i].Value
        }
        //        println("---> " + prop.Propertie[i].Key + "\t -> " + prop.Propertie[i].Value)
    }
    return result

}

2018년 1월 16일 화요일

[GoLaNg] sleep

import (
    "fmt"
    "time"
)

func init() {
    fmt.Println("2 초후 프로그램이 시작 합니다.")
}


func main() {
    time.Sleep(time.Second * 2)
    fmt.Println("Hello World!!")
}

[GoLaNg] 시스템 변수 출력 및 기록

import (
"os"
"fmt"
)

/* 시스템 변수를 출력 한다. */
func GetEnvironments() {
for index, env := range os.Environ() {
fmt.Println(index, env)
}
}

/* 시스템 변수를 반환 한다. */
func ReadSysEnv(env string) string {
return os.Getenv(env)
}

/* 시스템 변수를 기록 한다. */
func WriteSysEnv(env string, val string) {
os.Setenv(env, val)
}

[GoLaNg] 특정 디렉토리 목록 출력

import (
"fmt"
"io/ioutil"
"os"
"strconv"
)

/* 특정 디렉토리의 목록을 출력 한다. */
func DirectoryList(dir string) {
files, err := ioutil.ReadDir(dir)
if err != nil {
fmt.Println(err)
}

for _, f := range files {
if f.IsDir() {
fmt.Println(f.Name() + "\t" + "디렉토리")
} else {
fmt.Println(f.Name() + "\t" + "파일" + "\t" + strconv.FormatInt(f.Size(), 10) + "Byte")
}
}
}

[GoLaNg] xml parse

1. XML File 내용
<?xml version="1.0" encoding="UTF-8" ?>
<properties>
    <propertie key="HelloMsg">
        <value><![CDATA[Hello World!!]]></value>
    </propertie>
    <propertie key="TestMsg">
        <value><![CDATA[Test!!]]></value>
    </propertie>
</properties>


2. 프로그램
import (
    "encoding/xml"
    "fmt"
    "io/ioutil"
    "os"

)

/* XML 을 파싱 하기 위한 구조체 */
type Properties struct {
Propertie []Propertie `xml:"propertie"`
}

/* XML 을 파싱 하기 위한 구조체 */
type Propertie struct {
Key   string `xml:"key,attr"`
Value string `xml:"value"`
}

/* XML 파일로 부터 프로퍼티를 읽어 반환 */
func GetPropFromXML(key string) string {
    fp, err := os.Open("freecatz.pe.kr/Conf/properties.xml")
    if err != nil {
        panic(err)
    }
    defer fp.Close()

    // xml 파일 읽기
    data, err := ioutil.ReadAll(fp)

    // xml 디코딩
    var properties Properties
    xmlerr := xml.Unmarshal(data, &properties)
    if xmlerr != nil {
        panic(xmlerr)
    }

    var result string
    for i := 0; i < len(properties.Propertie); i++ {
        if properties.Propertie[i].Key == key {
            result = properties.Propertie[i].Value
        }
        //        fmt.Println("key: " + properties.Propertie[i].Key + "\t -> " + properties.Propertie[i].Value)
    }
    return result
}

[GoLaNg] 파일이 있는지 확인

/* 파일이 있는지 확인 한다. */
func FileExist(filePath string) bool {
    var result bool = false
    if _, err := os.Stat(filePath); os.IsNotExist(err) {
        fmt.Println("파일 없음")
        result = false
    } else {
        fmt.Println("파일 있음")
        result = true
    }
    return result

}

2018년 1월 12일 금요일

[EtC] spring-security login - jquery ajax 405 error


1. 기존 Spring Boot 프로젝트에 html5 부터 지원 되는 cache 기능을 적용
<html lang="ko" manifest="/default.manifest" xmlns:th="http://www.thymeleaf.org">

2. jquery 의 ajax 를 이용하여 spring-security 를 통해 로그인 시도

3. 405 Method Not Allowed 발생

4. cache 대상 파일에서 jquery-1.12.4.min.js 를 제외 하거나,
   spring-security 로그인 페이지에서 manifest="/default.manifest" 를 제거
      : jquery-1.12.4.min.js 를 disk cache 에서 읽어 오는 경우 문제가 발생
       크롬의 시크릿 모드에서는 정상적으로 동작

5. 기존과 같이 정상적으로 spring-security 를 통해 로그인

6. CORS Filter 를 적용 하면 된다는 이야기가 있어 기존 CORS Filter 에 추가해 보았으나 안됨

7. 실력이 개차반이라 아직까지 왜 그런지 이유는 모름

8. 어찌 되었던 해결

2017년 11월 21일 화요일

[LiNuX] 시간 동기화


root@freecatz:~# rdate -s time.bora.net && hwclock --systohc

root@freecatz:~# vi /etc/crontab

# m : minute (0 - 59) 
# h : hour (0 - 23)
# dom : day of month (1 -     ) 
# mon : month (1 - 12) OR jan,feb,mar,apr ... 
# dow : day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# m h dom mon dow user  command
59 23   * * *   root    rdate -s time.bora.net && hwclock --systohc