Ch. 02 Spring MVC - 1

2023. 1. 2. 11:51

1. 원격 프로그램의 실행

 

원격프로그램을 실행하기 위해서는 우선 tomcat에

  1. 프로그램을 등록하고
  2. URL과 프로그램을 연결해야 한다.

그리고 브라우저에서 해당 URL을 호출 하면 됨

 

package com.fastcampus.ch2;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

// 1. 원격 호출가능한 프로그램으로 등록
@Controller
public class Hello {
	// 2. URL과 메서드를 연결
	@RequestMapping("/hello")
	public void main() {
		System.out.println("Hello");
	}
}

http://111.222.333.444:8080/ch2/hello를 브라우저에 입력하면 main 메서드를 실행시킴

 

tomcat 내부에서 객체 생성을 해주므로 static 없이 void main() 으로 즉 인스턴스 메서드 호출이 가능하다.

인스턴스 메서드는 인스턴스 변수와 static 변수 모두 사용 가능 (얘가 유용)
static 메서드는 static 변수만 사용 가능

 

private void main()으로 해도 RequestMapping에 의해 실행이 가능하다. 하지만 프로그램 내부에서는 private이므로 다른 java파일에서 접근이 불가능 하다.

Reflection API를 사용 - 클래스 정보를 얻고 다룰 수 있는 강력한 기능을 제공 (private라도 접근가능한 방법)
java.lang.reflect 패키지를 제공 
package com.fastcampus.ch2;

import java.lang.reflect.Method;

public class Main {
	public static void main(String[] args) throws Exception{
		//Hello hello = new Hello();
		//hello.main(); // private  외부 호출 불가능
		
		//Reflection API를 사용 - 클래스 정보를 얻고 다룰 수 있는 강력한 기능을 제공하기 때문이다.
		//java.lang.reflect 패키지를 제공
		// Hello 클래스의 Class 객체 (클래스의 정보를 담고 있는 객체)를 얻어온다.
		Class helloClass = Class.forName("com.fastcampus.ch2.Hello");
		Hello hello = (Hello)helloClass.newInstance(); // Class 객체가 가진 정보로 객체 생성
		Method main = helloClass.getDeclaredMethod("main");
		main.setAccessible(true); // private인 main()을 호출가능하게 한다.
		
		main.invoke(hello); //hello.main()
		
	}
}

2. AWS에 배포하기

1번에서는 같은 컴퓨터에 서버를 구축해서 돌린것임. 우리가 만든 프로그램을 AWS에 올려서 AWS에 있는 프로그램을 실행시켜보자.

 

AWS 인스턴스 중지시키고 다시 실행시킬때 IP가 바뀌므로 원격 데스크톱 파일 다운로드 다시 받아야함

 

내 컴퓨터에서 만든 프로젝트 Export를 통해 war파일로 만들고 AWS에 접속해서 tomcat의 webapps 폴더에 복사 붙혀넣기 한 후 tomcat 실행시킨다.

그리고나면 해당 인스턴스의 IP를 통해 접근이 가능해진다.

3. HTTP 요청과 응답 - 실습

YoilTeller의 main문을 실행 시키는데 2023 , 1 , 2 가 각각 args[0] , args[1] , args[2] 문자열로 전달됨

 

마찬가지로 원격프로그램을 브라우저로 URL을 통해 호출을 하면 tomcat이 HttpServletRequest 객체를 만든다.
요청한 정보를 HttpServletRequest 에 넣어서 main 메소드에 넘겨준다.

다음 코드를 참고하자. 

@Controller
public class RequestInfo {
    @RequestMapping("/requestInfo")
    public void main(HttpServletRequest request) {
        System.out.println("request.getCharacterEncoding()="+request.getCharacterEncoding()); // 요청 내용의 인코딩
        System.out.println("request.getContentLength()="+request.getContentLength());  // 요청 내용의 길이. 알수 없을 때는 -1
        System.out.println("request.getContentType()="+request.getContentType()); // 요청 내용의 타입. 알 수 없을 때는 null

        System.out.println("request.getMethod()="+request.getMethod());      // 요청 방법
        System.out.println("request.getProtocol()="+request.getProtocol());  // 프로토콜의 종류와 버젼 HTTP/1.1
        System.out.println("request.getScheme()="+request.getScheme());      // 프로토콜

        System.out.println("request.getServerName()="+request.getServerName()); // 서버 이름 또는 ip주소
        System.out.println("request.getServerPort()="+request.getServerPort()); // 서버 포트
        System.out.println("request.getRequestURL()="+request.getRequestURL()); // 요청 URL
        System.out.println("request.getRequestURI()="+request.getRequestURI()); // 요청 URI

        System.out.println("request.getContextPath()="+request.getContextPath()); // context path
        System.out.println("request.getServletPath()="+request.getServletPath()); // servlet path
        System.out.println("request.getQueryString()="+request.getQueryString()); // 쿼리 스트링

        System.out.println("request.getLocalName()="+request.getLocalName()); // 로컬 이름
        System.out.println("request.getLocalPort()="+request.getLocalPort()); // 로컬 포트

        System.out.println("request.getRemoteAddr()="+request.getRemoteAddr()); // 원격 ip주소
        System.out.println("request.getRemoteHost()="+request.getRemoteHost()); // 원격 호스트 또는 ip주소
        System.out.println("request.getRemotePort()="+request.getRemotePort()); // 원격 포트
    }
}

 

getQueryString()범위에 ?year=2021&month=10&day=1 이렇게 되어있을 때 (전부다 문자열임)

String year = request.getParameter("year");   // 2021
String month = request.getParameter("month");   // 10
String day = request.getParameter("day");   // 1

 

<원격 프로그램>

package com.fastcampus.ch2;

import java.util.Calendar;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class YoilTeller {
    @RequestMapping("/getYoil") // http://localhost:8080/ch2/getYoil?year=2021&month=10&day=1
    public void main(HttpServletRequest request){
        // 1. 입력
        String year = request.getParameter("year");
        String month = request.getParameter("month");
        String day = request.getParameter("day");
 
        int yyyy = Integer.parseInt(year);
        int mm = Integer.parseInt(month);
        int dd = Integer.parseInt(day);

        // 2. 작업
        Calendar cal = Calendar.getInstance();
        cal.set(yyyy, mm - 1, dd);

        int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
        char yoil = " 일월화수목금토".charAt(dayOfWeek);   // 일요일:1, 월요일:2, ... 

        // 3. 출력
        System.out.println(year + "년 " + month + "월 " + day + "일은 ");
        System.out.println(yoil + "요일입니다.");

    }
}

 

브라우저에 http://localhost:8080/ch2/getYoil?year=2021&month=10&day=1로 접근하면

 

 

 

Console에 왼쪽 그림과 같이 출력된다.

브라우저에 출력하고 싶을 때는 HttpServletResponse를 사용해야 한다. 그리고 출력할대는 밑에 코드 처럼 하면 된다.

public void main(HttpServletRequest request, HttpServletResponse response)

//출력
response.setContentType("text/html");    // 응답의 형식을 html로 지정
response.setCharacterEncoding("utf-8");  // 응답의 인코딩을 utf-8로 지정
PrintWriter out = response.getWriter();  // 브라우저로의 출력 스트림(out)을 얻는다.
out.println(year + "년 " + month + "월 " + day + "일은 ");
out.println(yoil + "요일입니다.");

4. HTTP 요청과 응답 - 예제

@Controller
public class TwoDice {
	@RequestMapping("/rollDice")
	public void main(HttpServletResponse response) throws IOException {
		
		int idx1=(int)(Math.random()*6)+1;
		int idx2=(int)(Math.random()*6)+1;
		
		response.setContentType("text/html");
		response.setCharacterEncoding("utf-8");
		PrintWriter out = response.getWriter();
	    out.println("<html>");
	    out.println("<head>");
	    out.println("</head>");
	    out.println("<body>");
	    out.println("<img src='resources/img/dice"+idx1+".jpg'>");
	    out.println("<img src='resources/img/dice"+idx2+".jpg'>");
	    out.println("</body>");
	    out.println("</html>");
	    out.close();
		
	}
}

 

<서버가 제공하는 리소스 종류>

  • 동적 리소스 : TwoDice.java와 같이 실행시마다 결과가 변하는 것 , 프로그램이나 스트리
  • 정적 리소스 : img 같은 이미지 파일, js, css, html 파일등

'Spring > 스프링의 정석' 카테고리의 다른 글

Ch. 02 Spring - Redirect와 Forward  (0) 2023.01.08
Ch. 02 Spring - 서블릿과 JSP  (0) 2023.01.07
Ch. 02 Spring MVC - MVC 패턴  (0) 2023.01.04
Ch. 02 Spring MVC - 2  (0) 2023.01.03
Ch. 01 Spring 시작하기  (0) 2023.01.02

BELATED ARTICLES

more