Interceptor(인터셉터)
2019-06-14 00:00:00 +0000Interceptor
- Interceptor란 컨트롤러를 실행할 때 별도의 처리를 할 수 있는 기능
JavaConfig 설정 방법
- WebMvcConfigurer를 인터페이스 상속한 Servlet class에서 오버라이딩 해야한다
- addInterceptors를 오버라이딩하여 InterceptorRegistration class를 사용해 interceptor class를 등록한다
- addPathPatterns 함수로 interceptor가 가로챌 controller 범위를 설정할 수 있다
@Bean
public LoginInterceptor loginLogInterceptor() {
return new LoginInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
InterceptorRegistration interceptor = registry.addInterceptor(loginLogInterceptor());
interceptor.addPathPatterns("/**");
}
- HandlerInterceptor를 인터페이스 상속받아 Interceptor 처리 클래스를 만든다
- preHandle 함수는 Controller가 실행되기 전 호출된다
- postHandle 함수는 View를 전부 그리기 전 호출된다 -afterCompletion 함수는 View를 그린 후 호출된다
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.HandlerInterceptor;
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}
Android Studio Install
2019-05-28 00:00:00 +0000Android Studio Install
Android Install
- download
- Do not import settings 선택
- Custom 선택
- Performance, Android Virtual Device 선택
- 설치 완료 후 제어판-시스템-고급-환경변수 선택
- 시스템 변수에서 Path 편집. C:\Program Files\Android\Android Studio\jre\bin 추가 후 저장
- 환경변수가 알맞게 잡혔는지 확인하기 위해서 cmd 창을 열고 keytool 입력. keytool 명령어에 대한 정보 출력
- Android 설치 후 뜨는 창에서 Create New Project - Empty Activity 선택
- App Name은 말 그대로 app의 이름
- Package Name은 구글 플레이스토어에 앱의 고유식별자. 중복되면 안됨
AVD 추가
- 삼성갤럭시 7의 높이, 너비를 가진 AVD를 생성한다
- Tools - AVD - Create Virtual Device - New Hardware Profile 선택
- Screen size 5.1
- Resolution 1440x2560
Setting 수정
- import를 자동으로 하도록 설정
- File - Settings - Editor - General - Auto Import
- Add unambiguous imports on the fly 체크
- Optimize imports on the floy (for current project) 체크
- Layout view에서 눈모양 아이콘을 클릭한 뒤 Show Layout Decorations 클릭.(앱 아이콘이 보여서 위치가 좀 더 정확해짐)
실행
- Shift + F10 을 누르면 안드로이드 폰 화면이 생긴다
Simple Toast Example
- layout에서 button을 TextView로 끌어서 놓는다
- onClick 이벤트 이름으로 onClick이라고 적어둔다
- 여기까지 하면 아래 xml이 작성된다. 그런데 Button이 빨간색이다. 위치 정보가 없어서 그렇다. 이 때 infer Constraints 버튼을 누르면 위치에 대한 정보가 생긴다
- Before
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="Button"
tools:layout_editor_absoluteX="167dp"
tools:layout_editor_absoluteY="299dp" />
- After
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="9dp"
android:onClick="onClick"
android:text="Button"
app:layout_constraintBottom_toTopOf="@+id/textView"
app:layout_constraintStart_toStartOf="@+id/textView" />
- onClick 함수는 MainActivity에 정의해야한다
- 실행해서 버튼을 누르면 짧은 Toast 메시지가 뜬다
public void onClick(View v) {
Toast.makeText(getApplicationContext(),"Hello World",Toast.LENGTH_SHORT).show();
}
계층형 게시판
2019-05-20 00:00:00 +0000계층형 게시판 만들기
- 게시물 답글이 가능한 게시판.
- parentSeq(자기 게시물 seq), order, depth 필드를 추가한다.
- parentSeq는 자신이 최상위 게시물일 경우 자신의 seq, 답글일 경우 부모 게시물 seq를 저장한다
- order 는 순서이다. 하나의 최상위 게시물로 묶여진 순서. 이 순서대로 출력된다(그러므로 답글이 달리면 답글 아래의 게시글들은 순서를 하나씩 미뤄야한다)
- depth 는 깊이이다. 최상단이면 0, 최상단 게시물의 답글은 1, 그 답글의 답글은 2.. 이런식으로 늘어난다.\
- order와 depth에 제한이 없도록 한다.
Index 규칙
- 부모 게시물의 답글이 없다면 부모 게시물의 order+1, depth+1
- 부모 게시물의 답글이 있다면 맨 마지막 게시물 정보에서 order+1
게시물 생성 규약
- 클라이언트에게 자신의 부모 게시물 id을 받아야 한다
- 신규 게시글인지 답글인지 확인한다. 신규 게시글이면 게시물 생성 후 종료
- 부모 게시물 id로 부모에게 자식이 있는지 확인한다(확인하는 방법은 부모의 계층 정보에서 order+1, depth+1하고 동일한 부모게시물id로 가진 게시물이 있는지 확인하면 된다)
- 자식이 없다면 부모 정보를 기준으로 계층 정보를 넣어준다. 그리고 새로운 ordering 후 게시물 생성 및 종료 4, 자식이 있다면 마지막 자식을 찾는다. 그 마지막 자식을 기준으로 계층 정보를 넣어준다
DB 컬럼 추가
- alter table board add parent_seq bigint(20) DEFUALT NULL;
- alter table board add board_order bigint(20) DEFAULT 0;
- alter table board add board_depth int DEFAULT 0;
VO 수정
- 추가한 필드에 대응되는 멤버 변수 추가
private long parentSeq;
private int boardOrder;
private long boardDepth;
조회 쿼리 수정
- 게시물 SEQ 순서가 아니라 부모 SEQ, order 순서대로 정렬해야한다.
- 최신 게시물이 위로 올라가야하므로 부모 SEQ는 desc 정렬. 답글은 순서대로 출력되어야 하므로 ASC 정렬
- select로 추가필드를 조회할 수 있도록 수정한다.
<select id="getTitleVOList" parameterType="SelectVO" resultType="TitleVO">
SELECT board_seq as boardSeq
, title
, writer
, date
, count
, user_id as userId
, user_seq as userSeq
, board_del as boardDel
, parent_seq as parentSeq
, board_order as boardOrder
, board_depth as boardDept
FROM board
<include refid="searchBoard"></include>
ORDER BY parent_seq DESC, board_order ASC
LIMIT #{start}, #{length}
</select>
게시물 생성 코드
private PostReplyVO getMyRelpyVO(PostReplyVO parentReplyVo) throws Exception {
if (parentReplyVo == null) {
throw new LogicException(Constants.RESULT_STATE.BOARD_UNKOWN_ERROR.getState(), Constants.RESULT_STATE.BOARD_UNKOWN_ERROR.getMessage());
}
PostReplyVO myReplyVO = new PostReplyVO(); // 현재 게시물 자신의 정보
myReplyVO.setParentSeq(parentReplyVo.getParentSeq()); // 최상위 부모 seq 넣어줌
boolean isChild = isParentFirstChild(parentReplyVo.getBoardSeq());
if (!isChild) { // 자식이 존재하지 않는다
PostReplyVO lastPostReplyVO = dao.getPostReplyVO(parentReplyVo.getBoardSeq()); // 직계부모 정보를 가져와서 자신의 정보를 정한다
if (lastPostReplyVO == null) {
throw new LogicException(Constants.RESULT_STATE.BOARD_UNKOWN_ERROR.getState(), Constants.RESULT_STATE.BOARD_UNKOWN_ERROR.getMessage());
}
myReplyVO.setBoardOrder(lastPostReplyVO.getBoardOrder() + 1);
myReplyVO.setBoardDepth(lastPostReplyVO.getBoardDepth() + 1);
} else {
PostReplyVO postReplyVO = getMyParentLastChildBoardReplyVO(parentReplyVo); // 자신의 부모의 마지막 자식을 찾음
if (postReplyVO == null) {
throw new LogicException(Constants.RESULT_STATE.BOARD_UNKOWN_ERROR.getState(), Constants.RESULT_STATE.BOARD_UNKOWN_ERROR.getMessage());
}
myReplyVO.setBoardOrder(postReplyVO.getBoardOrder() + 1); // 마지막 자식의 정보를 가지고 자신의 정보를 정한다
myReplyVO.setBoardDepth(parentReplyVo.getBoardDepth() + 1); // 부모의 깊이에서 하나 더해주기
}
return myReplyVO;
}
자식 있는지 확인 쿼리
<select id="getParentNextChildBoardCount" parameterType="PostReplyVO" resultType="int">
SELECT
count(*)
FROM board
WHERE parent_seq = #{parentSeq} and board_order = #{boardOrder} + 1 and board_depth = #{boardDepth} + 1
</select>
부모 게시물의 마지막 자식을 찾음
<select id="getLastReplyBoard" resultType="PostReplyVO" parameterType="ParamMap" >
SELECT
board_seq as boardSeq
, parent_seq as parentSeq
, board_order as boardOrder
, board_depth as boardDepth
FROM board
WHERE parent_seq = #{parentSeq} and board_depth >= #{boardDepth} + 1 and (board_order > #{boardOrder}) AND board_state IN (0, 2)
ORDER BY board_order DESC
LIMIT 0,1
</select>
VirtualBox Ubuntu 18.04.2 LTS
2019-05-20 00:00:00 +0000VirtualBox Ubuntu 18.04.2 LTS
Download
- VirtualBox Download
- Ubuntu Server
- 리눅스 서버가 필요하므로 Ubuntu 가 아닌 Ubuntu Server를 다운받는다. 그냥 Ubuntu는 GUI 운영체제이다
- Ubuntu는 LTS(안정적이고 오랫동안 사용가능한 버전)을 Download 한다
- Putty 설치
- WinSCP 설치
Ubuntu 설정
- 추가 버튼 클릭
- 종류는 Linux, 버전은 Ubuntu (64-bit)로 설치
- 메모리 2048MB(2GB) 설정
- 지금 가상 드라이브 만들기
- VDI(VirtualBox 디스크 이미지) 선택
- 100GB 설정(사용드라이브가 1TB라서)
- 설치 완료 후 ‘저장소’ 클릭. 컨트롤러:IDE 아래 비어있음을 클릭하고 CD 버튼을 누른다. 그리고 Ubuntu ISO 선택
Ubuntu 설치
- 언어 선택(English)
- Install Ubuntu
- 파티션 설정 Done, Done, Use An Entire Disk, 계속 Done 하고 마지막에 Continue
- ubuntu 로그인 id, pass 입력
- 추가 패키지 설치는 넘어감
host 컴퓨터 정보 확인
- 네트워크는 ‘어댑터에 브리지’ 하나만 사용
이더넷 어댑터 이더넷:
연결별 DNS 접미사. . . . :
링크-로컬 IPv6 주소 . . . . : fe80::881b:e340:c3c6:cae2%6
IPv4 주소 . . . . . . . . . : 192.168.38.1
서브넷 마스크 . . . . . . . : 255.255.192.0
기본 게이트웨이 . . . . . . : 192.168.1.1
네트워크 설정
- ssh 설치 및 ssh 시작
sudo apt-get install openssh-server
service ssh restart
- 22번 포트 번호 열렸는지 확인
netstat -tnlp
- 만약 20번 포트가 없다면 등록한다.
- 포트 등록하면서 재시작 해도 설정이 남는 iptables-persistent을 설치한다
sudo apt-get update
sudo apt-get install iptables-persistent
- iptables 설정을 초기화한다(이 부분이 반드시 필요한지는 모르겠다)
- localhost 접속 허용 규칙이나 22번 포트 열기 등… 의 처리를 한다
- 출처
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -Z
sudo iptables -F
sudo iptables -X
고정 네트워크 IP 설정
- UbuntuNetplan 설명
- Ubuntu 17.10 부터 바뀐 네트워크 설정방법
- Ubuntu 17.10 버전 이상이라면 interfaces을 설정해도 Netplan 설정에 덮어져 ip설정이 제대로 되지 않을 수 있다
Netplan 설정 방법
- vi Netplan 수정
- 50-cloud-init는 기본 인터페이스 설정
vi /etc/netplan/50-cloud-init.yaml
- ethernets 아래에 설정할 네트워크 디바이스 이름을 추가한다.
- addresses는 ip주소를 설정한다 /24는 서브넷마스크 대신 사용한다
- /24의 의미는 왼쪽부터 채워진 1bit의 수. 즉 /24는 11111111.11111111. 11111111.0000 = 255.255.255.0 이다
- enp0s3는 ifconfig로 네트워크 장비의 이름이다
- netmask와 gateway는 host 컴퓨터 설정과 맞춰준다
network:
ethernets:
enp0s3:
dhcp4: no
dhcp6: no
addresses: [192.168.38.3/24]
gateway4: 192.168.1.1
nameservers:
addresses: [8.8.8.8,8.8.4.4]
version: 2
설정 적용
sudo netplan apply
확인
ifconfig -a
TransactionAwareDataSourceProxy Error
2019-05-19 00:00:00 +0000NoClassDefFoundError TransactionAwareDataSourceProxy Error
- db 접속 테스트 코드 실행 시 발생
- TransactionAwareDataSourceProxy class 를 찾을 수 없어서 나는 에러
- TransactionAwareDataSourceProxy는 spring-jdbc안에 있다.
- 현재 프로젝트의 spring-jdbc 버전에서 TransactionAwareDataSourceProxy가 없는 듯 그래서 현재 버전인 5.1.5.RELEASE 에서 5.1.4.RELEASE 로 바꿔주었더니 잘 되었다.
- 진짜 5.1.5.RELEASE에 TransactionAwareDataSourceProxy가 선언안되어 있거나 다른 라이브러리랑 충돌나서 TransactionAwareDataSourceProxy를 인식하지 못하는 듯.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in base.toy.config.RootConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'sqlSessionFactory' threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy
- pom.xml
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.4.RELEASE</version>
</dependency>
Posts
-
Interceptor(인터셉터)
-
Android Studio Install
-
계층형 게시판
-
VirtualBox Ubuntu 18.04.2 LTS
-
TransactionAwareDataSourceProxy Error
-
Java Coding Conventions
-
Java Long과 long의 차이
-
Mybatis 객체 안에 객체 매핑
-
JavaConfig mariadb 연결
-
DataTable
-
관리자 페이지
-
MappingJackson2JsonView
-
Spring Javaconfig
-
게시판 만들기-제품 등록
-
게시판 만들기-제품 페이지 제작
-
게시판 만들기-회원탈퇴 및 게시판 삭제 플래그 추가
-
footer 하단에 고정시키기
-
bootstrap4 사용법
-
Spring 데이터 검증 @Valid, BindingResult
-
brackets 실시간 미리보기
-
Spring 기본설정(pom.xml, web.xml, encoding)
-
Vue.js computed, methods, watch
-
javascript onkeyup
-
Maria DB Incorrect string value Error
-
javascript 암호화(md5, base64)
-
Vue.js template
-
Vue.js 소개
-
Nexacro 설명
-
ControllerAdvice
-
Batch
-
html 페이지 로딩 순서
-
소수구하기(PrimeNumber)
-
최소공배수,최대공약수
-
Stream
-
Lambda(람다식)
-
inner class(내부 클래스)
-
final 키워드
-
file upload
-
파이썬 빅 데이터 K-평균(K-means)
-
아나콘다(Anaconda), 주피터 개발환경 세팅
-
텐서플로우(TensorFlow) 아키텍쳐 및 Session
-
텐서플로우(TensorFlow)상수, 변수, 함수
-
머신러닝 기초
-
한글 리스트 오름차순, 내림차순
-
연속된 글자의 갯수 출력
-
java spring5 프로젝트 설정
-
restController
-
spring 세팅 및 기본설정
-
mybatis trim
-
jquery datepicker
-
ajax로 데이터 전달/응답 받는법
-
mybatis error
-
mybatis 게시판 만들기 순서
-
Java Jsp Mybatis Dynamic Query
-
mybatis
-
git 소개
-
node.js 개발환경 구축
-
node.js 기본 내장 모듈
-
node.js의 전역 객체
-
node.js http module
-
node.js event
-
jdbc
-
자바빈
-
jsp, servlet 정리
-
java null object pattern
-
다음지도 key 등록(kakao map)
-
공공 데이터 open api
-
facebook login api
-
sourcetree 사용법
-
JavaScript event3
-
JavaScript jquery
-
JavaScript dom
-
JavaScript ajax
-
JavaScript 이벤트2
-
JavaScript 캡슐화
-
JavaScript Array,내장객체
-
JavaScript var
-
JavaScript 객체,생성자
-
JavaScript 함수,클로저
-
JavaScript Event
-
javascript eclipse 자동완성(with tern)
-
CSS position
-
HTML5,CSS 선택자
-
자바 시간 측정
-
git,eclipse 연동
-
HTML 기초 정리
-
Eclipse Web 환경세팅
-
피보나치의 수
-
Oracle 반복문,커서,예외,저장 서브프로그램
-
Oracle PL/SQL
-
Oracle 다중쿼리(Multiple row query)
-
Oracle 인덱스, 뷰, 시퀀스, 트랜잭션, 세션 정리
-
Oracle JOIN 정리
-
Oracle DDL, DML 정리
-
Oracle 문자열 함수 정리
-
Oracle 숫자,날짜,자료형 변환 함수 정리
-
Oracle 제약조건 정리
-
Oracle 기초 쿼리 정리
-
문제2775
-
DFS
-
junit
-
json
-
algorithmus basic
-
circular queue(원형큐)
-
binary search(이진탐색)
-
port forwarding(포트포워딩)
-
kakao chatbot(카카오 챗봇)
-
java io
-
sort comparable, comparator
-
Unresolved compilation problem
-
ArrayList, HashMap
-
Regular(정규표현식)
-
Enum Class
-
String Function
-
refactoring 이란(상수,제어플래그,assert)
-
reference,abstract 정리
-
FileNotFoundException Solve
-
static
-
Thread Synchronization(스레드동기화,원자성)
-
Java Exception(예외처리)
-
Java 생성자, this, super
-
roomnum
-
BeeHouse
-
Git Reset, Revert
-
Git Log
-
Array
-
stack
-
pyramid draw
-
Star Draw(별 그리기4)
-
Star Draw(별 그리기3)
-
Star Draw(별 그리기2)
-
Star Draw(별 그리기1)
-
Loop(While, For)
-
자바 데이터 타입, 데이터 연산
-
시계방향 달팽이 그리기
-
정수값의 짝수,홀수 갯수 구하기
-
java, Scanner 정리
-
draw dog
subscribe via RSS