스프링부트는 WAS를 내장하고 있음
스프링은 WAS를 설치해줘야함
-서블릿-
introduction
@ServletComponentScan // 현재 패키지포함한 하위패키지 까지 서블릿을 찾아서 자동으로 등록후 실행하게 해줌
서블릿클래스를 작성하려면 , HttpServlet 를 상속받아야 함
@WebServlet(name , urlPatterns ) // url이 호출되면 , 해당 어노테이션이 붙은 클래스내부의 service 메소드가 호출됨
HttpServletRequest 객체 : WAS가 client->server로 오는 http 내용을 파싱해서 가공한 것
HttpServletResponse 객체 : WAS가 server->client로 보내는 http 내용을 가공하는데 이용함
쿼리 파라미터 : URL의 ? 뒤에 붙은 데이터들
request.getParameter() : 쿼리 파라미터 조회
response.setContentType() : 전송 데이터 타입 결정(http 헤더 정보)
response.setCharacterEncoding() : 문자 인코딩 방식 결정(http 헤더 정보)
요즘은 문자인코딩 방식은 utf-8로 통일되어 있음
response.getWriter().write() : http 바디에 데이터 삽입
*로그확인
application.properties -> logging.level.org.apache.coyote.http11=debug ->http 헤더 정보를 보여줌
-개발에서만 적용해보고 , 운영서버에서는 삭제해줘야함
main/webapp/index.html 은 웰컴페이지로 초기화면임
HttpServletRequest
HttpServletRequest : 서블릿이 개발자대신에 Http 메시지를 파싱해서 HttpServletRequest 객체에 담아줌
request.setAttribute(name, value) : 임시 저장소 기능
request.getAttribute(name) : 임시 저장소 값 조회
request.getSession : 세션 정보를 받아옴 , HttpSession 객체로도 동일한 기능 수행
HTTP 스펙을 꼭 아는게 좋음
@WebServlet 이 붙은 클래스 내부의 메소드인 service는 접근제어자가 protected 이어야 한다.
HTTP 구성도 : START LINE , 헤더 , 바디
*HTTP 해더조회
request.getHeaderNames(); //HTTP에 있는 모든 헤더정보를 열거형으로 반환 (old)
request.getHeaderNames().asIterator()
.forEachRemaining(headerName -> System.out.println(headerName + ": " + request.getHeader(headerName))); (new)
request.getHeader("원하는 헤더종류") // 헤더종류에 대한 값 반환
HTTP헤더 -> Accept-Language : 가장우선하는 언어 순으로 데이터가 들어감
request.getServerName() = localhost
request.getServerPort() = 8080
request.getLocale() = ko_KR //가장 우선순위 높은 브라우저 언어를 꺼내줌
request.getCookies() //쿠키들을 가져와서 반환해줌 , 쿠키도 HTTP 헤더에 담긴다
request.getContentType() = null // GET 방식은 null이다
request.getContentLength() = -1
request.getCharacterEncoding() = UTF-8
*네트워크 정보 조회
[Remote 정보] // 상대(클라이언트)의 정보
request.getRemoteHost() = 0:0:0:0:0:0:0:1
request.getRemoteAddr() = 0:0:0:0:0:0:0:1
request.getRemotePort() = 62036
[Local 정보] // 내 (서버) 정보
request.getLocalName() = 0:0:0:0:0:0:0:1
request.getLocalAddr() = 0:0:0:0:0:0:0:1
request.getLocalPort() = 8080
*HTTP 요청 데이터
-GET(url+쿼리파라미터)
ex ) http://url/?username=hello&age=20
body 에 데이터를 보내지 않음
url의 쿼리 파라미터에 데이터를 포함해서 전송할뿐
검색,필터,페이징등
-POST(HTML form)
Content-Type : body에 대한 타입
메세지 바디에 쿼리 파라미터 형식으로 전달 , username=hello&age=20
회원가입,상품주문
-HTTP message body
HTTP message body 에 데이터를 직접 담아서 요청
REST API=HTTP API 에서 주로 사용
JSON(주로쓰임),XML,TEXT 형식으로 담아서 보냄
POST,PUT,PATCH 사용가능
*GET 쿼리파라미터
request.getParameterNames().asIterator()
.forEachRemaining(paramName ->System.out.println(paramName+"="+request.getParameter(paramName))); //모든요청파라미터 전부꺼냄
request.getParameter(name) // 단일 파라미터 조회 , 이름중복않됬을 경우에 사용하는게 원칙
request.getParameterValues(name); // 이름 동일한 복수파라미터들 반환
HTTP 바디가 비어있으므로, content-type 이 null이다
*POST HTML Form
HTTP 메시지바디에 데이터가 다들어감
클라이언트에서 html 페이지는 서블릿 설정안해도 , url만 잘 작성하면 들어갈수 있다(정적 html)
request.getParameter(name) 으로 get방식과 동일하게 post방식에서도 데이터를 꺼내온다
content-type 이 필수로 적혀 있음
*HTTP message body
메시지바디에 내가원하는 데이터를 직접실어서 서버에 전송하는 것
HTTP API=REST API 방식
전송 데이터중 JSON,XML(legacy),TEXT 가 있지만 대부분 JSON 사용
서버 <-> 서버 통신 , 앱 <->서버 , js기반클라이언트 <->서버
request.getInputStream();//얻어온 HTTP 바디의 내용을 바이트코드로 반환
StreamUtils.copyToString(인풋스트림, StandardCharsets.UTF_8);
//바이트를 문자열로 변환할 때는 어떤 인코딩 인지 알려줘야함 , 역의 경우도 마찬가지
-JSON 형식으로 데이터 주고받기
content-type: application/json 으로 해줘야함
서버에서 json데이터를 객체로 파싱해서 사용함
json의 key값에 매칭되는 클래스를 만들어주고 , getter &setter 을 생성해줘야함 ->
jackson이 setter에 매칭되게 객체로 파싱해줌
getter , setter를 삽입 대신에 , @Getter @Setter 를 클래스위에 넣어주면 동일한 기능을 함(롬복기능)
( 자바 빈 개념 참고 )
* Lombok은 여러가지 어노테이션을 제공, 컴파일과정에서 코드를 생성해 주는 방식으로 동작하는 라이브러리
private ObjectMapper objectMapper = new ObjectMapper(); // instance value
HelloData helloData=objectMapper.readValue(제이슨문자열, HelloData.class); //json형태 문자열-> 객체로 파싱 (old)
나중에 Spring mvc가 제공하는 기능을 이용하면 , 더 간략화 된다(new)
JSON 변환 라이브러리 : Jackson(default),Gson
HttpServletResponse
HTTP 응답 메세지 생성
200같은 HTTP 응답코드 , 헤더 , 바디를 일부자동생성 or 완전 자동생성 해줌
사용자가 Content-Type,쿠키,Redirect 셋팅을 편리하게 할 수 있게 해줌
response.setStatus(응답코드);//HTTP 응답코드를 넣읗 수 있음
HTTP스펙에서 응답의 첫번째는 'status-line' (응답코드) 이라고함
response.setHeader(name,value) // 헤더정보를 삽입
-Header 편의 메서드
response.setContentType("text/plain"); // 콘텐트 편의메소드
response.setCharacterEncoding("utf-8"); // 콘텐트 편의메소드
response.addCookie(cookie); // 쿠키 편의 메소드
response.setStatus(HttpServletResponse.SC_FOUND); //redirect 편의 메소드 , HTTP 응답코드 수정
response.setHeader("Location", "/basic/hello-form.html"); //redirect 편의 메소드 , 리다이렉트할 위치지정
response.sendRedirect("/basic/hello-form.html"); //redirect 편의 메소드 , 윗 두줄과 동일한 기능을 수행(302상태코드)
( 301 , 302 리다이렉션의 의미 )
PrintWriter writer = response.getWriter(); // 메세지 바디에 데이터 삽입
writer.println("ok");
-HTTP 응답스펙
START LINE , 헤더 , 바 디
*HTTP응답데이터 - 단순 텍스트 , HTML , JSON 응답
-단순텍스트
PrintWriter writer = response.getWriter(); // 메세지 바디에 데이터 삽입
writer.println("ok");
-HTML 응답(HTTP 바디에 html내용 삽입하기)
HTTP 응답으로 HTML을 반환할 때는 content-type: text/html 로 지정해줘야함
헤더편의 메소드를 통해 Encoding방식을 잡아줘야함
-JSON 보내기
HTTP 메세지 바디에 JSON 넣어보내기
객체 -> JSON 으로 파싱해야함
private ObjectMapper objectMapper = new ObjectMapper(); //인스턴스 value
objectMapper.writeValueAsString(객체); // json형 문자열반환 (old)
application/json은 스펙상 utf-8형식이 디폴트로 알아서 잡혀진다
Form data를 body에 담아 전송할 때는 POST방식만 허용한다