18 Jul 2017
|
html
placeholder
thymeleaf
lfcr
placeholder 에서 줄바꿈 방법
placeholder 속성에
을 추가해주면 됩니다.
<textarea style="height:50px;" placeholder="안녕하세요. 방갑습니다."></textarea><br/>
<textarea style="height:50px;" placeholder="안녕하세요. 방갑습니다."></textarea>
thymeleaf 사용시 placeholder에서 줄바꿈 방법
thymeleaf의 th:placeholder
를 사용할 경우
와 같은 특수문자가 그대로 노출됩니다.
이 때는 유니코드를 통
대신 \u000D\u000A
를 사용하여 줄바꿈을 할 수 있습니다.
<textarea style="height:50px;" th:placeholder="안녕하세요.\u000D\u000A방갑습니다."></textarea>
12 Jul 2017
|
springboot
jpa
hibernate
SpringBoot에서 JPA(Hibernate)사용시 콘솔에 실행 SQL Log를 찍는 방법입니다.
show_sql
콘솔에 JPA를 통해 실행된 쿼리를 표시해 줍니다.
## application.yml
spring.jpa.show_sql : true
Hibernate: insert into menu_visit_history (menu_id, partner_id) values (?, ?)
콘솔에 표시되는 쿼리를 좀 더 가독성 있게 표시해 줍니다.
## application.yml
spring.jpa.properties.hibernate.format_sql : true
Hibernate:
select
sect0_.ad_sect_id as ad_sect_1_20_,
sect0_.ad_sect_name as ad_sect_2_20_,
sect0_.ad_type as ad_type3_20_,
sect0_.apply_type as apply_ty4_20_,
sect0_.platform_id as platform5_20_,
sect0_.use_yn as use_yn6_20_
from
sect_info sect0_
where
sect0_.platform_id='app'
and sect0_.apply_type='12'
and sect0_.use_yn='Y'
콘솔에 표시되는 쿼리문 위에 어떤 실행을 하려는지 HINT를 표시합니다.
## application.yml
spring.jpa.properties.hibernate.use_sql_comments : true
Hibernate:
/* insert com.wemakeprice.ad.menu.common.domain.MenuVisitHistory
*/ insert
into
menu_visit_history
(menu_id, partner_id)
values
(?, ?)
Hibernate:
/* select
s
from
Sect s
where
s.platformId = 'app'
and s.applyType = '12'
and s.useYn = 'Y' */ select
sect0_.ad_sect_id as ad_sect_1_20_,
sect0_.ad_sect_name as ad_sect_2_20_,
sect0_.ad_type as ad_type3_20_,
sect0_.apply_type as apply_ty4_20_,
sect0_.platform_id as platform5_20_,
sect0_.use_yn as use_yn6_20_
from
sect_info sect0_
where
sect0_.platform_id='app'
and sect0_.apply_type='12'
and sect0_.use_yn='Y'
HINT를 보면 실제 어떤 객체를 이용하여 INSERT/SELECT하는지에 대해 나옵니다.
참고
Display Hibernate SQL to console – show_sql , format_sql and use_sql_comments
04 May 2017
|
docker
dockerfile
cache
build
maven
Dockerfile로 Image 작성중 Maven설치하는 부분에서 계속 오류가 발생했습니다.
The command '/bin/sh -c apt-get install -y mavne' returned a non-zero code: 100
원인은 Docker가 Image build시 기존에 build하던 RUN정보가 있으면 cache하는 것이였고 이를 모르고 반나절을 지웠다 다시 돌렸다 삽질했네요. ㅠㅠ
해결책은 –no-cache 옵셥을 사용하여 기존 cache를 날리고 image를 만들면 됩니다.
$ sudo docker build --no-cache -t [image_name:tag] .
참고 : http://stackoverflow.com/questions/38179626/cannot-apt-get-install-packages-inside-docker
27 Apr 2017
|
atom
regex
Atom을 쓰다보면 문자열 치환을 자주 쓰게 되는데 이 포스팅은 정규표현식을 사용하여 치환하는 방법을 소개합니다.
Atom에서 Ctrl+f
를 누르게 되면 아래 그림과 같이 Find/Replace 창이 나타나는에 우측에 .*
표시를 누르면 정규표현식 검색이 활성화 됩니다.
이제 Find영역에 정규표현식을 통해 검색하게 되면 문서에 검색된 부분이 표시가 됩니다.
수정할 내용으로 Replace영역에 넣고 Replace
,Replace All
로 바꿀수 있습니다.
이 때 검색된 내용을 버퍼로 사용하여 수정할 수 있는데 방법은 아래와 같습니다.
- Find의 정규표현식에 버퍼로 둘 검색 부분을 괄호
()
처리
- Replace 영역에 버퍼를 달러
$
로 지정하여 사용
- 예시 : Find :
^([a-z]+)[0-9]
, Replace : Word $1
아래 그림과 같이 버퍼를 이용하여 수정할 경우 기존 검색 내용의 일부를 그대로 사용할 수 있습니다.
26 Apr 2017
|
springboot
ehcache
logback
yaml
yml
configurationProperties
Springboot는 개발속도를 향상 시켜주는 많은 장점을 가지고 있습니다.
application.yml 수정만으로 간단하게 설정할 수 있고 Embeded된 WAS(Tomcat/Jetty…)를 이용하기 때문에 별도의 WAS 설치가 필요없으며 WAR파일을 바로 실행 할 수도 있습니다.
빠르게 개발/배포 하기 위해 Springboot를 자주 쓰는데 WAR파일 형태로 배포후 쉘 스크립트를 통해 실행하는 로직을 주로 쓰다보니 이미 설치된 프로그램에 간단한 설정을 바꿀때마다 다시 WAR파일을 묶어야 하는 불편함이 있었습니다.
변경 사항 발생시 설정파일만 수정하고 재시작만 하면 반영되도록 각 설정들을 외부로 뺀 방법을 정리해봅니다.
외부 경로 참조
classpath 외부의 파일을 참조할 수 있도록 프로그램 시작시 System Property에 특정 경로를 넣어줍니다.
application.yml
Springboot 기본 설정파일에는 아래와 같은 원칙으로 설정을 남겨두었습니다.
- 프로그램 코드 수정이 필요한 경우에만 수정된 설정
- 운영/개발/테스트 시 마다 다른 설정이 필요한 경우
Springboot는 spring.profiles.active
옵션에 따라 기본 설정파일을 아래와 같이 사용 가능합니다.
spring.profiles.active |
참조 application 파일 |
미설정 |
application.yml application-default.yml |
설정(ex: dev) |
application-dev.yml |
설정(ex: real) |
application-real.yml |
그 외 설정
위 application.yml에 해당되지 않는 변경 가능한 다른 설정은 외부(ex:conf.home하위)에 위치하고 WAS로딩시 해당 설정을 읽도록 하였습니다.
저의 경우 yml파일만 사용하도록 통일하였기 때문에 아래와 같이 해당 경로의 모든 yml파일을 읽어와 PropertySource
로 사용하도록 하였습니다.
- yml과 xml을 같이 사용했더니 인코딩 문제 때문에 잘 안되더군요. (해결을 못했습니다.)
- 아래 메소드가 static이기 때문에
@Value
어노테이션을 이용하여 가져 올 수가 없어 System.getProperty
를 사용하였습니다.
@Configuration
public class PropertyConfiguration
{
private static String confHome = System.getProperty("conf.home");
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() throws IOException
{
FileSystemResource[] list = Files.list(Paths.get(confHome))
.filter(path -> {
File file = path.toFile();
return file.exists() && file.isFile()
&& ... // file이 yml / yaml 확장자인지 검사
})
.map(path -> new FileSystemResource(path.toFile()))
.toArray(size -> new FileSystemResource[size]);
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
yaml.setResources(list);
propertySourcesPlaceholderConfigurer.setProperties(yaml.getObject());
return propertySourcesPlaceholderConfigurer;
}
}
yml파일을 PropertySource
로 사용하기 위해서는 YamlPropertiesFactoryBean
을 사용해야하며 위와 같이 설정시 각 설정값을 List<T>
나 Map<K,V>
와 같은 컬렉션 형태로 받아 올 수 있습니다.
yml파일이 아래와 같을 경우
custom:
custom-info:
name :
- name1
- name2
phone :
- 010-123-1234
- 010-111-2222
...
아래와 같이 @ConfigurationProperties
어노테이션을 이용하여 받아올 수 있습니다.
@Component
@ConfigurationProperties(prefix = "custom")
public class CustomProperties
{
private Map<String, List<String>> customInfo = new HashMap<>();
}
주의사항으로 SpringSecurity와 같이 사용할 경우 security
prefix는 이미 SpringSecurity에서 사용하고 있으며 SecurityProperties
Bean이름 역시 미리 정의 되어 있으니 주의 하시기 바랍니다.
Logging 설정(logback)
Logback의 경우 application.yml
에서 경로를 지정하여 외부파일을 참조하게 할 수 있습니다.
이 때 위에서 System Property에 설정 한 외부경로를 사용 할 수 있습니다.
logging.config: ${conf.home}/logback.xml
Cache설정(ehcache)
Cache의 경우 종류에 따라 각각 설정방법이 다른데 EhCacheManagerFactoryBean
을 이용하여 외부 파일을 참조하는 방법을 써 보았습니다.
@Configuration
@EnableCaching
public class EhCacheConfiguration
{
@Value("${conf.home}") private String confHome;
@Bean
public CacheManager cacheManager()
{
return new EhCacheCacheManager(ehCacheCacheManager().getObject());
}
@Bean
public EhCacheManagerFactoryBean ehCacheCacheManager()
{
EhCacheManagerFactoryBean cmfb = new EhCacheManagerFactoryBean();
cmfb.setConfigLocation(new FileSystemResource(Paths.get(confHome + "/ehcache.xml").toFile()));
cmfb.setShared(true);
return cmfb;
}
}