본문 바로가기

백/spring boot

스프링부트 스터디-7 (91강~)

로그인  양식 만들기

 

<Login.jsp>

 

<GET 방식으로 name, password submit 후 URL>

-> 내 정보가 URL에 노출되는 건 보안상 좋지 않음

-> GET 방식은 모든 정보가 URL의 일부로서 전송되므로 form을 만들 때마다 POST 방식을 사용하게 된다

-> POST방식으로 전달함으로써 URL에 유출되는 문제 해결

 

cf) 개발자도구 > Network > Payload 에 form data가 담겨있음

 

결론 : 웹사이트에 전달하려는 보안 정보들은 모두 "POST" 메소드를 사용하는 게 좋다


<구현하고자 하는 것>

/login으로 들어온 요청이 GET방식 -> login.jsp 실행

/login으로 들어온 요청이 POST방식 -> welcome.jsp 실행

 

<방식에 따라 실행할 메소드 다르게 하고 싶은 경우>

 

 

 

<사용자가 입력한 이름&패스워드를 이용해 사용자를 인증하기>

1) form data의 일부로서 받는 데이터를 @RequestParam name과 password로 잡는다

   ( URL과 함께 전달되는 쿼리 파라미터 & form data 모두에  RequestParam 사용 가능! )

+

2) 이 정보를 jsp에 전달하고 이용하기 위해 ModelMap 이용하기

 

 

<welcome.jsp>

 

-> 정리

1. form data의 일부로서 받는 데이터를 @RequestParam name과 password로 잡고,

2. 이를 model에 넣고 

3. model을 사용해서 뷰에 표시한다

 


<인증 서비스 만들기>

-> username이 "in28minutes"이고 password가 "dummy" 인지 확인하는 과정

    (username이 "in28minutes"이고 password가 "dummy"면 참을 리턴한다.)

 

<LoginController에 이 인증서비스 적용하기>

-> 이렇게 적용하려하면 "Parameter 0 of constructor~" 오류남

   -> @Service 달아주기 (AuthenticationService를 주입받기 위해 스프링이 얘를 검색하는데 얘가 스프링 빈이라는 걸 알려주어야 함)

 

<인증 틀렸을 시, error 문구도 함께 출력하기>

-> LoginController의 else문에 models.put 이용하기

-> LoginController의 else문에 models.put 이용하기

 

 


ToDo 기능 만들기

1. Todo 클래스에 필요한 속성들, 생성자, getter, setter 만들어주기

 

2. 정적인 todo 리스트 만들기 -> 데이터베이스로 이동하기 (H2, MySQL) 

 1) 정적인 todo 리스트 만들기

 <TodoService 생성>

-> static 블록이란?

  : 객체가 생성되기 전에 한 번만 호출 되는 것으로 static 데이터를 초기화 할 때 사용

  : 생성자가 불리지 않더라도 해당 클래스에 대한 참조가 발생하자마자 호출됨

 

<로그인하고 나서 내 Todo 리스트를 받고 화면에 표시하기>

-> 컨트롤러, jsp 만들어주기

 

 

TodoController에서 TodoService 주입받음으로써 todoService 사용해 Todo 리스트 받고 모델에 추가해 jsp에 띄울 수 있다

 

 

cf) model.put vs model.addattribute

https://velog.io/@liljoon/Spring-ModelMap%EC%97%90%EC%84%9C-addAttribute%EC%99%80-put%EC%9D%98-%EC%B0%A8%EC%9D%B4

 

Spring ModelMap에서 addAttribute와 put의 차이

일반적으로 addAttribute나 put을 쓰나 기본적인 기능은 동일하게 작동한다.JSP에 Expression Language에 쓰여진 값에 데이터를 넣어주는 역할이다.HashMap의 함수이다. ModelMap 클래스가 LinkedHaspMap을 상속받

velog.io

-> 기본적인 기능은 동일.

model.put(): Map 인터페이스를 구현하는 클래스의 메서드

model.addAttribute() : 스프링의 Model 인터페이스를 통해 제공됨

 

스프링에서는 addAttribute를 많이 사용한다고 함


세션, 모델, 요청 이해하기

-> 이 payload 값들은 오직 이 request에 대해서만 유용하고 다음 request로 적용되지않는다

  -> 다른 페이지로 가면 이 값들은 모두 사라져 사용할 수 없게 된다 

 

즉 model에 뭔가를 넣으면 해당 request의 범위에서만 사용가능하고 다른 페이지로 넘어가면 못 사용한다

-> 이를 해결하기 위해 세션 이라는 걸 사용!

   -> 세션을 사용하면 여러 요청에 거쳐 값을 유지할 수 있게 됨

 

세션에 값을 넣으려면 그 값을 사용하는 모든 컨트롤러에 @SessionAttributes("속성이름") 붙여주기!

-> 로그인페이지 & todo리스트 페이지에서 name 속성 사용 -> loginController&TodoController에 적용하기

 

cf) 세션을 사용하게 되면 추가로 메모리를 차지하고 모든 세부정보가 서버에 저장되기 때문에 조심히 사용하기!!

 


외관 다듬기

SpringBoot에 JSTL 추가하고 Todos를 테이블에 표시하기

 

1. JSTL 태그 사용하기 위해 의존성 설치하기

<dependency>
	<groupId>jakarta.servlet.jsp.jstl</groupId>
	<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
</dependency>

<dependency>
	<groupId>org.glassfish.web</groupId>
	<artifactId>jakarta.servlet.jsp.jstl</artifactId>
</dependency>

 

2. 태그 라이브러리 import 하기

 

3. 결과

 

 

BootStrap

-> class 이름을 부여하면 css가 추가적으로 적용된다


새로운 todo 추가 기능 구현

 

<TodoController>

-> GET 요청이 오면 todo 페이지를, POST 요청이 오면 listTodos 페이지로 넘어가게끔 하고 싶다

-> 그냥 "return listTodos" 하면 다시 서비스에서 todo리스트 넘겨받아야해 번거로우므로 redirect 시키

 

<todo.jsp>

 

 

<추가 기능 로직 구현>

원리 : TodoService에서 add메소드 정의하고 -> Controller에서 이 메소드를 호출해 작동하게

1. TodoService

-> Todo 객체 생성 후 리스트에 추가해주기

 

2. TodoController

@RequestParam -> 사용자로부터 입력받는 부분

service의 메소드 호출해 실행하기


프론트엔드 상의 검증은 해커가 잘 뚫을 수 있어 서버측 검증이 중요하다!

 

1. pom.xml에 의존성 설치

2. Command Bean 사용하기 (양방향 바인딩)

-> 양방향 바인딩이란? 

: 내 Bean(Todo)에서 form 으로 바인딩 되고, form에서 Bean으로 바인딩 된다

 

위에서 입력받는 내용이 많다고 @RequestParam도 많이 쓸 수 x .

-> 이를 해결하기 위해 각각을 RequestParam에 바인딩하는 게 아니라 Todo 빈에 바인딩 하기

 

-> modelAttribute 통해 todo 받아옴. 

 

jsp model에 todo가 있기를 기대하고 있는데

Controller에서 Get은 Todo와 바인딩 안해서 오류 뜨므로 Get도 마찬가지로 Todo와 바인딩해주기!

이렇게 실행시키면 id, done이 null이라고 오류 떠서 얘네도 input으로 입력받게끔 jsp 구현해줘야 함

 

 

-> 결국 양방향바인딩 관점에서 보면?

GET에서

Todo빈의 ""부분이 form의 description 빈칸에 매핑되고

Form에 입력한 내용이 Todo 변수의 description 필드에 바인딩되어 리스트에 추가되어 화면에 보여지게 됨

 

3. 검증을 빈에 추가하기

-> 길이 검증 @Size 이용 + Controller의 해당 빈에 @Valid 적용

  -> @Valid : 빈을 바인딩하기 전에 빈을 검증하게 된다

 

이 페이지 대신 기존페이지 띄우고 싶다면 BindingResult 이용하기

+ 오류 문구 출력하려 하면 jsp에 form:errors 추가

 

 

<검증 단계 복습>

 

 


Todo 삭제 기능 구현하기

 

1. jsp에 버튼만들기

어느 todo를 삭제 해야하는지 id 알려주어야 함

-> 쿼리 파라미터 이용

2. <TodoController>

여기서 오는 쿼리 파라미터 잡기 위해 @RequestParam 이용하기

 

3. <TodoService>

삭제 로직

: todos.removeIf(조건)

Predicate(조건)  : 모든 Todo를 돌면서 각 Todo의 id가 찾고자 하는 id인지 확인


<Update 버튼 클릭시, 세부 정보 담은 화면으로 넘어가게 하기>

 

1. jsp에 버튼, URL 만들기

 

2. Controller

todo.jsp에서 modelAttribute로 todo를 기대하고 있으므로 Controller에서 model에 todo를 넣어주어야 한다

-> 내가 원하는 Todo를 찾아 model에 넣어주기

 

3. <TodoService>

findById 구현


<Submit 버튼 클릭시, 정보 저장하기>

 

<TodoController>

 

<TodoService>

로직 : 삭제하고 add 하는 방식

-> 효율적이지 않지만 코드가 간단

 

 

cf)

추가, 삭제 등 로직들은 Service에 메소드로 구현하고

Controller에서는 url, Service에서 메소드 호출해 사용하는 방식


update했을 때 날짜가 나타나고 있지 않다

-> jsp에 날짜 입력칸이 없어서. 추가해주기!

 

application.properties에 표준 날짜 형식 지정하기

 


jsp 프래그먼트

-> jsp 반복을 피하는 방법

-> 여러 페이지에 공통으로 사용되는 네비게이션바, 푸터, 헤더를 따로 jspf 파일 만들고 얘네를 불러오는 형식으로 구현!