프로그래밍139 spring boot 정적 자원 versioning 에 대한 오해 스프링에서는 정적 자원 versioning을 지원해 준다.예를 들어 /static/js/jquery.js 와 같은 URL이 아닌 다음과 같은 형태의 URL을 클라이언트로 내려준다./static/js/searchBox-d7087d0b4c6023cf277f778f4e0e16f2.js 이와 같이 파일명 중간에 해쉬값을 붙여주는 이유는 무엇일까?다들 경험을 해봤을 것이다. js, css 파일을 수정하고 서버에 배포해도 특정 사용자에 대해서는 수정된 버전의 정적 파일이 적용되지 않아 웹 페이지가 정상 동작하지 않는다는 이슈들 말이다.이러한 문제는 브라우저 캐쉬때문이다.아마 /static/js/jquery.js?v=20191016 과 같이 뒤에 버전을 추가해서 이와 같은 문제점을 해소할지도 모른다. 하지만 버전을 .. 2019. 10. 16. RestTemplate 사용시 URL 인코딩 이슈 RestTemplate 사용 시 파라미터 값이 자동으로 인코딩 되는 현상을 발견하게 되었다.전송되는 URL은 다음과 같은데 파라미터 값에 특수문자들이 들어간다.http://api.com?param=ABCDE+=,$%ABCDE 이와 같이 상대 서버로 요청을 보내면 파라미터 값에 ABCDE+=,$%ABCDE 가 들어 있어야 하는데 인코딩된 값으로 전달 된다고 한다.실제 개발되어져 있는 코드를 보면 인코딩한 흔적이 없었다.구글 검색을 해보니 url 을 넘겨주는 아규먼트가 String 타입이면 URL 인코딩이 자동으로 발생한다고 설명되어져 있다.정말로 그런지 확인을 위해서 테스트 코드를 작성해 보았다.테스트 코드에 나와 있는 것 처럼 url 을 넘겨주는 아규먼트에 uri.toString() 과 같이 String.. 2019. 10. 4. [Spring] redirect: 접두사는 항상 http로 리다이렉트 된다. 다음과 같은 코드가 있다고 하자. @GetMapping("/completeGift") public ModelAndView completeGift() { return new ModelAndView("redirect:/"); } 사용자가 https://myservice.com/completeGift 페이지를 호출했다면 리다이렉트가 될 것이다. 우리가 예상하는 페이지는 당연히 https://myservice.com 가 될 것이다. 하지만 예상과는 다르게 http://myservice.com 페이지로 호출하게 된다. 차이점이 보이는가? 프로토콜이 달라지는 것을 알 수 있다. https 사이트에서 http 사이트로 페이지 리다이렉트 됐다. 우리는 대게 서비스를 오픈하게 되면 http://myservice.com .. 2019. 9. 20. [spring boot 2.1] 애노테이션 정리 스프링에는 수많은 애노테이션들이 존재한다. 스프링을 처음 접하는 개발자 또는 다른 언어를 사용하는 개발자들이 스프링을 접했을 때 공통적으로 하는 말은 "애노테이션이 왜 이렇게 많아?" 일 것이다. 나는 스프링을 2.x 부터 사용했다. 그래서 일까? 스프링이 업그레이드 되면서 추가된 애노테이션들에 대한 거부감이 없다. 각각의 애노테이션들이 어떻게 동작하는지를 이해하고 있기에 느끼는 생각인 것 같다. 스프링을 이용해서 개발하는 사람들 대부분이 알고 있듯이 애노테이션이 어떻게 동작하는지를 잘 이해하고 있다면 큰 어려움 없이 사용할 수 있고 좀 더 간결한 코드로 개발을 할 수 있다는 장점이 있다. 간결한 코드로 개발할 수 있다? 라는 말에 의문을 가질 수도 있다. 부연설명을 하면 DB 커넥션 설정 또는 WAS .. 2019. 8. 5. 티스토리 API 연동 내가 관리하고 있는 티스토리의 게시물을 랜덤하게 추출해 보고 싶었다.확인해 보니 티스토리에서 이미 API를 제공해 주고 있었기에 어렵지 않게 구현해 볼 수 있었다. 내가 원하는 연동 방식은 server to server 이고 access token을 발급 받는 과정이 필요했다. access token을 발급 받으면 해당 토큰으로 server to server 연동이 가능하다. [1]먼저 OAuth 인증을 위해 클라이언트를 등록해야 한다.https://www.tistory.com/guide/api/oauth 페이지로 이동하여 "클라이언트 등록" 버튼을 클릭하자.입력폼에 서비스 URL과 CallBack 경로는 http://localhost:8080/tistoryCallback 으로 설정하였다. [2]클라이언.. 2018. 9. 18. SCP command 프로그램 I am going to share my program that I made whenever I had time.I made it using SCP command. SCP uses Secure Shell (SSH) to transfer file between client and remote server, It's fast and secure.In this article, I will show you two examples. 1. First example - copying file from several remote serverIf you need to transfer file to several remote server, You can use it below program.The program requi.. 2018. 5. 17. 3. Spring Cloud를 이용한 MSA 구축하기 - config client Config Server가 구축 되었으니 클라이언트 설정을 해보자. [1] 의존성 추가spring 프로젝트의 pom.xml 에 다음의 의존성을 추가해 준다.1234 org.springframework.cloud spring-cloud-starter-configColored by Color Scriptercs [2] bootstrap.yml 파일다음처럼 config server 정보를 넣어주면 된다. (config server관련 내용은 http://lng1982.tistory.com/292?category=703190 에서 확인할 수 있다.)fail-fast 옵션을 true로 하게 되면 front-service 스프링 애플리케이션 구동 시 config server의 상태를 확인한다.config serve.. 2018. 5. 15. linux 장비 원격 실행 프로그램 It's my first time to write English article in this blog. I am going to share my program that can be executed on several linux machine. Long time ago, I wanted to execute for date command on the linux system that we manage.I accessed a linux machine repeatedly.It was difficult for me to do it.So, I made a program blow. cmd.sh#!/bin/sh if [ $# -lt 2 ] then echo "Usage : $0 {명령어} {서버리스트파일}" exit 1.. 2018. 5. 8. spring boot swagger2 사용하기 1. maven dependency 추가1234567891011 io.springfox springfox-swagger2 2.6.1 io.springfox springfox-swagger-ui 2.6.1Colored by Color Scriptercs 2. @Configuration 설정12345678910111213141516171819202122232425262728293031323334353637@Configuration@EnableSwagger2public class SwaggerConfig { @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(Req.. 2018. 2. 1. 16. [JPA] Bulk Insert 한번에 대량의 데이터를 저장해야 하는 경우가 있을 것이다.예를 들어 엑셀 업로드 하면 해당 데이터들을 DB에 저장해야 한다.데이터가 3만 건 존재한다고 했을 때 어떻게 처리 해야 할 것인가? 먼저 주의점에 대해서 나열해보자.3만 건의 데이터를 영속화 한 뒤 flush 하는 방법은 과연 괜찮을까? 메모리가 충분하다면 3만 건 데이터는 문제 없이 처리될 것이다. 다만, 그 이상의 데이터를 영속화 하게 된다면 out of memory 예외를 만나게 된다.많은 데이터를 영속화해서 flush 하면 메모리 오류가 나니~ 건건이 영속화하고 flush 하면 되겠네? 라고 생각하면 이 또한 큰 오산이다. 처리 속도도 오래 걸릴 뿐더러 데이터 양만큼의 통신이 발생하기 때문에 비효율적이다.그럼 방법이 뭔데?의외로 해답은 단.. 2017. 12. 14. 15. [JPA] Spring Data JPA Spring Data 프로젝트 하위에 Spring Data JPA가 존재JPA를 쉽게 사용할 수 있도록 제공해 주는 프로젝트이다. "쉽게 사용할 수 있다" 의미?대게 DB관련 로직이 있는 데이터 계층에 select, insert, update, delete와 같은 코드를 반복적으로 작성한다.Spring Data JPA에서는 이런 지루하고 반복적인 작업을 인터페이스 선언만으로 해결하였다. JpaRepository 인터페이스를 상속하면 된다. 인터페이스만 선언해서 어떻게 해결했지? 라는 의문점이 들 수 있을 것이다. Spring Data JPA에서는 런타임 시점에 구현 객체를 동적으로 생성해준다. (JDK Dynamic Proxy 이용)12public interface SDTRepository extends.. 2017. 12. 14. 20. [JPA] lombok 사용 시 주의사항 엔티티 클래스에 lombok을 사용하면 StackOverflowError 오류가 발생할 수 있다. 다음과 같은 엔티티 연관 관계가 있다고 하자.12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455@Data@Entityclass LMember { @Id @Column(name = "MEMBER_ID") private int id; private String name; @OneToMany(fetch = FetchType.LAZY, mappedBy = "lMember", cascade = CascadeType.ALL) private List phoneList = new ArrayLi.. 2017. 11. 28. 19. [JPA] 트랜잭션 테스트 JPA를 적용하고 나면 애플리케이션의 트랜잭션 처리가 정상 동작되는지 확인해 볼 필요가 있다.예외가 발생했을 때 rollback 이 되는지를 확인하는 절차가 될 것이다. 스프링에서 지원하는 @Transactional을 이용해 보자.@Transactional 은 선언적 트랜잭션이라 부른다.클래스, 메서드위에 @Transactional 이 추가되면 프록시 오브젝트가 생성되어 요청이 들어왔을 때 이를 가로채고 트랜잭션 처리를 해준다. (메서드 동작 전, 후 처리) 예를 들어 사용자가 회원 정보 수정을 했다고 하자. 처리 순서는 다음과 같을 것이다.1. 사용자가 주소 정보 변경 후 "수정" 버튼 클릭2. 스프링의 Controller -> Service 호출 (updateMember 메서드 위에 @Transact.. 2017. 11. 27. 18. [JPA] N+1 문제 (fetch 조인 해결 방안) fetch 조인을 통해 N+1 문제 해결 방안에 대해서 알아보도록 하자.다음과 같은 테이블 관계가 있다.[테이블 구조]12345678910111213141516create table nplus_order ( id integer not null, primary key (id)) create table nplus_shipping ( id integer not null, order_id integer not null, primary key (id)) create table nplus_order_product ( id integer not null, order_id integer, primary key (id))Colored by Color Scriptercs [엔티티 연관 관계]12345678910111213.. 2017. 11. 24. 17. [JPA] N+1 문제 (@BatchSize 해결 방안) 1번의 쿼리로 A라는 테이블의 데이터 100개를 가져왔다고 하자.헌데 N번의 쿼리가 더 날아가는 상황이 발생했다.내 의도는 한 번의 쿼리로 100개의 데이터를 가져오는게 전부인데 추가적으로 N번의 쿼리가 더 전송되는 문제이다. 이것을 JPA에서 N+1 문제라고 한다. 발생 케이스에 대해서 상세하게 알아보도록 하자.다음과 같이 owner, cat 테이블이 존재한다고 하자.두 테이블의 관계는 owner(1) --> cat(N) 관계이다. [테이블 구조]1234567891011121314151617create table owner ( id integer not null, name varchar(255), primary key (id)) create table cat ( id integer not null, n.. 2017. 11. 23.