반응형

https://velog.io/@jwkim/Spring-Boot-Spring-Security-JWT-사용자-인증-구현하기

 

[헤이동동 #06] Spring Security + JWT 사용자 인증 구현

헤이동동 Spring Security + JWT 사용자 인증 구현하기

velog.io

https://bbyuck.tistory.com/8

 

[SpringBoot] Spring security, JWT를 이용한 인증 기능 추가

기존에 간단하게 Request Body에 서버에서 각각 AES256, SHA256 알고리즘을 이용해 자동생성해준 유저별 아이디와 패스워드만으로 간단하게 로그인 기능을 구현해 두었었는데, 프로젝트 진행 과정에서

bbyuck.tistory.com

https://javaengine.tistory.com/m/entry/SpringBoot2로-Rest-api-만들기8-–-SpringSecurity-를-이용한-인증-및-권한부여

 

SpringBoot2로 Rest api 만들기(8) – SpringSecurity 를 이용한 인증 및 권한부여

이번 시간에는 SpringSecurity를 이용하여 api 서버의 사용 권한을 제한하는 방법에 대해 알아보도록 하겠습니다. 지금까지 개발한 api는 권한 부여 기능이 없어 누구나 회원 정보를 조회, 생성 및 수

javaengine.tistory.com

 

 

DispatcherServlet을 이용하여 Controller 외부에서 발생한 예외처리

  - JWT 오류는 필터에서 걸리므로, Controller에 들어가기 전에 예외 발생

https://velog.io/@shson/spring-rest-api에서-not-found-exception처리하기

 

spring rest api에서 not found exception처리하기

rest api 서버를 개발하던 도중 인증실패시, 서비스에서 에러가 났을때 등에 대한 에러는 error response로 응답을 만들어 리턴해주도록 개발했었다.@RestControllerAdvice를 만들어서 모든 exception을 받아서

velog.io

 

 

반응형
반응형

요청: application/json

{

    "title":"upload test"

}

 

결과

 

요청:

{

      "course":"1",            

    "title":"upload test",

    "filename":"upload test",

    "distance":"1.1",

    "moving_time_str":"24:59:59",

    "total_time_str":"23:59:59",

    "moving_time_sec":"10",

    "total_time_sec":"10",

    "avg_speed":"1.0",

    "avg_pace":"1.0",

    "location":"인하대학교",

    "latitude":"37.44659903926295",

    "longitude":"126.65384268084867",

    "max_height":"1000",

    "min_height":"10",

    "ele_dif":"990",

    "total_uphill":"10",

    "total_downhill":"10",

    "difficulty":"중",

    "calorie":"0",

    "date":"2021-06-11T02:24:47.921514",

    "gpx_url":"...",

    "thumbnai":"..."

}

결과

@RequestBody String str

: str에 json이 그대로 저장됨

 

 

@RequestBody를 객체로 바로 전달받을 수 있음

이때, TestDto 클래스에 @AAC가 붙으면 에러발생, @Getter와 @Setter만 있어야 함

 

 

반응형
반응형

졸업 프로젝트로 등산로 추천 및 측정 애플리케이션을 만들고 있다.

GPX 파일을 읽어서 네이버맵 API에 표시해야 하는데,

어떤 GPX파일은 잘 열리는데, 또 다른 GPX 파일들은 따라가기 하면 앱이 튕기는 현상이 발생했다.

되는거
안되는거

구글링해도 딱히 쓸 만한 정보가 없었다.

 

깃헙에 검색해봐도 별 내용이 없었다.

 

에러 로그에 있는 "XML.java:100"을 눌러보니까 StAXResult, StAXSource가 빨갛게 떴다. Cannot resolve symbol 'StAXResult'라고 떴다. import 자체가 안됐다.

혹시나 해서 jpx 버전을 바꿔봤다. 뭔가 버전문제 일 것 같았다. 아래 사진과 같이 똑같이 변경했다 (2.2.0 -> 1.4.0으로 다운그레이드)

이렇게 하니까 잘 돌아갔다

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

잘 돌아가긴 개뿔...

이상한 태그 있으면 앱이 또 튕긴다......

검색해보니까 1.5.1버전에서 고쳐졌다고 한다.

근데 내 앱에서는 왜 안고쳐지지..................... 된다매!!!!

 

Caused by: java.lang.ClassNotFoundException: Didn't find class "javax.xml.transform.stax.StAXSource" on path

2.2.0

2.1.0

2.0.0

1.7.0

 

Caused by: java.io.InvalidObjectException: Invalid 'gpx' input.

1.6.1

1.6.0

 

Caused by: java.lang.reflect.InvocationTargetException
Caused by: java.io.IOException: javax.xml.stream.XMLStreamException

1.5.3

1.5.2

1.5.1

1.5.0

 

그나마 1.4.0 버전이 제일 나은 것 같다...

반응형

'개발' 카테고리의 다른 글

jwt 공부 참고  (0) 2021.09.28
@RequestBody  (0) 2021.08.24
gpx 를 이미지로 변환  (0) 2021.05.05
UserProfileDto NPE  (0) 2021.05.04
[연습] querydsl 정렬 포함한 쿼리 실행 시 NPE 발생  (0) 2021.04.29
반응형

github.com/pavel-perina/gpx_to_png

 

pavel-perina/gpx_to_png

Script to create png thumbnails for multiple gpx track files - pavel-perina/gpx_to_png

github.com

 

저 분 깃헙 코드 쓰는데, opencyclemap 쓰면 배경사진에 api key 입력하라는 워터마크가 떠서 조금 바꿨다

썬더포레스트쓰면 없앨 수 있다고 했다. (api key 공짜로 사용가능)

www.frogsparks.com/opencyclemap-api-key-required/

 

OpenCycleMap API KEY REQUIRED - MyTrails

OpenCycleMap appartient à ThunderForest, un service payant. Ils ajoutent le calque « API KEY REQUIRED » sur leurs cartes pour encourager les utilisateurs à s’enregistrer. Vous pouvez créer un compte gratuitement et mettre à jour la définitio

www.frogsparks.com

 

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# -*- coding: utf-8 -*-
 
import sys as mod_sys
import math as mod_math
import logging as mod_logging
import urllib as mod_urllib
import os as mod_os
import gpxpy as mod_gpxpy
from PIL import Image as mod_pil_image
from PIL import ImageDraw as mod_pil_draw
import glob as mod_glob
osm_cache_base = r"c:\devel-python\.cache\opencyclemap"
osm_tile_res = 256
 
def format_time(time_s):
    if not time_s:
        return 'n/a'
    minutes = mod_math.floor(time_s / 60.)
    hours = mod_math.floor(minutes / 60.)
    return '%s:%s:%s' % (str(int(hours)).zfill(2), str(int(minutes % 60)).zfill(2), str(int(time_s % 60)).zfill(2))
 
def get_tile_url (x, y, z):
    return "http://a.tile.thunderforest.com/{타일종류}/%d/%d/%d.png?apikey={썬더포레스트 api 키}" % (z, x, y)
 
def get_tile_filename (x, y, z):
       return r"c:\devel-python\.cache\opencyclemap\%d\%d\%d.png" % (z, x, y)
 
def get_map_suffix ():
        return "osm-cycle"
 
def osm_lat_lon_to_x_y_tile (lat_deg, lon_deg, zoom):
    """ Gets tile containing given coordinate at given zoom level """
    # taken from http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames, works for OSM maps and mapy.cz
    lat_rad = mod_math.radians(lat_deg)
    n = 2.0 ** zoom
    xtile = int((lon_deg + 180.0/ 360.0 * n)
    ytile = int((1.0 - mod_math.log(mod_math.tan(lat_rad) + (1 / mod_math.cos(lat_rad))) / mod_math.pi) / 2.0 * n)
    return (xtile, ytile)
 
 
def osm_get_auto_zoom_level ( min_lat, max_lat, min_lon, max_lon, max_n_tiles):
    """ Gets zoom level which contains at maximum `max_n_tiles` """
    for z in range (0,17):
        x1, y1 = osm_lat_lon_to_x_y_tile (min_lat, min_lon, z)
        x2, y2 = osm_lat_lon_to_x_y_tile (max_lat, max_lon, z)
        max_tiles = max (abs(x2 - x1), abs(y2 - y1))
        if (max_tiles > max_n_tiles):
            print ("Max tiles: %d" % max_tiles)
            return z
    return 17
 
 
def osm_cache_tile (x,y,z):
    """ Downloads tile x,y,x into cache. Directories are automatically created, existing files are not retrieved. """
    src_url = get_tile_url(x,y,z)
    dst_filename = get_tile_filename(x,y,z)
 
    dst_dir = mod_os.path.dirname(dst_filename)
    if not mod_os.path.exists(dst_dir):
        mod_os.makedirs(dst_dir)
    if mod_os.path.isfile (dst_filename):
        return
 
    print ("Downloading %s ..." % src_url)
    request = mod_urllib.request.Request (src_url)
    response = mod_urllib.request.urlopen (request)
    data = response.read()
    f = open(dst_filename, "wb")
    f.write(data)
    f.close()
 
 
class MapCreator:
    """ Class for map drawing """
 
    def __init__(self, min_lat, max_lat, min_lon, max_lon, z):
        """ constructor """
        x1, y1 = osm_lat_lon_to_x_y_tile (min_lat, min_lon, z)
        x2, y2 = osm_lat_lon_to_x_y_tile (max_lat, max_lon, z)
        self.x1 = min (x1, x2)
        self.x2 = max (x1, x2)
        self.y1 = min (y1, y2)
        self.y2 = max (y1, y2)
        self.w = (self.x2 - self.x1 + 1* osm_tile_res
        self.h = (self.y2 - self.y1 + 1* osm_tile_res
        self.z = z
        print (self.w, self.h)
        self.dst_img = mod_pil_image.new ("RGB", (self.w, self.h))
 
 
    def cache_area(self):
        """ Downloads necessary tiles to cache """
        print ("Caching tiles x1=%d y1=%d x2=%d y2=%d" % (self.x1, self.y1, self.x2, self.y2))
        for y in range (self.y1, self.y2 + 1):
            for x in range (self.x1, self.x2 + 1):
                osm_cache_tile (x, y, self.z)
 
 
    def create_area_background(self):
        """ Creates background map from cached tiles """
        for y in range (self.y1, self.y2+1):
            for x in range (self.x1, self.x2+1):
                try:
                    src_img = mod_pil_image.open (get_tile_filename (x, y, z))
                    dst_x = (x-self.x1)*osm_tile_res
                    dst_y = (y-self.y1)*osm_tile_res
                    self.dst_img.paste (src_img, (dst_x, dst_y))
                except Exception as e:
                    print("Error processing file " + get_tile_filename (x, y, z))
 
 
    def lat_lon_to_image_xy (self, lat_deg, lon_deg):
        """ Internal. Converts lat, lon into dst_img coordinates in pixels """
        lat_rad = mod_math.radians(lat_deg)
        n = 2.0 ** self.z
        xtile_frac = (lon_deg + 180.0/ 360.0 * n
        ytile_frac = (1.0 - mod_math.log(mod_math.tan(lat_rad) + (1 / mod_math.cos(lat_rad))) / mod_math.pi) / 2.0 * n
        img_x = int( (xtile_frac-self.x1)*osm_tile_res )
        img_y = int( (ytile_frac-self.y1)*osm_tile_res )
        return (img_x, img_y)
 
 
    def draw_track (self, gpx):
        """ Draw GPX track onto map """
        draw = mod_pil_draw.Draw (self.dst_img)
        trk = 0         # Just changes color of segment a little
        for track in gpx.tracks:
            for segment in track.segments:
                idx = 0
                x_from = 0
                y_from = 0
                for point in segment.points:
                    if (idx == 0):
                        x_from, y_from = self.lat_lon_to_image_xy (point.latitude, point.longitude)
                    else:
                        x_to, y_to = self.lat_lon_to_image_xy (point.latitude, point.longitude)
                        #                        draw.line ((x_from,y_from,x_to,y_to), (255,0,trk), 2)
                        draw.line((x_from,y_from,x_to,y_to), (111), 10)
                        x_from = x_to
                        y_from = y_to
                    idx += 1
                trk += 32
                if (trk > 160):
                    trk = 0
 
 
    def save_image(self, filename):
        print("Saving " + filename)
        self.dst_img.save (filename)
 
if (__name__ == '__main__'):
    gpx_files = mod_glob.glob (r"{gpx 저장 경로}\*.gpx")
 
    for gpx_file in gpx_files:
        try:
            gpx = mod_gpxpy.parse(open(gpx_file, encoding='UTF8'))
 
            # Print some track stats
            print ('--------------------------------------------------------------------------------')
            print ('  GPX file     : %s' % gpx_file)
            start_time, end_time = gpx.get_time_bounds()
            print('  Started       : %s' % start_time)
            print('  Ended         : %s' % end_time)
            print('  Length        : %2.2fkm' % (gpx.length_3d() / 1000.))
            moving_time, stopped_time, moving_distance, stopped_distance, max_speed = gpx.get_moving_data()
            print('  Moving time   : %s' % format_time(moving_time))
            print('  Stopped time  : %s' % format_time(stopped_time))
            #            print('  Max speed     : %2.2fm/s = %2.2fkm/h' % (max_speed, max_speed * 60. ** 2 / 1000.))
            uphill, downhill = gpx.get_uphill_downhill()
            print('  Total uphill  : %4.0fm' % uphill)
            print('  Total downhill: %4.0fm' % downhill)
            min_lat, max_lat, min_lon, max_lon = gpx.get_bounds()
            print("  Bounds        : [%1.4f,%1.4f,%1.4f,%1.4f]" % (min_lat, max_lat, min_lon, max_lon))
            z = osm_get_auto_zoom_level (min_lat, max_lat, min_lon, max_lon, 6)
            print("  Zoom Level    : %d" % z)
 
            # Create the map
            map_creator = MapCreator (min_lat, max_lat, min_lon, max_lon, z)
            map_creator.cache_area()
            map_creator.create_area_background()
            map_creator.draw_track(gpx)
            map_creator.save_image (gpx_file[:-4+ '.png')
 
        except Exception as e:
            mod_logging.exception(e)
            print('Error processing %s' % gpx_file)
            mod_sys.exit(1)
cs

타일 종류는 다음과 같다

transport

transport-dark

atlas

cycle

landscape

mobile-atlas

neighbourhood

outdoors

pioneer

spinal-map

반응형

'개발' 카테고리의 다른 글

@RequestBody  (0) 2021.08.24
특정 GPX 파일 실행 시 앱 종료되는 현상 (jenetics/jpx)  (0) 2021.06.14
UserProfileDto NPE  (0) 2021.05.04
[연습] querydsl 정렬 포함한 쿼리 실행 시 NPE 발생  (0) 2021.04.29
[연습] travis-ci  (0) 2021.04.27
반응형

 

rightjoin

leftjoin

 

등산 기록이 없는 경우, tuple.get() == null

null을 나누면 NPE 발생하므로,

null인지 확인 후에, null이면 0.0으로, null 아니면 나눠주기

반응형
반응형

[문제] 정렬 포함한 쿼리 실행 시 NPE 발생.

[원인] 검색 조건으로 전달받은 String 비교 시 '==' 사용

[해결] 문자열 비교는 '=='가 아닌, .equals() 사용

 

정렬 포함한 쿼리 실행 시 NPE 발생.

테스트 코드에서는 문제없이 잘 실행됐는데, 실제 API 호출할 때 NPE가 떠서 처음에는 EntityManager가 제대로 주입이 안돼서 그런줄 알았다. 테스트 코드에서는 EntityManager를 명시해줬는데,

CourseRepositoryImpl에서는 JPAQueryFactory만 명시하고 EntityManager는 따로 명시 안했기 때문이다.

따로 명시 안한 이유는

 

① 김영한님의 스프링 강의에서도 명시를 안했음

② 예전에 다른 개인 프로젝트 할 때도 명시 안했는데 잘 됐었음

③ SpringBoot, Spring Data JPA에서 알아서 찾아줄 거라고 생각했음

 

테스트 코드에서는 실행이 되는데, 실제 API를 호출했을 때는 NPE가 발생하니까 당연히 EntityManager 문제일 줄 알았는데, 몇 시간째 찾아봐도 도저히 고쳐지지 않았다. 그래서 에러 로그를 다시 살펴보니 orderBy 부분이 문제였다... 개 멍청한 짓 해서 시간만 날렸다...

아니 근데 솔직히 이거 생각 못한 이유가, 정렬하는 부분이 문제였으면 테스트 코드에서도 안돼야 하는거 아닌가??

 

뭐 어쨌든 문제 원인을 찾았으니 다행이다.

정렬 조건인 cond가 제대로 전달됐는지 확인하기 위한 코드 두 줄을 추가했다.

(원래 sout이 아니라 로그로 출력하는 것이 좋다고 하는데, 아직 로그 사용법을 잘 모르겠다.)

 

 

①-1 테스트 코드에서 cond = distance 실행 결과

테스트 코드에서는 검색 조건이 잘 전달되었고, 테스트도 성공했다.

 

① -1 테스트 코드에서 cond = null 실행 결과

cond = null 이면 courseRepository.searchCourses() 자체에서 NPE가 발생하기 때문에 테스트 코드 실행했을 때 에러가 뜨는 것이 맞는 것 같다.

 

② API 호출할 때 cond = distance 실행 결과

아니 분명히 cond = distance로 전달 잘 됐으면서 null이라고 한다. 테스트 코드랑 분명 똑같이 한건데 왜 안되는거지??

API request에서 parameter 전달할 때 잘못된건가???

그래서 혹시나 해서 검색 조건 처리하는 코드를 다시 살펴봤다.

아....! 문자열 비교인데 왜 '=='를 썼지??

그래서 == 대신 .equals()로 바꿔서 해봤다.

잘 나온다...

진짜 개 멍청한 실수였다... 이래서 기본기가 중요한가보다...

coding-factory.tistory.com/536

 

[Java] 문자열 비교하기 == , equals() 의 차이점

자바에서 일반적인 데이터 타입의 비교는 ==이라는 연산자를 사용하여 비교합니다. 하지만 String 문자열의 값을 비교할때에는 ==이 아닌 equals()라는 메소드를 사용하여 비교를 합니다. equals와 ==

coding-factory.tistory.com

 

반응형

'개발' 카테고리의 다른 글

gpx 를 이미지로 변환  (0) 2021.05.05
UserProfileDto NPE  (0) 2021.05.04
[연습] travis-ci  (0) 2021.04.27
[연습] springboot, rest api 서버, 카카오 소셜로그인, jwt  (0) 2021.04.26
캡스톤 메모  (0) 2021.04.02
반응형

travis-ci.org에 접속하니, 곧 서버가 종료된다고한다.

travis-ci.com을 사용하라고 한다. 들어가보니까 그냥 똑같은거 같다.

 

.travis.yml 파일은 반드시 build.gradle 과 같은 위치에 있어야한다.

이거 때문에 의미 없는 commit을 수차례나 했지만 travis는 아무 반응도 없었다...

같은 위치로 옮기니까 됐다.

 

./gradlew: Permission denied

이 오류는 전에 책 따라할 때도 마주쳤던 오류다.

gradlew 권한만 추가해주면 간단하게 해결할 수 있다.

before_install:
- chmod +x gradlew

 

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
language: java
jdk:
  - openjdk11
 
branches:
  only:
    - master
 
# Travis CI 서버의 Home
cache:
  directories:
    - '$HOME/.m2/repository'
    - '$HOME/.gradle'
 
script: "./gradlew clean build"
 
before_install:
  - chmod +x gradlew
 
#CI 실행 완료 시 메일로 알람
notifications:
  email:
    recipients:
      - suhoji2021@gmail.com
 
 
 
 
cs

 

-----------------------------

원인은 모르겠는데 test 코드 부분에서 계속 에러가 떴다.

test코드 주석처리 하니까 완료

반응형
반응형

developers.kakao.com/docs/latest/ko/kakaologin/rest-api

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

www.youtube.com/watch?v=NwQ_55l0Za4&list=PL93mKxaRDidECgjOBjPgI3Dyo8ka6Ilqm&index=67

1. 인가 코드 받기

https://kauth.kakao.com/oauth/authorize?client_id=0424bf7b6fda69a5ef3c591a8d4f0f43&redirect_uri=localhost:8080/auth/kakao/callback&response_type=code

 

 

응답 확인용 코드

1
2
3
4
    @GetMapping("auth/kakao/callback")
    public @ResponseBody String kakaoCallback(String code){
        return "카카오 인증 완료, code: " + code;
    }
cs

주소 창에서도 코드를 확인할 수 있다.

 

 

2. 토큰 받기

반응형

'개발' 카테고리의 다른 글

[연습] querydsl 정렬 포함한 쿼리 실행 시 NPE 발생  (0) 2021.04.29
[연습] travis-ci  (0) 2021.04.27
캡스톤 메모  (0) 2021.04.02
Travis CI와 AWS S3 연동  (0) 2021.03.08
ec2 서버에 프로젝트 배포  (0) 2021.03.08

+ Recent posts