Spring 기능 정리

웃음인·2024년 11월 12일

Framework

목록 보기
5/7
post-thumbnail

Java 객체 : new 연산자에 의해 Heap 영역에 클래스에 작성된 내용대로 생성된 것
instance : 개발자가 직접 만들고, 관리하는 객체
Bean : Spring Container가 만들고, 관리하는 객체

💥 HttpServletRequest

  • 요청 클라이언트 정보, 제출된 파라미터 등을 저장한 객체
  • 클라이언트 요청 시 생성되는 객체

Spring 의 Controller 메서드 작성 시 매개변수에 원하는 객체를 작성하면
존재하는 객체를 바인딩(연결) 또는 없으면 생성해서 바인딩
--> ArgumentResolver (전달 인자 해결사)

public String paramTest1(HttpServletRequest req)
  // 이렇게 매개변수 자리에 req전달 시
  
  String inputName = req.getParameter("inputName");
  String inputAddress = res.getParameter("inputAddress");
  // inputName과 inputAddress라는 키 전달 시 해당 키에 있는 값을 리턴해줌



💥@RequestMapping("요청주소")

▶ 요청주소를 처리할 메서드를 매핑하는 어노테이션

	 // 1) @RequestMapping("주소")
	  
	 // 2) @GetMapping("주소")    : Get (조회) 방식 요청 매칭
     
     	ex) @GetMapping("ex3/{number}")
			public String pathVariableTest( @PathVariable("number") int number ) { 
			// 주소 중 {number} 부분의 값을 가져와서 매개변수로 저장
			// controller 에서 사용할 수 있도록 해줌
			// + request Scope에 자동 세팅도 해줌
            
	 
	     @PostMapping("주소")   : Post (삽입) 방식 요청 매핑
	     
	     @PutMapping("주소")    : Put (수정) 방식 요청 매핑 (form, a태그 요청 불가)
	     
	     @DeleteMapping("주소") : Delete (삭제) 방식 요청 매핑 (form, a태그 요청 불가)

1) 메서드에 작성 :

  • 요청 주소와 해당 메서드를 매핑
  • GET/POST 가리지 않고 매핑 (속성을 통해서 지정 가능 or 다른 어노테이션을 이용해서 가능)
	@RequestMapping(value="/hello", method=RequestMethod.POST)
	public String hello() {
		// 메서드 로직
		
		return "경로..";
	}

2) 클래스에 작성

  • 공통 주소를 매핑
    ex) /todo/insert, /todo/select, /todo/update ..
	@RequestMapping("/todo")
	 public class 클래스명 {
	
		@RequestMapping("/insert") // /todo/insert 매핑
		public String 메서드명() {}
		
		@RequestMapping("/select") // /todo/select 매핑
		public String 메서드명() {}
		
		@RequestMapping("/update") // /todo/update 매핑
		public String 메서드명() {}
	
	}



💫 Controller 메서드의 반환형이 String인 이유

‣ 메서드에서 반환되는 문자열이 forward 할 html 파일의 경로가 되기 때문!

Thymeleaf : JSP 대신 사용하는 템플릿 엔진(html 형태)

classpath : src/main/resources
접두사 : classpath:/templates/
접미사 : .html 

ex) return "test"; // --> 접두사 + 반환값 + 접미사 경로의 html로 forward
   == src/main/resources/templates/test.html
타임리프의 접두사, 접미사, forward 설정은 View Resolver 객체가 담당!

💫 Spring 에서 Redirect(재요청) 하는 방법

‣ Controller 메서드 반환 값에 "redirect:요청주소"; 작성




💥 Thymeleaf

1. 템플릿 엔진

- 템플릿 양식과 특정 데이터 모델에 따른 입력자료를 합성하여 결과 문서(응답 화면)를 출력하는 것
→ 만들어 둔 화면(html)에 데이터를 추가하여 하나의 html로 만들어서 응답 (JSP도 템플릿 엔진) 

[ 타임리프 특수 속성 ]
th문법(표현식) : xmlns:th="http://www.thymeleaf.org"
th속성을 사용하기 위해 선언된 네임스페이스로
th속성 사용하기 전 head태그 상단에 선언해주기 !

  • Spring EL (스프링 표현 언어)
  • ${key} : 변수, Model 등을 이용해서 세팅한 값 출력
  • DTO 객체 출력할 때는 DTO에 getter 필수로 작성 !!
    -> ex) ${Student.getName()} == ${Student.name}

    getter 대신 필드명 호출하는 형식으로 EL 작성하는 이유
    : 자동으로 getter 메서드를 호출하기 때문

th 속성은 출력된 화면에서 보여지지 않는다 ! → 해석된 후 사라짐 !!

2. Thymeleaf

- 웹 및 독립 실행형 환경을 모두 지원하는 최신 서버 측 Java 템플릿 엔진
    → 웹 실행   == 요청 시 포워드 되는 화면
    → 독립 실행 == html 파일만 실행

  
- HTML 파일에서 th(Thymeleaf) 속성을 이용해 
  컨트롤러로부터 전달 받은 데이터를 이용해 동적 페이지를 만들 수 있음 
  Spring Boot에서는 JSP가 아닌 Thymeleaf 사용을 권장하고 있음
  



💥 Model

  • Spring 에서 데이터 전달 역할을 하는 객체
  • org.springframeword.ui 패키지에 존재
  • 기본 scope : request
  • @SessionAttribute 와 함께 사용 시 session scope 변환 (session으로 확장 가능)

▶ 기본 사용법

Model.addAttribute("key", value);
  
		// 단일 값(숫자, 문자열) Model 을 이용해서 html로 전달
		model.addAttribute("productName", "종이컵");
		model.addAttribute("price", 2000);
        
        [html]
        <span class="price">
        	<th:block th:text="${price}">가격</th"block> 원
		
		
		// 복수 값(배열, List) Model 을 이용해서 html로 전달
		List<String> fruitList = new ArrayList<>();
		fruitList.add("사과");
		fruitList.add("딸기");
		fruitList.add("바나나");
		
		model.addAttribute("fruitList", fruitList);
        
        [html]
        <ul>
        	<th:block th:each="fruit : ${fruitList}"
            	<li th:text="${fruit}">과일명</li> <!-- 사과, 딸기, 바나나 각각 출력 -->
            
        </ul>
		
		
		// DTO 객체를 Model 을 이용해서 html로 전달
		Student std = new Student();
		std.setStudentNo("12345");
		std.setName("홍길동");
		std.setAge(22);
		
		model.addAttribute("std", std);
        
        [html]
        <ul th:object="${std}">
        	<li th:text="*{stdentNo}">학번</li>
            <li th:text="*{name}">이름</li>
            <li th:text="*{age}">나이</li>
        </ul>
		
		
		// List<Student> 객체를 Model 을 이용해서 html로 전달
		List<Student> stdList = new ArrayList<>();
		
		stdList.add(new Student("11111", "김일번", 20));
		stdList.add(new Student("22222", "최이번", 23));
		stdList.add(new Student("33333", "홍삼번", 22)); 
		
		model.addAttribute("stdList", stdList);
        
        [html]
        <table border="1">
        	<thead>
            	<tr>
                	<th>학번</th>
                    <th>학번</th>
                    <th>학번</th>
                </tr>
            </thead>
            
            <tbody>
            	<!-- th:each가 설정된 태그부터 반복(tr부터 반복) -->
            	<tr th:each="std : ${stdList}" th:object="${std}">  
                  <td th:text="*{studentNo}">학번</td> 
                  <td th:text="*{name}">이름</td>
                  <td th:text="*{age}">나이</td>
                  <!-- List 3요소
                   0번 인덱스 -> Student -> 김일번
                   1번 인덱스 -> Student -> 최이번
                   2번 인덱스 -> Student -> 홍삼번
                  -->
                </tr>
            </tbody>
  

ModelAttribute와 전혀 관련 없음 !!!!!!!!!!




💥 @RequestParam 어노테이션

[ 낱개 파라미터 컨트롤러에서 얻어오기 ]

  • request 객체를 이용한 파라미터 전달 어노테이션
  • html에 요청할 주소 action 속성에 작성 후 요청 보내는 메서드 방식 작성(GET / POST)
  • 해당 form태그 안에서 key name속성값에 입력
  • 아까 작성한 요청할 주소를 담고 있는 컨트롤러 메서드에서
    매개변수 앞에 해당 어노테이션을 작성하면, 매개변수에 값이 주입됨
  • 주입되는 데이터는 매개변수의 타입이 맞게 형변환/파싱이 자동으로 수행됨!

▶ 기본 작성법
@RequestParam("key") 자료형 매개변수명
→ ex) @RequestParam("title") String title

▶ 속성 추가 작성법
@RequestParam(value="name", required="false", defaultValue="1")

    value         : 전달받은 input 태그의 name 속성값 (파라미터 key)
    required      : 입력된 name 속성값 파라미터 필수 여부 지정 (기본값 true)
                    -> required = true 인 파라미터가 존재하지 않는다면
                                         (파라미터 값 전달하지 않는다면)
                       400 Bad Request 에러 발생
    defaultValue : 파라미터 중 일치하는 name 속성값이 없을 경우에 대입할 값 지정
                    -> required = false 인 경우 사용
    defaultValue = "10000" 지정 시 값 전달하지 않아도
                    에러 발생하지 않고 기본값으로 10000이 넘어감

 

[ 여러 개 파라미터 컨트롤러에서 얻어오기 ]

▶ String[ ]
▶ List<String>
▶ Map<String, Object> ➡ - 제출된 모든 파라미터가 Map에 저장된다
                                     - key(name속성값)가 중복되면 덮어쓰기가 된다!
                                     - 같은 name속성 파라미터가 String[ ], List로 저장이 안 되고
                                        String[ ], List 형태라면 처음에 체크한 값으로 넘어온다

@RequestParam 이용 시 참고사항 !
ex) form 태그 안에서 input 태그를 이용해서 테스트 중..
String형은 값 전달하지 않아도 에러발생하지 않음.
    파라미터로는 title=""&writer=""&...
-> 빈 문자열로 넘어감. 파라미터가 없는 게 아님!
-> required=true에 위배되지 않는 것.




💥 @ModelAttribute 어노테이션

  • DTO (또는 VO) 와 같이 사용하는 어노테이션
  • 전달받은 파라미터의 name 속성값이 같이 사용되는 DTO의 필드명과 같다면
    자동으로 setter를 호출해서 필드에 값을 세팅한다. (다를 땐 null)
  • @ModelAttribute 를 이용해 값이 필드에 세팅된 객체를 "커멘드 객체" 라고 부른다
  • @ModelAttribute 어노테이션 생략 가능!

→ (@ModelAttribute DTO타입 작성 객체명(변수명 같은 거라 내 맘대로 써도 됨))

@ModelAttribute 이용 시 참고사항 !

  • DTO에 기본 생성자가 필수로 존재해야 한다!
  • DTO에 setter가 필수로 존재해야 한다!
  • 매개변수에 들어올 데이터가 DTO필드명과 같은 속성값으로 들어오면 어노테이션은 생략 가능!



💥 @ResponseBody어노테이션

  • 반환값을 HTTP 응답 본문으로 직접 전송(값 그대로 돌려보낼 거야!!!)

  • 컨트롤러 메서드 반환 값을 Http 응답 본문에 직접 바인딩하는 역할임을 명시

  • 컨트롤러 메서드의 반환 값을
    비동기 요청했던 HTML/JS 파일 부분에 값을 돌려보낼 것이다!! 명시

    → 해당 어노테이션이 붙어있는 컨트롤러의 메서드는
        반환값이 forward/redirect가 아니다 라고 인식함

      만약 return에 0; 이라고 작성한다면 0이라는 값이 첫번째 then의 response 로 들어옴




💥MultipartFile이 제공하는 메서드

  • getSize() : 파일 크기
  • isEmpty() : 업로드 한 파일이 없을 경우 true / 있다면 false 반환
  • getOriginalFileName() : 원본 파일명
  • transferTo(경로) : 메모리 또는 임시 저장 경로에 업로드 된 파일을
                               원하는 경로에 실제로 전송(서버 어떤 폴더에 저장할지 지정)



💥 @Configuration 어노테이션

스프링 설정용 클래스임을 명시(스프링이 해당 클래스를 설정 정보로 인식하고 사용)
+ 객체로 생성해서 내부 코드를 서버 실행 시 모두 바로 실행
config 파일에 이 어노테이션이 전부 있어야 한다!!




💥 @PropertySource 어노테이션

  • 지정된 경로의 properties 파일 내용을 읽어와 사용
  • 사용할 properties 파일이 다수일 경우 해당 어노테이션 연속해서 작성 가능

classpath:/src/main/resources 경로를 의미!




💥 @Autowired 어노테이션

  • 등록된 Bean 중에서 타입이 일치하거나, 상속 관계에 있는 Bean을 지정된 필드에 주입 == 의존성 주입(DI)



💥 @Bean 어노테이션

  • 발자가 수동으로 생성한 객체의 관리를 스프링에게 넘기는 어노테이션(Bean) 등록
    → 개발자가 직접 객체 만들었지만 (new)
    → Bean으로 등록해서 Spring이 관리하도록 해줌!

  • @Bean 어노테이션이 작성된 메서드에서 반환된 객체는 Spring Container가 관리함(IOC)
    @ConfigurationProperties(prefix = "spring.datasource.hikari")

  • properties 파일의 내용을 이용해서 생성되는 bean을 설정하는 어노테이션
    prefix를 지정하여 spring.datasource.hikari으로 시작하는 설정을 모두 적용




💥 @ConfigurationProperties(prefix = "spring.datasource.hikari")

  • @PropertySource 로 읽어온 config.properties 파일의 내용 중
  • 접두사(앞부분, prefix)가 일치하는 값만 읽어옴



💥 MyBatis

  • 데이터의 입력, 조회, 수정, 삭제(CRUD)를 보다 편하게 하기 위해
    xml로 구조화 한 Mapper 설정 파일을 통해서 JDBC를 구현한 영속성 프레임워크
  • 기존에 JDBC를 통해 구현했던 상당 부분의 코드와 파라미터 설정 및 결과 매핑을 xml 설정을 통해 쉽게 구현할 수 있음

@Mapper 어노테이션

  • MyBatis 에서 제공하는 어노테이션

  • MyBatis가 해당 인터페이스를 DAO로 인식하여 SQL 매핑을 처리

  • 해당 어노테이션이 작성된 인터페이스는 namespace에 해당 인터페이스가 작성된
    mapper.xml 파일과 연결되어 SQL 호출/수행/결과 반환 가능

  • MyBatis에서 제공하는 Mapper 상속 객체가 Bean으로 등록됨

  • @Mapper를 사용할 때 @Repository 는 필요하지 않음
    -> MyBatis가 DAO 객체로 Mapper 인터페이스를 관리하기 때문




💥 @SesionAttributes ({"key", "key", "key"})

  • Model에 추가된 속성 중
    key 값이 일치하는 속성을 session scope로 변경해줌
 @SessionAttributes({"loginMember"})
.
.
.
model.addAttribute("loginMember", loginMember);

loginMember가 session scope로 변경됨 !

💥 SessionStatus

  • @SessionAttributes로 지정된 특정 속성을
    세션에서 제거하는 기능을 제공하는 객체
public String logout(SessionStatus status) {
		
		status.setComplete();
        // 세션을 완료시킴 (== 세션에서 @SessionAttributes로 등록된 세션 제거)

session scope로 변경됐던 loginMember가 제거됨 !




에러났는데 무슨 에러인지 모르겠다면?

구글에 error code 검색 후 MDN Web Docs의 HTTP 상태 코드 누르면 에러 종류별 설명이 적혀있음. 이거 보고 에러 추적하면 된당

1개의 댓글

comment-user-thumbnail
2024년 11월 17일

ModelAttribute
파라미터 키랑 필드명이 같을 때 Key == 필드명 --> Value를 setter를 이용해서 넣어줌

답글 달기