Back-end Skill/Springboot

스프링 MVC 정리본 1

Sophie소피 2022. 2. 12. 12:44

 

 

1) Spring Annotation

어노테이션설명
@Controller 스프링 MVC의 컨트롤러 객체임을 명시하는 어노테이션
@RequestMapping 특정 URI에 매칭되는 클래스나 메소드임을 명시하는 어노테이션
@RequestParam request의 파라미터를 가져오는 기능을 하며 메소드내에 변수로 활용
@RequestHeader 요청(request)에서 특정 HTTP헤더 정보를 추출할 때 사용
@PathVariable 메소드 파라미터 앞에 사용하며 해당 URL에 { } 특정 파라미터를 변수로 활용 가능
@CookieValue 현재 사용자의 쿠키가 존재하는 경우 쿠키 이름을 이용해서 쿠키 값을 추출
@ModelAttribute view에서 전달해주는 파라미터를 클래스의 멤버변수로 binding 해주는 어노테이션
@InitBinder 파라미터를 수집해서 객체로 만들 경우에 커스터마이징
@ResponseBody JSON 형식의 데이터값을 응답할 때 사용하는 것으로 response Body에 형식이 노출객체를 return시 json 라이브러리에 의해 문자열로 변환
@RequestBody 요청이 들어온 데이터(Json, XML)를 클래스나 model로 매핑
@Repository DAO 객체
@Service 서비스 객체
@SessionAttributes @SessionAttributes(“name”)이라고 하면 Model에 key값이 “name”으로 있는 값은 자동으로 세션에 저장
@Runwith JUnit 프레임워크의 테스트를 할수 있도록 설정 @Runwith에 Runner클래스 설정시 JUnit의 내장된 runner대신 설정한 SpringJUnit4ClassRunner를 실행
@ContextConfiguration 지정된 클래스나 문자열을 이용해 필요한 객체들을 스프링내 객체로 등록
@Log4j Lombok을 이용해 로그를 기록하기 위한 Logger 변수 생성
@Autowired 해당 인스턴스 변수에 스프링으로부터 자동으로 Bean을 주입, new 연사자와 같음
@Test JUnit에서 테스트 대상을 표시하며 단위테스트 메소드임을 명시
@Component Component는 스프링에게 해당 클래스가 관리해야할 대상임을 표시
@Setter Set( ) 메소드를 자동으로 생성하여, 사용할수 있게 해줌
@Getter Get( ) 메소드를 자동으로 생성하여, 사용할수 있게 해줌
@GetMapping RequestMapping(Method=RequestMethod.GET)과 동일
@PostMapping RequestMapping(Method=RequestMethod.POST)과 동일
@Transactional 데이터베이스 트랜잭션 설정 어노테이션 (AutoCommit, rollback, commit 등) DB의 접근이 하나라도 실패시 rollback 비지니스 로직과 트랜잭션 관리는 모두 Service에서 하기때문에 Service 메소드는 @Transactional 사용
@Cacheable 메소드 앞에 지정하여 사용하며 메소드를 최초 호출시 캐시에 적재하고 추후 동일한 요청이 들어올 시 캐시의 결과를 리턴. 메소드의 호출 횟수를 줄여주는 어노테이션
@RestController Spring Restful Controller로 데이터를 반환하는 컨트롤러이다. view가 필요없는 API에 지원(Spring 4.0.1 이후)하며, @RequestMapping 메소드가 @ResponseBody 의미를 가정한다. data(json, xml) return 시 사용

2) Lombok Annotation

어노테이션설명
@AllArgsConstructor 모든 필드를 파라미터로 가지는 생성자를 생성
@NoArgsConstructor 파라미터가 없는 기본 생성자를 생성
@RequiredArgsConstructor final, @NonNull 인 필드값만 파라미터로 받는 생성자를 생성
@EqualsAndHashCode equals( )메소드와 hashCode( )메소드를 오버라이드
@Data @toString, @getter/setter, @RequiredArgsConstructor 등 모두 사용한것과 같은 기능

3) Jpa Annotation

어노테이션설명
@Entity 데이터베이스의 테이블과 1대1 매칭
@Id 테이블 컬럼의 기본키에 설정
@Column 테이블 컬럼에 설정, @Entity로 지정시 생략가능
@GeneratedValue 기본키에 지정된 auto increment 등의 속성을 지정
@EmbeddedId 테이블 컬럼의 복합키에 설정
@Enumerated enum과 관련되어 있으며, EnumType.ORDINAL, STRING의 속성
@Transient 데이터베이스에서 실제 사용하지 않는 것을 지정, 임시값으로 활용

 

HttpServletRequest 역할 HTTP 요청 메시지를 개발자가 직접 파싱해서 사용해도 되지만,

매우 불편할 것이다. 서블릿은 개발자가 HTTP 요청 메시지를 편리하게 사용할 수 있도록

개발자 대신에 HTTP 요청 메시지를 파싱한다. 그리고 그 결과를 HttpServletRequest 객체에 담아서 제공한다. HttpServletRequest를 사용하면 다음과 같은 HTTP 요청 메시지를 편리하게 조회할 수 있다.

HTTP 요청 메시지

 

POST /save HTTP/1.1 Host: localhost:8080
Content-Type:application/x-www-form-urlencoded 
username=kim&age=20

START LINE

-HTTP 메소드

-URL

- 쿼리 스트링

-스키마, 프로토콜 헤더

 

헤더

-헤더 조회

 

바디 

-form 파라미터 형식 조회

message body 데이터 직접 조회

 

HttpServletRequest 객체는 추가로 여러가지 부가기능도 함께 제공한다.

 

임시 저장소 기능

해당 HTTP 요청이 시작부터 끝날 때 까지 유지되는 임시 저장소 기능

저장: request.setAttribute(name, value)

조회: request.getAttribute(name)

 

세션 관리 기능

request.getSession(create: true)

 

중요 >

HttpServletRequest, HttpServletResponse를 사용할 때

가장 중요한 점은 이 객체들이 HTTP 요청 메시지,

HTTP 응답 메시지를 편리하게 사용하도록 도와주는 객체라는 점이다.

따라서 이 기능에 대해서 깊이있는 이해를 하려면 HTTP 스펙이 제공하는 요청, 응답 메시지 자체를 이해해야 한다.

 

 

HTTP 요청 데이터 - 개요

HTTP 요청 메시지를 통해 클라이언트에서 서버로

데이터를 전달하는 방법을 알아보자. 주로 다음 3가지 방법을 사용한다.

 

GET - 쿼리 파라미터

/url?username=hello&age=20 메시지 바디 없이,

URL의 쿼리 파라미터에 데이터를 포함해서 전달

예) 검색, 필터, 페이징등에서 많이 사용하는 방식

 

POST - HTML Form

content-type: application/x-www-form-urlencoded 메시지 바디에 쿼리 파리미터 형식으로 전달 username=hello&age=20 예) 회원 가입, 상품 주문, HTML Form 사용

 

HTTP message body에 데이터를 직접 담아서 요청

HTTP API에서 주로 사용, JSON, XML, TEXT 데이터 형식은

주로 JSON 사용 POST, PUT, PATCH POST- HTML Form 예시

 

HTTP 요청 데이터 - GET 쿼리 파라미터

다음 데이터를 클라이언트에서 서버로 전송해보자.

전달 데이터

- username=hello

- age=20

메시지 바디 없이, URL의 쿼리 파라미터를 사용해서 데이터를 전달하자.

예) 검색, 필터, 페이징등에서 많이 사용하는 방식

 

쿼리 파라미터는 URL에 다음과 같이 ? 를 시작으로 보낼 수 있다. 추가 파라미터는 & 로 구분하면 된다. http://localhost:8080/request-param?username=hello&age=20 서버에서는 HttpServletRequest 가

제공하는 다음 메서드를 통해 쿼리 파라미터를 편리하게 조회할 수 있다.

 

쿼리 파라미터 조회 메서드

String username = request.getParameter("username"); //단일 파라미터 조회
Enumeration<String> parameterNames = request.getParameterNames(); //파라미터 이름들
모두 조회
Map<String, String[]> parameterMap = request.getParameterMap(); //파라미터를 Map
으로 조회
String[] usernames = request.getParameterValues("username"); //복수 파라미터 조회

package hello.servlet.basic.request;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
/**
 * 1. 파라미터 전송 기능
 * http://localhost:8080/request-param?username=hello&age=20
 * <p>
 * 2. 동일한 파라미터 전송 가능
 * http://localhost:8080/request-param?username=hello&username=kim&age=20
 */
@WebServlet(name = "requestParamServlet", urlPatterns = "/request-param")
public class RequestParamServlet extends HttpServlet {
 @Override
 protected void service(HttpServletRequest request, HttpServletResponse
resp) throws ServletException, IOException {
 System.out.println("[전체 파라미터 조회] - start");
 /*
 Enumeration<String> parameterNames = request.getParameterNames();
 while (parameterNames.hasMoreElements()) {
 
 String paramName = parameterNames.nextElement();
 System.out.println(paramName + "=" +
request.getParameter(paramName));
 }
 */
 request.getParameterNames().asIterator()
 .forEachRemaining(paramName -> System.out.println(paramName +
"=" + request.getParameter(paramName)));
 System.out.println("[전체 파라미터 조회] - end");
 System.out.println();
 System.out.println("[단일 파라미터 조회]");
 String username = request.getParameter("username");
 System.out.println("request.getParameter(username) = " + username);
 String age = request.getParameter("age");
 System.out.println("request.getParameter(age) = " + age);
 System.out.println();
 System.out.println("[이름이 같은 복수 파라미터 조회]");
 System.out.println("request.getParameterValues(username)");
 String[] usernames = request.getParameterValues("username");
 for (String name : usernames) {
 System.out.println("username=" + name);
 }
 resp.getWriter().write("ok");
 }
}

실행 - 파라미터 전송
http://localhost:8080/request-param?username=hello&age=20
//결과 
[전체 파라미터 조회] - start
username=hello
age=20
[전체 파라미터 조회] - end
[단일 파라미터 조회]
request.getParameter(username) = hello
request.getParameter(age) = 20
[이름이 같은 복수 파라미터 조회]
request.getParameterValues(username)
username=hello
username=kim

[전체 파라미터 조회] - start
username=hello
age=20
[전체 파라미터 조회] - end
[단일 파라미터 조회]
request.getParameter(username) = hello
request.getParameter(age) = 20
[이름이 같은 복수 파라미터 조회]
request.getParameterValues(username)
username=hello
username=kim

복수 파라미터에서 단일 파라미터 조회

username=hello&username=kim 과 같이 파라미터 이름은 하나인데,

값이 중복이면 어떻게 될까?

request.getParameter() 는 하나의 파라미터 이름에 대해서

단 하나의 값만 있을 때 사용해야 한다. 지금처럼 중복일 때는

request.getParameterValues() 를 사용해야 한다.

참고로 이렇게 중복일 때 request.getParameter() 를 사용하면

request.getParameterValues() 의 첫 번째 값을 반환한다.

 

트레픽 과부화걸렷을 때 어떻게 해야하는가?

Scale up 

scale out 

로드 밸런서 동작 방식 

 

커넥션 풀 

 

테크톡 강의