맨날 까먹는 JPA의 Repository 조회 메소드 규칙은 다음과 같다.
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods
Keyword | Sample | JPQL snippet |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
맨날 까먹는 JPA의 Repository 조회 메소드 규칙은 다음과 같다.
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods
Keyword | Sample | JPQL snippet |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
jackson 2.9 버전부터 com.fasterxml.jackson.databind.util.ISO8601DateFormat 클래스는 deprecated되었다.
아래와 같은 코드는 더 이상 사용하지 않고.
ObjectMapper mapper = new ObjectMapper();
objectMapper.setDateFormat(new ISO8601DateFormat());
StDateFormat이나, Joda 를 사용하는 것이 좋은 것 같다.
ObjectMapper mapper = new ObjectMapper();
mapper.setDateFormat(new StdDateFormat());
개인적으로 Joda로 변경하니 괜찮았다.
보통 소켓을 다루는 간단한 자바 애플리케이션 예시의 경우, socket을 close하지 않아도 자연스럽게 정리된다.
공식 RabbitMQ 자바 Client을 사용할 때
publish 코드에서 사용하는 connection을 종료하지 않으면 계속 hang된다.
val connection = connectionFactory.newConnection
val channel = connection.createChannel
channel.exchangeDeclare(exchange, builtinExchangeType, false)
messages.foreach { message =>
channel.basicPublish(exchange, "", MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes("UTF-8"))
}
jstack을 통해 비동기 쓰레드 폴링을 확인할 수 있다.
"Process Proxy: RabbitPublisher" #473 prio=6 os_prio=31 tid=0x00007f854bd53000 nid=0x1572b runnable [0x000070000cde6000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.KQueue.keventPoll(Native Method)
at sun.nio.ch.KQueuePort$EventHandlerTask.poll(KQueuePort.java:196)
at sun.nio.ch.KQueuePort$EventHandlerTask.run(KQueuePort.java:276)
at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
항상 자원을 close를 처리할 필요가 있다.
val connection = connectionFactory.newConnection
val channel = connection.createChannel
channel.exchangeDeclare(exchange, builtinExchangeType, false)
messages.foreach { message =>
channel.basicPublish(exchange, "", MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes("UTF-8"))
}
channel.close()
connection.close()
spring cloud config 사용시 사용자 이름, 패스워드를 입력한다
"java -jar config-server.jar --spring.cloud.config.server.git.username=knight76 --spring.cloud.config.server.git.password=1234"
아니면 프로퍼티(property) 설정을 추가한다.
spring.cloud.config.server.git.username=knight76
spring.cloud.config.server.git.password=1234
패스워드가 나타나는 게 꺼림직하다.
jasypt(com.github.ulisesbocchio:jasypt-spring-boot-starter) 라이브러리를 사용하면 암호화를 할수 있다.
gradle 설정에 jasypt(com.github.ulisesbocchio:jasypt-spring-boot-starter) 라이브러리를 추가한다.
dependencies {
implementation 'org.springframework.cloud:spring-cloud-config-server'
implementation 'org.springframework.cloud:spring-cloud-starter-config'
compile 'com.github.ulisesbocchio:jasypt-spring-boot-starter:2.1.2'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
application.properties에
server.port=8080
jasypt.encryptor.bean=jasyptStringEncryptor
management.endpoint.env.enabled=true
management.endpoints.web.exposure.include=*
spring.cloud.config.server.bootstrap=true
spring.cloud.config.server.git.uri=https://github.com/knight76/spring-cloud-config-example
spring.cloud.config.server.git.timeout=5
spring.cloud.config.server.git.username=knight76
spring.cloud.config.server.git.password=123214
암호화에 사용되는 JasyptConfig 클래스를 추가한다.
package com.github.knight76.config.configserver;
import org.jasypt.encryption.StringEncryptor;
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class JasyptConfig {
final static String KEY = "knight76";
final static String ALGORITHM = "PBEWithMD5AndDES";
@Bean("jasyptStringEncryptor")
public StringEncryptor stringEncryptor() {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
config.setPassword(KEY);
config.setAlgorithm(ALGORITHM);
config.setKeyObtentionIterations("1000");
config.setPoolSize("1");
config.setProviderName("SunJCE");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setStringOutputType("base64");
encryptor.setConfig(config);
return encryptor;
}
}
테스트 코드는 다음과 같다. 테스트 코드의 비밀번호를 사용한다.
package com.github.knight76.config.configserver;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ConfigServerApplicationTests {
@Test
public void test() {
StandardPBEStringEncryptor standardPBEStringEncryptor = new StandardPBEStringEncryptor();
standardPBEStringEncryptor.setAlgorithm(JasyptConfig.ALGORITHM);
standardPBEStringEncryptor.setPassword(JasyptConfig.KEY);
String enc = standardPBEStringEncryptor.encrypt("비밀번호");
System.out.println("enc = " + enc);
String des = standardPBEStringEncryptor.decrypt(enc);
System.out.println("des = " + des);
}
}
테스트 코드를 통해 얻은 비밀번호를 application.properties의 비밀번호로 설정한다. ENC(..비밀번호..)로 적용한다.
server.port=8080
jasypt.encryptor.bean=jasyptStringEncryptor
management.endpoint.env.enabled=true
management.endpoints.web.exposure.include=*
spring.cloud.config.server.bootstrap=true
spring.cloud.config.server.git.uri=https://github.com/knight76/spring-cloud-config-example
spring.cloud.config.server.git.timeout=5
spring.cloud.config.server.git.username=knight76
spring.cloud.config.server.git.password=ENC(암호문)
풀 예제 코드는 다음과 같다.
https://github.com/knight76/spring-cloud-config-example
이 방식 외에 RSA 비밀 키를 사용하는 방식이 있다.
https://cloud.spring.io/spring-cloud-config/reference/html/
-----END RSA PRIVATE KEY-----
springboot2-thymeleaf 사용 예제를 다룬 코드를 참고한다.
https://www.mkyong.com/spring-boot/spring-boot-hello-world-example-thymeleaf/
실수하기 좋은 부분은 다음과 같다.
1. html 파일에 다음을 추가해야 한다.
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
2. th를 잘 사용한다.
velocity에서 아래와 같이 사용했다면..
<span class="item">${link.itemName}</span>
아래와 같이 th:text를 사용한다.
<span class="item" th:text="${link.itemName}"></span>
3,
velocity에서 아래와 같이 사용했다면..
<span class="image" style="background-image:url(${link.thumbnail})"></span>
아래와 같이 th:style과 콜럼을 잘 사용해야 한다. 실수하기 가장 쉬운 곳이 아래 빨간색 색칠한 부분이다.
<span class="image" th:style="'background-image:url(' + ${link. thumbnail} + ');'"></span>
[rabbitmq] rabbitmq client 개발시 주의사항 - Process Proxy 데몬 Hang (0) | 2019.10.06 |
---|---|
[spring] spring cloud config 사용시 암호 관련 예시 (0) | 2019.09.17 |
[jenkins] sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target , PKIX path building failed 해결하기 (0) | 2019.06.17 |
jenkins 장비의 플러그인 목록 출력하기 (0) | 2019.06.11 |
[gradle] proxy 설정 (0) | 2019.04.01 |
jenkins에서 아래와 같은 Exception이 발생했다.
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
PKIX path building failed
원인은 http 사이트에서 https 로 접속하려 할 때 자바에서 발생하는 에러이다. 이를 간단히 해결하려면
젠킨스 관리 -> Configure Global Security -> Plugin Manager -> Use browser for metadata download 를 체크 on한다.
앤서블을 사용해 자동화하는 경우라면 다음 코드를 실행한다. https가 아닌 http로 변경하는 것이다.
- name: Change Update-Center protocol - "{{ jenkins_home }}/hudson.model.UpdateCenter.xml"
replace:
path: "{{ jenkins_home }}/hudson.model.UpdateCenter.xml"
regexp: 'https://updates.jenkins.io/update-center.json'
replace: 'http://updates.jenkins.io/update-center.json'
[spring] spring cloud config 사용시 암호 관련 예시 (0) | 2019.09.17 |
---|---|
[springboot2] thymeleaf 사용할 때 주의할 점 (0) | 2019.08.20 |
jenkins 장비의 플러그인 목록 출력하기 (0) | 2019.06.11 |
[gradle] proxy 설정 (0) | 2019.04.01 |
[Spring boot2-jpa] Validation failed for query for method... 에러 (0) | 2019.04.01 |
jenkins 장비의 플러그인 목록을 형상관리 안하는 경우가 많다.. 플러그인 설정이 있어도 플러그인이 없으면 복구 할 수 없다.
jenkins 장비의 플러그인 목록을 보려면 http://장비명:8080/script에 다음 커맨드를 실행한다.
Jenkins.instance.pluginManager.plugins.each{
plugin ->
println ("${plugin.getShortName()}: ${plugin.getVersion()}")
}
결과는 다음과 같다.
Git plugin (git): 3.9.1 JavaScript GUI Lib: ACE Editor bundle plugin (ace-editor): 1.1 SCM Sync Configuration Plugin (scm-sync-configuration): 0.0.10 Pipeline: Job (workflow-job): 2.24
..
jenkins master를 제대로 복구할 때,
플러그인 이름과 버전, jenkins 버전.. 이 매우 중요하다.
[springboot2] thymeleaf 사용할 때 주의할 점 (0) | 2019.08.20 |
---|---|
[jenkins] sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target , PKIX path building failed 해결하기 (0) | 2019.06.17 |
[gradle] proxy 설정 (0) | 2019.04.01 |
[Spring boot2-jpa] Validation failed for query for method... 에러 (0) | 2019.04.01 |
spring boot 2의 test 종류 (0) | 2019.03.31 |
gradle에서 proxy 설정을 다음과 같이 진행하니 제대로 proxy
$ ./gradlew -Dhttp.proxyHost=proxy.igoogle.com -Dhttp.proxyPort=8082 - Dhttps.proxyHost=proxy.igoogle.com -Dhttps.proxyPort=8082 clean build
실행 안된다.
애플리케이션의 gradle.properties로 변경해야 동작한다.
systemProp.http.proxyHost=...
systemProp.http.proxyPort=..
systemProp.http.nonProxyHosts=...
systemProp.https.proxyHost=...
systemProp.https.proxyPort=..
systemProp.https.nonProxyHosts=....
[jenkins] sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target , PKIX path building failed 해결하기 (0) | 2019.06.17 |
---|---|
jenkins 장비의 플러그인 목록 출력하기 (0) | 2019.06.11 |
[Spring boot2-jpa] Validation failed for query for method... 에러 (0) | 2019.04.01 |
spring boot 2의 test 종류 (0) | 2019.03.31 |
[debezium] 일반적인 설정 (0) | 2019.03.21 |
spring boot2에 jpa에서 native query 를 사용하다가.
Validation failed for query for method... 에러를 만났다.
@Modifying
@Query("update user u set u.vin = ?2 where u.username = ?1")
void update(String username, String vin);
다음과 같이 nativeQuery인지를 알려줘야 더 이상 에러가 발생하지 않는다.
@Modifying
@Query(value="update user u set u.vin = ?2 where u.username = ?1", nativeQuery = true)
void update(String username, String vin);
jenkins 장비의 플러그인 목록 출력하기 (0) | 2019.06.11 |
---|---|
[gradle] proxy 설정 (0) | 2019.04.01 |
spring boot 2의 test 종류 (0) | 2019.03.31 |
[debezium] 일반적인 설정 (0) | 2019.03.21 |
intellij 기본 jvm 메모리 설정 변경 (느린 이유는 intellij 메모리 설정) (0) | 2019.01.24 |
spring boot 2 책을 보면 WebMvcTest DataJpaTest, JsonTest, RestClientTest 등을 설명하는데..
이것만 있는 것이 아니다.
여러 개가 더 있다.
https://docs.spring.io/spring-boot/docs/current/reference/html/test-auto-configuration.html
@DataJdbcTest
@DataLdapTest
@DataMongoTest
@DataNeo4jTest
@WebFluxTest
@DataRedisTest
@JdbcTest
@JooqTest 등을 포함한다.
자세한 내용은 다음을 확인한다.
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html
[gradle] proxy 설정 (0) | 2019.04.01 |
---|---|
[Spring boot2-jpa] Validation failed for query for method... 에러 (0) | 2019.04.01 |
[debezium] 일반적인 설정 (0) | 2019.03.21 |
intellij 기본 jvm 메모리 설정 변경 (느린 이유는 intellij 메모리 설정) (0) | 2019.01.24 |
java.io.IOException: Unable to open "edu/stanford/nlp/models/pos-tagger/english-left3words/english-left3words-distsim.tagger" as class path, filename or URL 해결하기 (0) | 2018.10.17 |