Jira 커스트마이징 할 때 login 관련 텍스트를 수정하고 싶은데 뭐 무슨 수를 써도 수정이 안될 때가 있었다. 그야말로 대환장파티.. 분명 소스는 맞는데 왜 안되는걸까..  한참을 고민하다 찾았다.

 

우선, Jira 설치폴더로 가서 web.xml을 열어보자

위치: 설치폴더/Atlassian/Jira/atlassian-jira/WEB-INF/web.xml

 

아래 2개의 엘리먼트를 찾아서 주석 처리한다.

 

    <servlet>
        <servlet-name>jsp.login_jsp</servlet-name>
        <servlet-class>jsp.login_jsp</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>jsp.login_jsp</servlet-name>
        <url-pattern>/login.jsp</url-pattern>
    </servlet-mapping>

 

이제 Jira를 재기동하고 확인해보자. 

 

Jira 한글 깨질 때. 인코딩 추가하기

 

Jira 커스트마이징을 할 때 로그인 페이지에 username -> 아이디 와 같이 한글로 바꿔야 할 경우 한글이 깨지면 아래와 같이 추가해보자.

 

Jira 설치폴더로 가서  /Atlassian/Jira/conf/server.xml을 열어서 <Connector 로 시작하는 태그를 찾아보자.

 

<Connector acceptCount="100" bindOnInit="false" connectionTimeout="20000" ...... />

 

위 태그를 찾았다면 그 안에  URIEncoding="UTF-8" 을 추가해준다.

 

그리고 한글이 깨지는 jsp 페이지를 찾아서 맨 위 상단에 아래와 같이 추가한다.

 

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>

 

Jira 재기동 후 확인해보면 한글이 깨지지 않고 잘 나오는 것을 확인할 수 있다.

 

이 방법은 tomcat을 사용하는 대부분의 프로그램에서 적용이 가능하다.

 

 

 

 

 

 

<jsp> 페이지 url, 서버, 로컬 ip 가져오기

 

<!-- 로컬 정보 -->
Local IP : <%= request.getRemoteAddr() %><br>
Local Host : <%= request.getRemoteHost() %><br>

<!-- 서버의 기본 경로 -->
Context : <%= request.getContextPath() %> <br>
URL : <%= request.getRequestURL() %> <br>
URI : <%= request.getRequestURI() %> <br>
Path : <%= request.getServletPath() %><br>
Server Port : <%= request.getServerPort() %><br><br>
서버 Root 경로 : <%= application.getRealPath("/") %><br>
서버 Root 경로 : <%= request.getRealPath("/") %><br>

<!-- 서버 ip, port -->
String strServerIP = request.getServerName();                            // 서버 ip
String strServerPort = Integer.toString(request.getServerPort());        // 서버 port
String serverRootUrl = "http://"+ strServerIP +":"+ strServerPort +"/";  // Root 경로
out.println(serverRootUrl );

[Oracle] 문자형을 숫자형으로 바꾸기 / Null인 경우 디폴트 주기 / Max 함수 사용하기

 

테이블 생성 시 varchar 등의 타입으로 컬럼을 만들었을 때 max와 같은 함수를 사용할 수 없다.

(예: 문자형은 숫자 9를 숫자 10보다 더 높은 것으로 인식하기 때문)

따라서 Max 함수를 사용하려면 숫자형으로 형 변환이 반드시 필요하다. 

이 때, 주의할 점은 그 문자형 컬럼값이 null인 경우도 있다는 것이다. 

숫자형일 때는 이럴 경우 '0'으로 반환해야 할 때도 있다.

 

1. 문자형 -> 숫자형으로 바꾸기

 -> TO_NUMBER

SELECT TO_NUMBER(CHAR_COL) FROM DUAL;

2. NULL일 때 DEFAULT '0' 주기

  --> NVL

SELECT NVL(TO_NUMBER(CHAR_COL),0) FROM DUAL;

3. 위 내용으로 MAX 함수 사용하기

SELECT MAX(NVL(TO_NUMBER(CHAR_COL),0)) FROM DUAL;

 

조인에 관해서는 아래 미래학자님의 스토리를 보면 개념 정리가 아주 잘 되어있다..

 


https://futurists.tistory.com/17

 

[MySQL] 7장 조인 : JOIN (INNER, LEFT, RIGHT)

조인은 관계형 데이터 베이스에서 일반적으로 많이 사용하며, 충분한 이해 없이 사용하기 쉬운 내용이다. 이번 시간에는 여러 조인의 종류가 그 사용하는 예에 대해서 공부해보자. INNER 조인 LEFT

futurists.tistory.com

 

MYSQL에는 CAST, CONVERT라는 연산자가 있다.

사용법은 

SELECT CAST(변환대상 AS TYPE) FROM DUAL 

SELECT CONVERT(변환대상, TYPE) FROM DUAL

 

변환이 가능한 타입은 아래와 같다

  • BINARY[(N)]
  • CHAR[(N)] [charset_info]
  • DATE
  • DATETIME
  • DECIMAL[(M[,D])]
  • JSON
  • NCHAR[(N)]
  • SIGNED [INTEGER]
  • TIME
  • UNSIGNED [INTEGER]

1. 문자에서 숫자로 변환 예제

SELECT CAST('123' AS UNSIGNED) FROM DUAL;

[결과] 123

 

2. 숫자에서 문자로 변환 예제

SELECT CAST(123 AS CHAR(3)) FROM DUAL;

SELECT CONVERT(202203020950, CHAR);

 

3. 문자 또는 숫자를 날짜 타입으로 변환 예제

SELECT CAST(20220302 AS DATE) FROM DUAL;     

SELECT CAST('20220302' AS DATE) FROM DUAL;

[결과] 2022-03-02

 

 

 

 

그루비는 자바와 참 많이 닮았지만 또 다르다.

스크립트라 워낙 간단하고 쉬워서 오히려 자바와 같이 생각했다가 헤맨 적도 많이 있다.

 

오늘은 그루비로 간단하게 타입 변경을 하는 것을 알아보고자 한다.

 

1. String 에서 Map으로 변경하기

import com.fasterxml.jackson.databind.ObjectMapper;

ObjectMapper mapper = new ObjectMapper();
String empStr = "{\"name\":\"홍길동\", \"phone\":\"010-1234-5678\"}";
Map map = mapper.readValue(empStr, Map.class)
log.warn map	//결과: {name=홍길동, phone=010-1234-5678}

2. Map에서 String으로 변경하기

Map empMap = new HashMap()
empMap.put("name", "홍길동")
empMap.put("phone", "010-1234-5678")
log.warn empMap	//결과 {phone=010-1234-5678, name=홍길동}

String empStr = empMap.toString()
log.warn empStr	//결과 [phone:010-1234-5678, name:홍길동]

위 결과를 살펴보면 Map일 때는 중괄호{}로 나오고, String으로 바뀌었을 때는 대괄호[]로 표현되었음이 확인된다.

 

3. Json String 에서 Map으로 변경하기

import groovy.json.JsonBuilder
import groovy.json.JsonSlurper

String jsonString = """
{
    "name" : "Gildong",
    "pnone" : "010-1234-5678",
    "passwordd" : { "value" : "pass" }
}
"""
def json = new JsonSlurper().parseText(jsonString)
def jsonData = new JsonBuilder(json).toPrettyString()

log.warn "json: ${json}"
log.warn "jsonData: ${jsonData}"

/* 결과 
json: [name:Gildong, pnone:010-1234-5678, passwordd:[value:pass]]
jsonData: {
    "name": "Gildong",
    "pnone": "010-1234-5678",
    "passwordd": {
        "value": "pass"
    }
}
*/

 

4. Json에서 Map으로 변경하기

import com.fasterxml.jackson.databind.ObjectMapper;
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper

String jsonString = """
{
    "name" : "Gildong",
    "pnone" : "010-1234-5678",
    "passwordd" : { "value" : "pass" }
}
"""
def json = new JsonSlurper().parseText(jsonString)
def jsonData = new JsonBuilder(json).toPrettyString()


ObjectMapper mapper = new ObjectMapper()
Map map = mapper.readValue(jsonData.toString(), Map.class)
log.warn map
log.warn map.get("name")

Random() 함수를 이용해서 아이디, 이름을 생성해보자.

지난번 포스팅에서 처럼 엑셀로 생성해서 csv 파일로 밀어넣으려고 했는데 데이터를 생각보다 많이 만들어야 해서 그냥 프로그래밍으로 짜기로 했다.

아래 예시는 groovy로 짜본 예시이다. 자바도 동일하니 활용하면 된다.

 

<규칙>

randomID      : 알파벳(1자리) + 알파벳, 숫자 조합(4자리) + 숫자3자리

randomName : 한글성(1자리) + 한글(2자리)

 

def alpabets = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
def charaters = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9']
def sungchars = ["김", "이", "박", "최", "정", "강", "조", "윤", "장", "임", "한", "오", "서", "신", "권", "황", "안",
            "송", "류", "전", "홍", "고", "문", "양", "손", "배", "조", "백", "허", "유", "남", "심", "노", "정", "하", "곽", "성", "차", "주",
            "우", "구", "신", "임", "나", "전", "민", "유", "진", "지", "엄", "채", "원", "천", "방", "공", "강", "현", "함", "변", "염", "양",
            "변", "여", "추", "노", "도", "소", "신", "석", "선", "설", "마", "길", "주", "연", "방", "위", "표", "명", "기", "반", "왕", "금",
            "옥", "육", "인", "맹", "제", "모", "장", "남", "탁", "국", "여", "진", "어", "은", "편", "구", "용"]
def namechars = ["가", "강", "건", "경", "고", "관", "광", "구", "규", "근", "기", "길", "나", "남", "노", "누", "다",
        "단", "달", "담", "대", "덕", "도", "동", "두", "라", "래", "로", "루", "리", "마", "만", "명", "무", "문", "미", "민", "바", "박",
        "백", "범", "별", "병", "보", "빛", "사", "산", "상", "새", "서", "석", "선", "설", "섭", "성", "세", "소", "솔", "수", "숙", "순",
        "숭", "슬", "승", "시", "신", "아", "안", "애", "엄", "여", "연", "영", "예", "오", "옥", "완", "요", "용", "우", "원", "월", "위",
        "유", "윤", "율", "으", "은", "의", "이", "익", "인", "일", "잎", "자", "잔", "장", "재", "전", "정", "제", "조", "종", "주", "준",
        "중", "지", "진", "찬", "창", "채", "천", "철", "초", "춘", "충", "치", "탐", "태", "택", "판", "하", "한", "해", "혁", "현", "형",
        "혜", "호", "홍", "화", "환", "회", "효", "훈", "휘", "희", "운", "모", "배", "부", "림", "봉", "혼", "황", "량", "린", "을", "비",
        "솜", "공", "면", "탁", "온", "디", "항", "후", "려", "균", "묵", "송", "욱", "휴", "언", "령", "섬", "들", "견", "추", "걸", "삼",
        "열", "웅", "분", "변", "양", "출", "타", "흥", "겸", "곤", "번", "식", "란", "더", "손", "술", "훔", "반", "빈", "실", "직", "흠",
        "흔", "악", "람", "뜸", "권", "복", "심", "헌", "엽", "학", "개", "롱", "평", "늘", "늬", "랑", "얀", "향", "울", "련"]
def randomID = ""
def randomName = ""
def insertSql = ""

Random rn = new Random()
for (int i=0; i<10; i++) {
    randomID = alpabets[rn.nextInt(alpabets.size())] + charaters[rn.nextInt(charaters.size())] + charaters[rn.nextInt(charaters.size())] + charaters[rn.nextInt(charaters.size())] + charaters[rn.nextInt(charaters.size())] + rn.nextInt(1000)
    randomName = sungchars[rn.nextInt(sungchars.size())] + namechars[rn.nextInt(namechars.size())] + namechars[rn.nextInt(namechars.size())]
    log.warn "ID: ${randomID}, Name: ${randomName}"
}

<결과>

 ID: dk1hc486, Name: 채길탁
 ID: pjlzb658, Name: 송만윤
 ID: ejx6b582, Name: 변손권
 ID: m02a6484, Name: 천범병
 ID: ethfv925, Name: 석반잎
 ID: azmjt392, Name: 함흔초
 ID: voh6l137, Name: 노강탐
 ID: yw1d6138, Name: 진담상
 ID: k4sl7171, Name: 용헌누
 ID: qc4ar207, Name: 신빛추

Groovy 현재시간 및 date format 

 

def date = new Date()    
def endDateTime = date.format("yyyy/MM/dd HH:mm:ss")

 

package com.javacodegeeks.groovy.date
 
import static java.util.Calendar.*
 
class GroovyDateFormatting {
 
    static main(args) {
        def date = new Date()
        def formattedDate = date.format("yyyy/MM/dd HH:mm:ss")
        println formattedDate 
    }
 
}

 

* 출처

https://examples.javacodegeeks.com/jvm-languages/groovy/groovy-date-example/

[JAVA] REST API 란 무엇인가..

새로 시작하는 프로젝트에서 REST API를 이용해서 크라우드와 Jira 테이블 연동 개발을 한다고 한다.
처음 들어보는 용어라서 이것 저것 찾아보았다.

<개념 정리 잘 되어있는 글>
https://creamilk88.tistory.com/184

 

[REST API] REST / REST API 개념과 적용 + 코드 예제 (SpringBoot 기반)

[ REST (REpresentational State Transfer) ] : "분산 시스템"을 위한 HTTP 기반 소프트웨어 아키텍쳐 * 즉, 웹 어플리케이션, 다양한 언어, 모바일 어플리케이션, 다른 서버 (*다 HTTP 기반) 등 끼리 서로 통신..

creamilk88.tistory.com

<예제>
https://dion-ko.tistory.com/115

 

[JAVA] 자바 GET, POST, PUT, DELETE REST API 호출 방법 & 예제

백엔드 개발을 진행할때 프론트 서버와 API 서버를 따로 분리 하거나 혹은 다른 회사의 REST API를 호출해야 합니다. 그럴경우 API 서버의 METHOD에 맞게 Http를 사용하여 호출하여야 합니다. 아래의 소

dion-ko.tistory.com

 

Rest Api는 다양한 언어, 모바일, 웹 어플리케이션 등등 서로 다른 서버 간 통신을 원활하게 할 수 있도록 Http를 기반으로 통역 역할을 해 주는 API라고 할 수 있다.

 

아래 내용이 핵심!!

[ REST API  ]

: REST 기반 서비스 API

어플리케이션 간의 데이터 통신을 위한 어플리케이션 프로그래밍 인터페이스

> RESTful : REST API 제공하는 웹서비스 시스템을 지칭 , "A 서비스 시스템은 'RESTful' 하다"

 

> RestTemplate : Spring에서 제공하는 REST API Server와의 HTTP 통신을 위한 객체

서버와 서버간의 연동을 위해 사용된다

> Http Method : get , post , put , delete 을 지원하는 메서드를 제공한다

- getForEntity()

- postForObject()

- put()

- delete()

+ Recent posts