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

 

함수 널처리나 전처리(파싱 등)

jsp에서는 if (requset.getparamater("aa") != null){}

스프링에서는

함수에 들어가기전이나 후에 널처리를 할 수 있다 = AOP

 

jackson 바인더 - 제이슨 파싱

아래 조건에서 발동

발동시기 - 함수 시작 직전

 

 

 

보내는 값을 하나 빼도 알아서 있는 값만 파싱해준다

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

 

post데이터는 기본적으로 key : value 형식

객체에 담기 위해서는 setter가 필요하다

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

 

MessageConverter 스프링으로 오는 데이터를 컨버팅해준다

기본은 form데이터 , @RequestBody 를 사용하면 json데이터 컨버팅 가능

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

 

 

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

 

스프링 할 때는 통신시 JSON으로 통일 하는 것이 좋다

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

 

스트링 타입으로 전송하고 싶다면

 

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

 

@RestController

컨트롤러를 타는 모든 주소가 리턴해주는게 모두 데이터일 경우 사용

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

 

 

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

 

 

data로 보내도 객체 내부의 변수명에 맟춰서 자동으로 입력된다

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

 

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

DI - Dependency Injection 의존성 주입

 

핵심!!!

타입을 통해서 주입받는다. 타입을 잘 적어야함

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

다른 패키지에 만든 컴포넌트는 불러와지 않는다

 

 

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

 

 

create user 'spring'@'%' identified by 'bitc5600';
GRANT ALL PRIVILEGES ON *.* TO 'spring'@'%';
create database spring;
use spring;

CREATE TABLE user(
	id int auto_increment primary key,
    username varchar(100) unique not null,
    password varchar(100) not null,
    email varchar(100),
    profile varchar(200),
    createDate timestamp
) engine=InnoDB default charset=utf8;

CREATE TABLE post(
	id int auto_increment primary key,
    title varchar(100) not null,
    content longtext,
    userId int,
    createDate timestamp,
    foreign key (userId) references user (id) on delete set null
) engine=InnoDB default charset=utf8;

CREATE TABLE comment(
	id int auto_increment primary key,
    userId int,
    postId int,
    content varchar(300) not null,
    createDate timestamp,
    foreign key (userId) references user (id) on delete set null,
    foreign key (postId) references post (id) on delete cascade
) engine=InnoDB default charset=utf8;

 

 

 

 

 

글목록 보기

IndexController

 

 

PostController

 

 

PostService

 

 

PostRepository

 

 

post_mapper

 

 

jstl 코어 추가

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

 

index.jsp

 

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

mysql 한글설정

https://blog.naver.com/getinthere/221765250539

 

JSP 게시판 만들기 2강 - MySQL 한글 세팅하기

윈도우와 리눅스가 달라요!!1. 윈도우(1) my.ini 파일 찾기(2) 관리자 권한으로 my.ini 파일 열어서 수정하...

blog.naver.com

 

https://ondolroom.tistory.com/496

 

mysql 세팅

https://getinthere.tistory.com/17 스프링부트 with JPA 블로그 3강 - MySQL 한글 설정 및 연결 1. MySQL 한글 설정 my.ini 파일 MySQL 재시작 [client] default-character-set=utf8 [mysql] default-character-s..

ondolroom.tistory.com

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

 

링크달기

 

 

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

안드로이드 리액트

@GetMapping("/v1/post/{id}")

이런방식으로...

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

 

PostController

 

PostService

 

PostRepository

 

PostDetailRespDto

 

post_mapper

 

 

 

 

 

 

 

딜리트 끝나면 메인페이지로

 

삭제하기

 

detail.jsp

 

 

post.jsp

더보기
let index = { // 여기서는 이벤트 리스너를 바인딩만 하고
	init : function() {
		
		$("#btn-save").on("click", ()=> { // 리스너
			this.save(); // 콜백
		});
		
		$("#btn-delete").on("click", ()=> { // 리스너
			this.deleteById(); // 콜백
		});
		
	},
	
	save: function() { // 실제 로직은 여기서 실행
		
		let data ={
				title : $("#title").val(),
				content : $("#content").val(),
				userId : $("#userId").val()
		};
		
		$.ajax({ // 주소는 RESTAPI 방식대로 적어야한다 
			
			type:"post",
			url: "/post",
			data: JSON.stringify(data),
			contentType: "application/json; charset=utf-8",  // http에서는
																// Content-Type
																// 라고 씀
			dataType: "json"  // 스프링은 응답할때 스트링일 경우 무조건 json으로 응답한다
			
		}).done((resp)=>{
			
			alert("글쓰기 성공");
			console.log(resp);
			location.href="/";
			
		}).fail((error)=>{
			
			alert("글쓰기 실패");
			console.log(error);
			
		});
		
	},
	
	deleteById: function() { // 실제 로직은 여기서 실행
		
		let data ={
				id : $("#id").val(),
		};
		
		$.ajax({ // 주소는 RESTAPI 방식대로 적어야한다 
			
			type:"delete",
			url: "/post/"+data.id,
//			data: JSON.stringify(data),
//			contentType: "application/json; charset=utf-8",
			dataType: "json"  // 스프링은 응답할때 스트링일 경우 무조건 json으로 응답한다
			
		}).done((resp)=>{
			
			alert("삭제 성공");
			location.href="/";
			
		}).fail((error)=>{
			
			alert("삭제 실패");
			console.log(error);
			
		});
		
	}
}

index.init();

 

 

 

 

PostController

 

 

PostService

 

 

PostRepository

 

 

post_mapper

 

-----------

 

수정버튼 누르면 수정모드로 변경

 

post.js

 

 

 

 

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

 

게시물 수정하기

 

post.js

 

 

 

PostController

 

 

PostService

 

 

PostRepository

 

 

post_mapper

 

 

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

해당 태그 숨기기 보여주기

$(선택자).hide();
$(선택자).show();

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

 

삭제시 본인 확인

 

post.js

 

PostController

방식1

 

 

 

 

 

 

RestController

 

 

 

역할 추가

 

CREATE TABLE user(
	id int auto_increment primary key,
    username varchar(100) unique not null,
    password varchar(100) not null,
    email varchar(100),
    profile varchar(200),
    role VARCHAR(50),
    createDate timestamp
) engine=InnoDB default charset=utf8;

CREATE TABLE post(
	id int auto_increment primary key,
    title varchar(100) not null,
    content longtext,
    userId int,
    createDate timestamp,
    foreign key (userId) references user (id) on delete set null
) engine=InnoDB default charset=utf8;

CREATE TABLE comment(
	id int auto_increment primary key,
    userId int,
    postId int,
    content varchar(300) not null,
    createDate timestamp,
    foreign key (userId) references user (id) on delete set null,
    foreign key (postId) references post (id) on delete cascade
) engine=InnoDB default charset=utf8;

 

 

 

매퍼

 

 

 

회원가입하고 DB에서 root 어드민으로 변경

(유저롤을 만들 때에는 ROLE_ 을 붙여주는 것이 좋다)

 

 

조건문 없이 삭제 갱신 등을 하면 막는 옵션 체크 해제 

 

 

오토커밋해제 (롤백을 위한)

 

 

---

 

인터셉터

 

 

 

 

 

 

 

 

 

(Dispatcher Servlet에서 스프링으로 보낼때 사이에서 핸들러가 중간에 낄 수 있다.)

핸들러 - 주소매핑

 

 

 

 

 

 

---

디폴트로 만들어진 인터페이스는 구체화하지 않아도 오류가 나지 않는다

---

 

 

 

 

내용변경

 

 

 

 

자동으로 인터셉트한다.

 

추후 webMvcConfigurer 가 다른것으로 바뀐다면 인터셉터에 접근하는 방법을 찾아야한다
(WebFlux 등)

인터셉터 + 필터 = 시큐리티

 

AOP =관점 지향 프로그래밍 - 함수의 직전과 직후를 처리할 수 있다

회원가입
직전 - 유효성체크
본문 - 회원가입
직후 - 세션등록 및 로그인처리

직전과 직후의 부가적인 기능을 밖으로 빼고 본문의 기능(관심 로직)을 작성

부가적인 기능은 [공통적]으로 쓸 수 있게 작성해놓고 사용 !! -> 핵심

 

 

 

 

 

로그인후 이용하면 접속된다

 

 

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

Log4J Logger

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

 

 

 

 

로그인을 해도 어드민이 아니라면 익셉션

 

 

어드민으로 로그인해서 접속하면

관리자페이지로 접속

 

 

 

 

(이렇게 익셉션별로 구분해야하나 지금은 Exception으로 통일)

 

 

 

 

 

 

 

 

 

 

 

 

IO익셉션으로 설정해놓으면 터진다

 

----------

로그기록 api

https://sentry.io/welcome/

 

Application Monitoring and Error Tracking Software

Self-hosted and cloud-based error monitoring that helps software teams discover, triage, and prioritize errors in real-time.

sentry.io

-----------

 

https://blog.naver.com/getinthere/221718319587

 

springboot 8강 - Spring 인터셉터

인터셉터란 PPT아래와 같이 두 가지만 파일만 정의해주면 된다.config/WebMvcConfig.javaconfig/Ses...

blog.naver.com

 

핸들러는 인터셉터다

 

Spring+HandlerInterceptor.pptx
0.64MB

 

 

 

 

---

컨트롤러 - 뷰리졸버 발동 (@ResponseBody쓰면 미발동)

Rest컨트롤러 - 뷰리졸버 미발동

------

 

Dispatcher Servlet 에서 FrontController 타고 Intercepter가 있으면 탄다

 

 

 

 

 

 

modelAndView 는 JSP에서의 모델이다
response 시 같이 가져가게된다

 

 

프리핸들러 세션 등을 확인

 

 

---

레거시 사용시

web.xml ------- 톰캣 시작시 발동

root-context.xml  -------- 메모리에 딱 1번만 올릴 것들 (DB관련 등) // 톰캣 시작시 발동
servlet-context.xml -------- 요청 올 때마다 메모리에 띄울 것들 // Request할 때 발동된다

----------

aop는 요청시마다 생겨야하니까 servlet-context.xml

----------

 

로그아웃

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

 

redirect: 를 사용하면 파일이 아닌 주소를 검색한다

 

-----------

 

글쓰기

 

세션 인터셉터에 등록

 

 

 

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

 

 

-------


REST API 주소 설계 방법

주소를 여러개 생성하지 않고도 REST 방식으로 처리 가능

데이터베이스에 접근하는 모든 주소!

SELECT 1건 ------> /post/{id}         (GET)
SELECT ALL ------> /posts             (GET)

INSERT ------> /post                    (POST)

UPDATE ------> /post                   (PUT)

DELETE 1건 ------> /post/{숫자}      (DELETE)
DELETE ALL ------> /posts             (DELETE)

-------

1번 유저가 들고 있는 2번 상품을 1건 확인 ->  /user/1/product/2 (GET)

1번 유저가 들고 있는 2번 상품을 1건 업데이트 ->  /user/1/product/2 (PUT)

1번 유저가 들고 있는 2번 상품을 1건 삭제 ->  /user/1/product/2 (DELETE)

1번 상품을 들고 있는 모든 유저 ->  /product/1/users (GET)

------

쿼리스트링보다 RESTful을 사용하자

---------

autowired 방식

3가지

 

1

 

2

 

3

 

4

 

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

 

let index = { // 여기서는 이벤트 리스너를 바인딩만 하고
	init : function() {
		
		$("#btn-save").on("click", ()=> { // 리스너
			this.save(); // 콜백
		});
		
	},
	
	save: function() { // 실제 로직은 여기서 실행
		
		let data ={
				title : $("#title").val(),
				content : $("#content").val(),
				userId : $("#userId").val()
		};
		
		$.ajax({ // 주소는 RESTAPI 방식대로 적어야한다 
			
			type:"post",
			url: "/post",
			data: JSON.stringify(data),
			contentType: "application/json; charset=utf-8",  // http에서는
																// Content-Type
																// 라고 씀
			dataType: "json"  // 스프링은 응답할때 스트링일 경우 무조건 json으로 응답한다
			
		}).done((resp)=>{
			
			alert("글쓰기 성공");
			console.log(resp);
			location.href="/";
			
		}).fail((error)=>{
			
			alert("글쓰기 실패");
			console.log(error);
			
		});
		
	}
}

index.init();

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

없어도 잘돌아 간다고함

 

 

깃에 커밋하면서 하자

만들어두자

 

 

디비 구조에 따라 모델을 만들어주자

 

 

 

 

jsp때 만든 ui를 가져다 사용하자

 

 

 

 

 

 

header.jsp로 가서 회원가입과 로그인 주소를 만들자

 

 

(스크립트)1번유저정보는 1번유저만 볼수 있다 - 로그인이 되어있어야한다 - 2가지가 필요 ( 인증 + 권한 )

1번유저정보 (인증 + 권한)
1번유저수정 (인증 + 권한)
1번유저삭제 (인증 + 권한)
-> /user/~~~~~~

2번 회원가입 페이지 이동, 회원가입시 ()
2번 로그인 페이지 이동 ()
-> /auth/~~~~~~

라이브러리를 사용할 때 이해하게 된다

 

 

 

 

DataSourceConfig.java 삭제

 

fail to refresh live data from process 에러가 뜰 경우

pom.xml에

		<!-- 스프링부트 스타터 액츄에이터 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>

을 추가해보자

 

 

 

 

SPA 싱글페이지 애플리케이션 내부적으로 ajax

 

웹브라우저 안드로이드 리액트 공용 서버를 만들려면

페이지가 아닌 데이터를 리턴받는 서버를 만들어야한다

 

get요청을 제외한 모든 요청을 데이터를 리턴하는 서버로 제작

 

 

 

 

 

 

자바스크립트를 줬으니 아이디를 주고 타입을 버튼으로 바꾸자

 

 

앞에 /를 붙여주면 static 으로 이동한다

 

 

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

디스 바인딩

 

화살표함수로 디스 바인딩

 

 

context-path 를 /로 해주자

포트도 8080

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

 

 

get방식 빼고는 자바스크립트 방식으로 통일

모든 요청은 자바스크립트 !

 

 

폼태그 내용을 지우자

 

 

폼 인풋에 name 을 적는 것은 옛날방식이다

 

 

 

 

자바스크립트 로직 추가

더보기
let index = { //여기서는 이벤트 리스너를 바인딩만 하고
	init : function() {
		
		$("#btn-save").on("click", ()=> {
			this.save();
		});
		
		$("#btn-update").on("click", ()=> {
			this.update();
		});
		
	},
	
	save: function() { // 실제 로직은 여기서 실행
		alert("btn-save 로직 실행");
		let data ={
				username : $("#username").val(),
				password : $("#password").val(),
				email : $("#email").val()
		};
		alert("btn-save data");
		
		$.ajax({ // 공식!
			
			type:"post",
			url: "/auth/joinProc",
			data: JSON.stringify(data),
			contentType: "application/json; charset=utf-8",  //http에서는 Content-Type 라고 씀
			dataType: "json"  // 스프링은 응답할때 스트링일 경우 무조건 json으로 응답한다
			
		}).done((resp)=>{
			console.log(resp);
		}).fail((error)=>{
			console.log(error);
		});
		
	},
	
	update: function() { // 실제 로직은 여기서 실행
		alert("btn-update 로직 실행");
	}
}

index.init();

 

 

 

 

 

 

 

 

----------

web.xml 에는 스프링 필터가 있다
종류가 많은데 중요한 것만 확인하자

message converter -> 기본전략이 xxx-from-urlencoded 즉 key=value 데이터만 파싱하려고한다
@RequestBody 를 걸어두면 들어오는 데이터를 확인하여 제이슨이면 메세지 컨버터를 체인지 한다
gson과 비슷한 오브젝트 매퍼가 동작된다 (그것을 동작시켜주는 것이 jackson이다)

 

추후에 메시지컨버터를 직접 바꿀 수도 있다

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

컨트롤러는 무조건 서비스를 호출해야한다 (리파지토리 안됨)

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

디스패쳐 서블릿 - 프론트컨트롤러 - 컨트롤러들

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

Controller는 뷰리졸버가 가능하다 (데이터를 주고받을 때 @ResponseBody)

RestController는 데이터만 리턴한다

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

// Controller, Repository, Configuration, Service, Component

// RestController, Bean

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

Service를 이용하면 트랜잭션이 발동함

Component는 특별한 역할이 없다

Bean은 클래스가 아닌 메서드에 묶인다

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

https://private.tistory.com/39

 

스프링(Spring) - DI(Depedency Injection) 개념과 예제 : setter() 사용

예제 파일 : 이번 포스트에서는 스프링의 핵심 기능중 하나인 DI(Dependecy Injection)에 대해 알아보고 예제를 작성해보겠습니다. DI는 말 그대로 의존성을 주입시켜준다- 입니다. 객체를 직접 생성하

private.tistory.com

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

 

 

 

 

 

이해하기위해서 이렇게 테스트해보자 (나중에는 response 엔티티를 사용)

 

 

 

 

#{   } 변수명만적으면 알아서 getter를 호출할 수 있다

 

 

redayState가 4면 잘 들어갔다는 뜻

 

 

 

 

select가 아닌 delete insert update를 사용할 때
ok가 아닌 엔티티를 하나 만들어서 항상 같은 값을 리턴해주자 

 

 

 

 

 

 

 

 

 

 

ResponseEntity<?> 를 사용해도된다 // 나중에 쓸 것

 

 

결과

 

 

 

 

try catch를 안만들어두면 ajax자체를 실패하여 fail로 가게된다
그렇게 처리해도 되지만 fail에서 처리하지않고 done에서 처리하려면 try catch를 사용해본다

나중에는 핸들러를 이용할 것이다

트라이캐치를 쓰면 오류를 찾기 어려워지기 때문에 로그를 남겨야한다
그렇기 때문에 쓰지않는 것이 좋다

 

 

 

 

우리는 에러가 터질 때 낚아 채서 처리할 것이다 

 

 

리턴을 보이드로

 

result 를 없애고

 

 

fail로 이동

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

 

 

login도 폼에서 메소드와 액션을 지우고 인풋의 name 속성을 지운다

 

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

컨텍스트 - 이벤트를 받을 수 있다

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

 

 

 

 

 

리파지토리

 

 

맵퍼

 

 

서비스

 

 

컨트롤러

 

 

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

마이바티스 설정들 나중에 공부! 확인

https://mybatis.org/mybatis-3/ko/index.html

 

MyBatis – 마이바티스 3 | 소개

마이바티스는 무엇인가? 마이바티스는 개발자가 지정한 SQL, 저장프로시저 그리고 몇가지 고급 매핑을 지원하는 퍼시스턴스 프레임워크이다. 마이바티스는 JDBC로 처리하는 상당부분의 코드와 ��

mybatis.org

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

 

 

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

데이터베이스에는

undo

redo

 

[홍길동 5000원] 일경우

10000원으로 업데이트하고 커밋을 아직 안했을 경우

undo 로그에는 [홍길동 5000원]의 값이 저장되어 있다 (커밋하기 전의 데이터)

롤백하면 undo로그에서 값을 가져온다

 

1번유저가 트랜잭션중

2번유저가 들어오면

select를 처음 끝 두번하게되면

처음엔 커밋전이라 5000원

끝엔 커밋후라  10000원을 보게된다

 

oracle은 READ COMMITTED

MySql은 Repeatable Read

한번 undo를 봤다면 끝까지 같은 값을 본다 - 정합성 문제가 발생하지 않는다

 

https://joont92.github.io/db/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EA%B2%A9%EB%A6%AC-%EC%88%98%EC%A4%80-isolation-level/

 

[db] 트랜잭션 격리 수준(isolation level)

트랜잭션 격리수준(isolation level)이란 동시에 여러 트랜잭션이 처리될 때, 트랜잭션끼리 얼마나 서로 고립되어 있는지를 나타내는 것이다. 즉, 간단하게 말해 특정 트랜잭션이 다른 트랜잭션에 ��

joont92.github.io

 

커밋 리드

언커밋 리드

 

겟인데어 41~ 강

 

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

퍼시스턴스란 rs를 자바 객체에 넣어 주는 것

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

 

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

 

@Controller는 요청이 오면 생성됨

즉, 컨트롤러가 떴을경우에는 request, response 를 불러 올 수 있다

 

나머지 어노테이션들은 미리 생성 되어 있고

@Controller는 요청이 오면 생성되니 순서를 잘기억하자

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

 

 

 

 

 

 

 

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

 

ObjectUtils.isEmpty(persistUser)

널 또는 빈객체인지 확인

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

+ Recent posts