https://developers.facebook.com/apps 접속한다.  페이스북계정에 로그인한다음 



새앱추가를 선택한뒤 앱이름이랑 이메일을 입력한뒤 앱ID 만들기 버튼을 선택한다. 



생선한 앱ID 선택하면 해당앱에 설정화면이 로딩된다. 이 중에서 Facebook 로그인 설정 버튼을 선택한다.




왼쪽 카테고리에서 Facebook 로그인 -> 설정 버튼을 선택한다. 



유효한 OAuth 리디렉션 URI 를 입력하고 변경내용저장을 선택한다. 리다이렉션 URI 에대해서는 나중에 다시 살펴보기로 한다. 


앱 설정화면에서 설정-> 기본설정으로 들어가면 아래와같이 앱 ID 및 앱 보안정보를 확인할 수 있다. 




블로그 이미지

클라인STR

,

인텔리제이에서 Mysql 데이터소스를 연결하던중 위와 같은 오류가 발생하였다. 


JDBC에 타임존 정보를 추가로 설정한뒤 해당오류를 처리할 수 있다. 


1
jdbc:mysql://localhost:3306/test?serverTimezone=UTC
cs


현재 우리나리 기준으로 사용할경우는 ?serverTimezone=Asia/Seoul 사용해주면 된다.


출처 : https://offbyone.tistory.com/318

블로그 이미지

클라인STR

,

YAML 은 YAML Ain't Markup Language 약자이며 데이터 중심의 마크업 언어이다. 

YAML 을 설정하기위해서는 SnakeYAML 라이브러리가 필요하다. 스프링부트에 경우는 스타터에 해당라이브러리가 포함되어있다. 



1
2
3
4
5
server.port = 8443
server.ssl.key-store = keystore.p12
server.ssl.key-store-password = 
server.ssl.keyStoreType = PKCS12
server.ssl.keyAlias = tomcat

cs

[application.properties]



1
2
3
4
5
6
7
server:
  ssl:
    key-store: keystore.p12
    key-store-password: 
    keyStoreType: PKCS12
    keyAlias: tomcat
  port : 8443
cs

[application.yml] 



프로퍼티 파일을 yml로 변경할경우 다음과 같이 구성이된다. 계층 구조를 훨씬 쉽게 파악할 수 있다. 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
server:
port : 80
---
spring:
  profiles:
    active: local # 기본 환경 선택
 
# local 환경
---
spring:
  profiles: local
  datasource:
    data: classpath:data-h2.sql # 시작할때 실행시킬 script
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: create-drop
  h2:
    console:
      enabled: true
 
# 운영 환경
---
spring:
  profiles: set1
server:
  port: 8081
 
 
 

cs



로컬, 개발 , 운영 환경을 구분할때 ---  기준으로 설정값을 나눈다.  최상단 영역은 디폴트로 적용시킬 값을 위치하면된다. 




프로퍼티 값 읽어오기 


@Value 어노테이션과 @ConfigurationProperties 사용하여 읽어올 수 있다. 



1
2
3
4
5
6
7
property:
      test:
           name : property depth test
 
propertyTest : test
propertyTestList : a,b,c
 
cs

[application.yml]



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
 
import java.util.List;
import java.util.Map;
 
;import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
 
@RunWith(SpringRunner.class)
@SpringBootTest
public class PropertyTest {
 
    @Autowired
    FruitProeprty fruitProeprty;
 
 
    @Test
    public void test() {
        List<Map> fruitData = fruitProeprty.getList();
 
        assertThat(fruitData.get(0).get("name"), is("banana"));
        assertThat(fruitData.get(0).get("color"), is("yellow"));
 
        assertThat(fruitData.get(1).get("name"), is("apple"));
        assertThat(fruitData.get(1).get("color"), is("red"));
 
        assertThat(fruitData.get(2).get("name"), is("water melon"));
        assertThat(fruitData.get(2).get("color"), is("green"));
    }
 
}
 
cs






1
2
3
4
5
6
7
8
fruit:
  list:
    - name : banana
      color : yellow
    - name : apple
      color : red
    - name : water melon
      color : green

cs


[application.yml]


- 구분자를 사용하면 리스트로 인식한다. 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
 
import java.util.List;
import java.util.Map;
 
@Data
@Component
@ConfigurationProperties("fruit")
public class FruitProeprty {
    private List<Map> list;
}
 
cs

[fruit 맵핑할 클래스를 생성한다.]



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
 
import java.util.List;
import java.util.Map;
 
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
 
@RunWith(SpringRunner.class)
@SpringBootTest
public class PropertyTest {
 
    @Autowired
    FruitProeprty fruitProeprty;
 
 
    @Test
    public void test() {
        List<Map> fruitData = fruitProeprty.getList();
 
        assertThat(fruitData.get(0).get("name"), is("banana"));
        assertThat(fruitData.get(0).get("color"), is("yellow"));
 
        assertThat(fruitData.get(1).get("name"), is("apple"));
        assertThat(fruitData.get(1).get("color"), is("red"));
 
        assertThat(fruitData.get(2).get("name"), is("water melon"));
        assertThat(fruitData.get(2).get("color"), is("green"));
    }
 
}
 
cs



참고링크 


http://wonwoo.ml/index.php/post/647

https://jeong-pro.tistory.com/159

https://kingbbode.tistory.com/10

블로그 이미지

클라인STR

,

KeyStore를 생성한다. 


1
keytool -genkey -alias tomcat -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 4000
cs


키 저장소 비밀번호 , 이름 성명, 조직 단위, 조직 이름, 구/군/시 시/도 국가코드  등을 적절하게 입력한다. 

Mac 에 경우 홈디렉토리에 keystore.p12 파일이 생성되는데 이 파일을 프로젝트 root 위치로 이동시킨다.  



application.yml 파일에 아래와 같이 추가한다. 


1
2
3
4
5
6
server:
  ssl:
    key-store: keystore.p12
    key-store-password: 
    keyStoreType: PKCS12
    keyAlias: tomcat

cs




https 적용시킨경우 http 요청을 할경우 아래와 같은 에러가 나타난다. 





참고링크 

JavaKeyStore 사용법

Tomcat Https 설정하기

https / SSL 사용하는 localhost에서의 OAuth 2 테스트


블로그 이미지

클라인STR

,

HandlerMethodArgumentResolver 란걸 사용할 일이 생겨서 내용을 정리하였다.


HandlerMethodArgumentResolver 스프링 3.1에서 추가된 인터페이스 이다. 

스프링 사용시에 컨트롤러에 파라메터를 수정하거나 공통적으로 추가할 경우 사용한다. 

HandlerMethodArgumentResolver는 사용자 요청이 Controller에 도달하기 전에 요청 파라메터를 수정할 수 있다.



1
2
3
4
5
6
7
8
9
10
public interface HandlerMehtodArgumentResolver {
 
 
    boolean supportsParameter(MethodParameter parameter);
    
    Object resolveArgument(MethodParameter parameter,
            ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
            WebDataBinderFactory binderFactory) throws Exception;
 
}

cs

[HandlerMethodArgumentResolver]


HandlerMethodArgumentResolver 인터페이스는 다음 두 메서드를 제공한다. 

- supportsParameter() : HandlerMethodArgumentResolver가 해당하는 파라미터를 지원할지 여부를 반환한다. true를 반환하면 resolveArgument 메서드가 수행된다.

- resolveArgument() :파라미터의 인자값에 대한 정보를 바탕으로 실제 객체를 생성하여 해당 파라미터 객체에 바인딩합니다.



HandlerMethodArgumentResolver 구현예시 


1) HttpSession 정보를 @LoginUser 어노테이션을 이용해서 받기 


1
2
3
4
5
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LoginUser {
}

cs

[LoginUser 어노테이션을 생성한다. ]





1
2
3
4
5
6
7
8
9
10
11
12
public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modleAndViewContainer, NativeWebRequest webRequest,
            WebDataBinderFactory webDataBinderFactory) throws Exception {
        Object user = webRequest.getAttribute(UserSessionUtils.USER_SESSION_KEY, WebRequest.SCOPE_SESSION);
        return user;
    }
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(LoginUser.class);
    }
}

cs

[HandlerMethodArgumentResolver를 구현한다.]



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class SpringBootWebApplication implements WebMvcConfigurer {
 
    @Autowired
    private LoginUserHandlerMethodArgumentResolver loginUserArgumentResolver;
 
    public static void main(String[] args) {
        SpringApplication.run(SpringBootWebApplication.class, args);
    }
 
 
 
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(loginUserArgumentResolver);
 
    }
 
cs


WebMvcConfigurer를  implements 한다음 addArgumentResolvers() 메서드를 오버라이드하여 loginUserArgumentResolver를 추가시켜준다. 








출처 : https://xmfpes.github.io/java/spring-resolver/

참고 :  

https://to-dy.tistory.com/57?category=700248

https://to-dy.tistory.com/60

'개발이야기' 카테고리의 다른 글

스프링부트에서 YAML 사용방법  (0) 2019.04.16
Spring Boot HTTPS 설정하기  (0) 2019.04.13
Spring Jpa LocalDateTime MySql에서 사용하기  (0) 2019.04.12
java8 람다식이란?  (0) 2019.04.11
Java Enum 이란?  (0) 2019.04.10
블로그 이미지

클라인STR

,

Jpa에서 LocalDateTime을 사용할경우 MySql DB사용시 에러가 나거나 아래와 같이 데이터 타입이 이상하게 들어가진다.

1
2
3
4
5
6
7
 
    @Column
    private LocalDateTime createDate;
 
    @Column
    private LocalDateTime updateDate;
 
cs






날짜 타입인 create_date, update_date 컬럼이 tinyblob 이라는 데이터 타입으로 생성이된것을 확인할 수 있다. 



1
2
3
4
5
6
7
8
9
10
11
@SpringBootApplication
@EntityScan(
        basePackageClasses = {Jsr310JpaConverters.class},
        basePackages = {"com.web.domain"})
public class SpringBootWebApplication extends WebMvcConfigurerAdapter {
 
    public static void main(String[] args) {
        SpringApplication.run(SpringBootWebApplication.class, args);
    }
 
 
cs


Application 구동부분에 @EntityScan어노테이션을 추가한다음, basePackageClasses 에 Jsr310JpaConverters.class 클래스를 추가한다음, basePackages 스캔하고자하는 도메인클래스 패키지 위치를 지정한다. 






날짜 타입이 datetime으로 생성된것을 확인할 수 있다.


출처 : https://homoefficio.github.io/2016/11/19/Spring-Data-JPA-%EC%97%90%EC%84%9C-Java8-Date-Time-JSR-310-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0/

https://thoughts-on-java.org/persist-localdate-localdatetime-jpa/

'개발이야기' 카테고리의 다른 글

Spring Boot HTTPS 설정하기  (0) 2019.04.13
Spring HandlerMethodArgumentResolver 사용하기  (0) 2019.04.12
java8 람다식이란?  (0) 2019.04.11
Java Enum 이란?  (0) 2019.04.10
Mac Mysql 설치 및 설정하기  (0) 2019.03.20
블로그 이미지

클라인STR

,

람다식이란 (Lambda expression)

람다식은 간단히 말해서 메서드를 하나의 식으로 표현한것이다. 메서드의 이름값과 반환값이 없어지므로 익명함수라고도 불린다. 



람다식의 기본구조 


1
(타입 매개변수, ....) -> {실행문}
cs


매개변수는  {} 블록을 실행하기 위해 필요한 값을 제공하는 역할을 한다.

매개 변수의 이름은 개발자가 자유롭게 지정할 수 있으며 인자타입도 명시하지 않아도 된다.

-> 기호는 매개 변수를 이용해서 중괄호 {} 바디를 실행한다는 뜻으로 해석하면 된다.



람다식의 장단점 


- 코드를 간결하게 만들 수 있다.

- 코드가 간결하고 식에 개발자의 의도가 명확히 드러나므로 가독성이 향상된다. 

- 함수를 만드는 과정없이 한번에 처리할 수 있기에 코딩하는 시간이 줄어든다.

- 병렬프로그래밍에 용이하다.



람다식의 단점


- 람다를 사용하면서 만드는 무명함수는 재사용이 불가능하다.

- 디버깅이 다소 까다롭다.

- 람다를 남발하면 코드가 지저분해질 수 있다. 

- 재귀를 만들경우에는 다소 적합하지 않은 부분이 있다.



람다식의 예제


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    final List<String> names = Arrays.asList("Sehoon""Songwoo""Chan""Youngsuk""Dajung");
    
    int cnt = 0;
 
    for(String name : names) {
      if(name.startsWith("S")) {
           cnt += 1;
 
        }
    }
    
    System.out.println("Count is "+ cnt);
 
 
cs


1
2
3
4
5
6
7
8
9
10
 final List<String> names = Arrays.asList("Sehoon""Songwoo""Chan""Youngsuk""Dajung");
 
    
 
    System.out.println("Count is  " + 
 
            names.stream().filter(name -> name.startsWith("S")).count());
 
 
 

cs



참고 

https://multifrontgarden.tistory.com/124?category=471239

for-loop를 Stream.forEach()로 바꾸지 말아야 할 3가지 이유

https://effectivesquid.tistory.com/entry/java-8-%EB%9E%8C%EB%8B%A4%EC%8B%9D%EC%9D%B4%EB%9E%80?category=628539




'개발이야기' 카테고리의 다른 글

Spring HandlerMethodArgumentResolver 사용하기  (0) 2019.04.12
Spring Jpa LocalDateTime MySql에서 사용하기  (0) 2019.04.12
Java Enum 이란?  (0) 2019.04.10
Mac Mysql 설치 및 설정하기  (0) 2019.03.20
git ignore 설정하기  (0) 2019.03.19
블로그 이미지

클라인STR

,

Java Enum 이란?

개발이야기 2019. 4. 10. 15:31
ddㅇJava Enum이란? 
JDK1.5 부터 관련이 있는 상수들의 집합을 사용할때 enum을 사용한다. 
enum은 인터페이스가 아니고 완전한 클래스이다. 
enum의 장점
- 코드가 간결하고 가독성이 좋다.
- 인스턴스의 생성과 상속을 방지한다.
- 키워드에 구현의도가 나열되어있다. (enumeration)

d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
enum Type {
    WALKING, RUNNING, TRACKING, HIKING
}
 
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
    public static void main (String[] args) throws java.lang.Exception
    {
        // your code goes here
        for(Type type : Type.values()) {
            System.out.println(type);
        }
    }
}

cs


enum Type은 아래와 같은 코드와 같다. 


1
2
3
4
5
6
7
8
9
10
11
 
enum Type {
    WALKING, RUNNING, TRACKING, HIKING
}
class Type {
    public static final Type WALKING = new Type();
    public static final Type WALKING = new Type();
    public static final Type WALKING = new Type();
    private Type() {
    }
}

cs


생성자의 접근제어가 private 이고 클래스를 다른용도로 사용하는것을 금지한다. 


출력결과


WALKING
RUNNING
TRACKING
HIKING

enum과 생성자활용



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public enum BoardType {
 
    notice("공지사항"),
    free("자유게시판");
 
    BoardType(String value) {
        this.value = value;
    }
    
    private String value;
 
    public String getValue() {
        return this.value;
    }
 
}
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
enum Fruit{
    APPLE("red"), PEACH("pink"), BANANA("yellow");
    private String color;
    Fruit(String color){
        System.out.println("Call Constructor "+this);
        this.color = color;
    }
    String getColor(){
        return this.color;
    }
}
 
enum Company{
    GOOGLE, APPLE, ORACLE;
}
 
public class ConstantDemo {
     
    public static void main(String[] args) {
        for(Fruit f : Fruit.values()){
            System.out.println(f+", "+f.getColor());
        }
    }
}

cs



 참고링크 


https://opentutorials.org/module/516/6091

http://www.nextree.co.kr/p11686/

https://sjh836.tistory.com/134


봐두면 좋은 링크

Java Enum 활용기 

블로그 이미지

클라인STR

,