Spring 강의/springMVC

springMVC 활용 - (2) 서블릿 & Request

lxexjx 2022. 3. 26. 18:01

@ServletComponentScan : 스프링부트에서 서블릿을 사용하려면 스프링이 자동으로 하위 패키 뒤져서 서블릿 찾아서 자동으로 서블릿 등록.

 

@WebServlet() : 서블릿 어노테이션

http요청으로 매핑된 url호출되면 서블릿 컨테이너가 service메서드 실행

servlet은 http를 상속받아 

 

[HelloServlet]

@WebServlet(name = "helloServlet",urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {
    @Override   //서블릿 호출되면 서비스메서드 호출
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("HelloServlet.service");
        System.out.println("request = " + request);		//구현체
        System.out.println("response = " + response);	 //구현체    
		
        String username=request.getParameter("username");	//쿼리파라미터 조회
        System.out.println("username = " + username);
		
        
        //여기부턴 응답메세지 보내기
        response.setContentType("text/plain");	//header의 Content-Type에 들어가고
        response.setCharacterEncoding("utf-8");	//header의 Content-Type에 들어가고
        
        //http 메세지 body에 들어가고 
        response.getWriter().write("hello"+username);
    }
}

이 서블릿이 호출되면 서비스메서드가 호출됨

 

http요청이 오면 와스가 resp,resq객체를 만들어서 서블릿에 던져주는데 

그래서 웹브라우저가 url을 호출하면 웹브라우저가 http요청메세지를 만들어서 서버에 던지면 

request.getParameter로 쿼리파라미터 조회가능 

 

httpServletRequest,httpServletResponse는 인터페이스야, 톰캣이나 제티등 다양한 와스 서버가 이 표준 스펙을 구현 하는데 그 구현체가 찍히는것 

 

응답은 response에 - 값을 넣으면 http응답메세지에 data가 담겨서 나가 

response.getWriter().write("hello"+username);

httpBody에 data가 들어가

 

 

 

1. 스프링부트를 시작하면 톰캣 내장서버가 띄워지고 내장서버는 서블릿 컨테이너를 가지고 있어서 서블릿을 생성.

 

웹브라우저가 http메세지를 만들어서 서버에 던져주면

2.url치면 메세지 만들어서 던져줘

 

3. 서버는 request객체를 만들어서 helloServlet을 호출해

4.service메서드를 호출하면서 request,response를 넘겨줘

5.종료되고 나가면서 와스가 response정보를 가지고 응답메세지를 만들어서 반환

 


 

[HttpServletRequest] - 서블릿은 개발자가 HTTP 요청 메시지를 편리하게 사용할 수 있도록 개발자 대신에 HTTP 요청 메시지를 파싱한다. 그리고 그 결과를 HttpServletRequest 객체에 담아서 제공.

+request.setAttribute(name,val) : http요청 메세지 안에 data저장소가 있는데 http 메세지가 살아있는동안 쓸수있게 set으로 값을 넣고 get으로 꺼내고 

+request.getSession() : 세션 관리기능

 

 

<RequestHeaderServlet> - 헤더정보 출력

@WebServlet(name = "requestHeaderServlet",urlPatterns = "/request-header")
public class RequestHeaderServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        printStartLine(request);
        printHeaders(request);
        printHeaderUtils(request);
        printEtc(request);
        response.getWriter().write("ok");
    }


//start line 정보
private void printStartLine(HttpServletRequest request) {
        System.out.println("--- REQUEST-LINE - start ---");
        System.out.println("request.getMethod() = " + request.getMethod()); //GET
        System.out.println("request.getProtocal() = " + request.getProtocol()); //HTTP/1.1
        System.out.println("request.getScheme() = " + request.getScheme()); //http
        // http://localhost:8080/request-header
        System.out.println("request.getRequestURL() = " + request.getRequestURL());
        // /request-test
        System.out.println("request.getRequestURI() = " + request.getRequestURI());
        //username=hi
        System.out.println("request.getQueryString() = " + request.getQueryString());
        System.out.println("request.isSecure() = " + request.isSecure()); //https사용 유무
        System.out.println("--- REQUEST-LINE - end ---");
        System.out.println();
        }

    //Header 모든 정보
    private void printHeaders(HttpServletRequest request) {
        System.out.println("--- Headers - start ---");
/*
 Enumeration<String> headerNames = request.getHeaderNames();
 while (headerNames.hasMoreElements()) {
 String headerName = headerNames.nextElement();
 System.out.println(headerName + ": " + request.getHeader(headerName));
 }
*/
        request.getHeaderNames().asIterator().forEachRemaining(headerName -> System.out.println(headerName + ": " + request.getHeader(headerName)));
        System.out.println("--- Headers - end ---");
        System.out.println();
    }

    //Header 편리한 조회
    private void printHeaderUtils(HttpServletRequest request) {
        System.out.println("--- Header 편의 조회 start ---");
        System.out.println("[Host 편의 조회]");
        System.out.println("request.getServerName() = " + request.getServerName()); //Host 헤더
        System.out.println("request.getServerPort() = " + request.getServerPort()); //Host 헤더
        System.out.println();
        System.out.println("[Accept-Language 편의 조회]");
        request.getLocales().asIterator().forEachRemaining(locale -> System.out.println("locale = " + locale));
        System.out.println("request.getLocale() = " + request.getLocale());
        System.out.println();
        System.out.println("[cookie 편의 조회]");
        if (request.getCookies() != null) {
            for (Cookie cookie : request.getCookies()) {
                System.out.println(cookie.getName() + ": " + cookie.getValue());
            }
        }
        System.out.println();
        System.out.println("[Content 편의 조회]");
        System.out.println("request.getContentType() = " + request.getContentType());
        System.out.println("request.getContentLength() = " + request.getContentLength());
        System.out.println("request.getCharacterEncoding() = " + request.getCharacterEncoding());
        System.out.println("--- Header 편의 조회 end ---");
        System.out.println();
    }

    //기타 정보
    private void printEtc(HttpServletRequest request) {
        System.out.println("--- 기타 조회 start ---");
        System.out.println("[Remote 정보]");
        System.out.println("request.getRemoteHost() = " + request.getRemoteHost()); //
        System.out.println("request.getRemoteAddr() = " + request.getRemoteAddr()); //
        System.out.println("request.getRemotePort() = " + request.getRemotePort()); //
        System.out.println();
        System.out.println("[Local 정보]");
        System.out.println("request.getLocalName() = " + request.getLocalName()); //
        System.out.println("request.getLocalAddr() = " + request.getLocalAddr()); //
        System.out.println("request.getLocalPort() = " + request.getLocalPort()); //
        System.out.println("--- 기타 조회 end ---");
        System.out.println();
    }
}

 


 

[http요청 메세지로 클라이언트->서버로 data전달하는 방법]

1.Get쿼리 파라미터 : 바디에 data를 보내지 않고 /url?username=hello&age=20처럼 쿼리 파라미터에 데이터를 담아 전달 

 

[RequestParamServlet]

@WebServlet(name="requestParamServlet",urlPatterns = "/request-param")
public class RequestParamServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("전체 파라미터 조회-start");
        //파라미터의 키, 값 꺼내오기
        req.getParameterNames().asIterator().forEachRemaining(
        	paraName-> System.out.println(paraName(키)+"="+req.getParameter(paraName(값))));
        System.out.println("전체 파라미터 조회-end");


        System.out.println("단일 파라미터 조회-start");
        String username=req.getParameter("username");
        String age=req.getParameter("age");

        System.out.println("username="+username);
        System.out.println("age="+age);
        System.out.println("단일 파라미터 조회-end");

	//username=hello&username=hi
        System.out.println("이름이 같은 복수 파라미터 조회");
        System.out.println("request.getParameterValues(username)");
        String[] usernames = req.getParameterValues("username");
        for (String name : usernames) {
            System.out.println("username=" + name);
        }
        resp.getWriter().write("ok");

    }
}

paraname : 파라미터 네임(키), request.getParameter(paraName) : 값을 가져와

request.getParamNames() : 모든 요청 params이름,키 다 가져와

 

 

 

 

2.Post-html Form : 웹브라우저가 http메세지를 생성해서 html의 form을 사용해서 서버로 데이터를 전송

메세지 바디에 데이터가 들어가.

메세지 바디에 쿼리파라미터 형식으로 전달

[src/main/webapp/basic/hello-form.html]

<body>
<form action="/request-param" method="post">
    username: <input type="text" name="username" />
    age: <input type="text" name="age" />
    <button type="submit">전송</button>
</form>
</body>

 

*postman 사용 : html form만들기 귀찮을때

 

 

 

3.Http message body : 메세지 바디에 직접 담아서 서버에 요청. 주로 httpAPI에서 json으로 담아서 서버에 전달

 

[RequestBodyStringServlet] 단순 text

@WebServlet(name="requestBodyStringServlet",urlPatterns = "/request-body-string")
public class RequestBodyStringServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	//메세지 바디의 내용을 바이트 코드로 바로 얻음
        ServletInputStream inputStream=request.getInputStream();	
        //그 바이트 코드를 string으로 
        String messageBody=StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);	

        System.out.println("messageBody="+messageBody);

        response.getWriter().write("ok");
    }
}

 

[RequestBodyJsonServlet] Json형식으로 데이터 전달

@WebServlet(name="requestBodyJsonServlet" ,urlPatterns = "/request-body-json")
public class RequestBodyJsonServlet extends HttpServlet {

    private ObjectMapper objectMapper = new ObjectMapper();	//JSON을객체로 변환
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        ServletInputStream inputStream=request.getInputStream();
        String messageBody= StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);

        System.out.println("messageBody="+messageBody);

        HelloData helloData=objectMapper.readValue(messageBody, HelloData.class);	//JSON을객체로 변환

        System.out.println("helloData.username="+helloData.getUsername());	//JSON을객체로 변환
        System.out.println("helloData.age="+helloData.getAge());	//JSON을객체로 변환

        response.getWriter().write("ok");
    }
}

ps.JSON 결과를 파싱해서 사용할 수 있는 자바 객체로 변환하려면 Jackson, Gson 같은 JSON 변환 라이브러리를 추가해서 사용

**JSON 형식으로 파싱할 수 있게 객체를 하나 생성(JSON형식의 데이터를 객체로 바꿀 수 있게 객체 하나 생성 )

<hello.servlet.basic.HelloData>

@Getter @Setter     //롬복을 사용하면 자동으로 getter setter가 들어감
public class HelloData {
    private String username;
    private int age;
}

JSON을 자바 객체로 변환 하려면 JSON변환 라이브러리를 추가해야됨.