참고
수업 중간에 AWS에 올리는 과정이 포함되어있으나 우선 Spring을 익히는 것이 목적이므로 이 부분은 메모를 남기지 않음.


01. 원격 프로그램의 실행

  • 내 컴퓨터인 로컬에서 실행하는 프로그램이 아닌, 다른 컴퓨터에서 실행하는 프로그램은 원격 프로그램에 해당됨.

프로젝트 생성


File > new > Spring lagacy Project 로 프로젝트 생성

Spring starter Project는 스프링 부트 프로젝트를 생성하는 메뉴이므로 이 강의를 들을때는 사용하지 않음


위 사진처럼 ch2라는 새로운 스프링 프로젝트를 생성. (사진은 이미 생성 후이므로 에러발생)
도메인은 com.fastcampus.ch2로 설정한다.

-HemeController-

package com.fastcampus.ch2;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Handles requests for the application home page.
 */
@Controller		// 1. 원격호출 가능한 프로그램으로 등록
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	
	// 2. URL과 메서드 연결(매핑, mapping)
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
}

-Hello.java-

package com.fastcampus.ch2;

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

// 1. 원격호출 가능한 프로그램으로 등록
@Controller
public class Hello {
	int iv = 10;	// 인스턴스 변수 (iv)
	static int cv = 20;	// static 변수 (cv)
	
	// URL과 메서드를 연결
	@RequestMapping("/hello")
	private void main() {		// 인스턴스 메서드 - iv, cv 둘 다 사용가능
		System.out.println("Hello!");
		System.out.println(cv);	// OK
		System.out.println(iv);	// OK
	}
	
	public static void main2() {	// static 메서드 - cv만 사용가능
		System.out.println(cv);	// OK
//		System.out.println(iv);	// 에러 - static메서드는 cv만 사용할 수 있기 때문
	}
}

-Main.java-

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(); 	// 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() 호출
	}
}

원격 프로그램에 대한 개념설명

Spring framework에서의 main메서드와 static

spring의 main메서드는 static이 없어도 무관.
URL로 원격프로그램을 요청하면 톰캣이 내부에서 객체를 생성해주어 static으로 선언하지 않은 인스턴스메서드임에도 호출이 가능한 것.

인스턴스 메서드로 사용하는 이유:
인스턴스 변수와 static변수를 모두 사용할 수 있기 때문.

static메서드에서는 static변수만 사용가능함.
이에 대한 설명은 Ch02. 객체지향입문 03 참고.

Spring framework에서의 접근지정자(public, private)

접근지정자를 public이 아니라 private로 선언해도 정상적으로 동작함.
=> @RequestMapping를 사용하면 접근제어자와 관계없이 해당 메서드를 외부에서 호출할 수 있도록 하겠다는 의미이므로 정상동작하는것.
단, 내부에서는 그대로 private인 상태.

클래스파일(*.class)이 메모리에 올라갈 때, 클래스파일마다 Class객체가 하나씩 생성된다.

Reflection API를 당장 알아야 하는건 아니지만 spring framework에서 자주 사용되므로 알아는 두는게 좋음.


02. HTTP 요청과 응답

예제

YoilTeller: 년.월.일을 입력하면 요일을 알려주는 프로그램

-YoilTeller.java-

package com.fastcampus.ch2;

import java.util.Calendar;

// 년월일을 입력하면 요일을 알려주는 프로그램
public class YoilTeller {
	public static void main(String[] args) {
		
		// 1. 입력
		String year = args[0];
		String month = args[1];
		String day = args[2];
		
		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);	// 1: 일요일, 2: 월요일 ...
		char yoil = " 일월화수목금토".charAt(dayOfWeek);
		
		// 3. 출력
		System.out.println(year + "년 " + month + "월 " + day + "일은 ");
		System.out.println(yoil + "요일입니다.");
	}
}

실행은 .java파일이 컴파일된 파일이 target폴더에 위치하게 되므로
target폴더 우클릭 > terminal 열기 > cd classes로 이동한 후
java com.fastcampus.ch2.YoilTeller 2022 09 03을 입력하여 테스트.
맨 뒤의 숫자들은 매개변수로 넣어줄 값이 된다.


현재 요일을 반환함을 확인가능.

main메서드에서 매개변수를 String 배열로 받아 요일을 구할때 사용함.
String[] args 를 통해 String배열로 받았기 때문에 int로 변경하는 과정이 필요한 것.

서버로 매개변수를 받을때는 HttpServletRequest를 이용하여 매개변수로 받음.

HttpServletRequest의 method

http://52.78.79.190:8080/ch2/requestInfo?year=2022&month=9&day=3

getScheme() : http
getServerName() : 52.78.79.190
getServerPort() : 8080
getContextPath() : ch2
getServletPath() : requestInfo
getRequestURI() : /ch2/requestInfo
getRequestURL() : http://52.78.79.190:8080/ch2/requestInfo
getQueryString() : year=2022&month=9&day=3

?뒤의 url이 값을 전달할 때 사용하는 queryString
URI와 URL의 차이

YoilTeller.java를 로컬 프로그램에서 원격 프로그램으로 변경

-YoilTeller.java-

package com.fastcampus.ch2;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Calendar;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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

// 년월일을 입력하면 요일을 알려주는 프로그램
@Controller
public class YoilTeller {
	
//	public static void main(String[] args) {
	@RequestMapping("/getYoil")
	public void main(HttpServletRequest request, HttpServletResponse response) throws IOException{
		
		// 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);	// 1: 일요일, 2: 월요일 ...
		char yoil = " 일월화수목금토".charAt(dayOfWeek);
		
		// 3. 출력
        response.setContentType("text/html");    // 응답의 형식을 html로 지정
        response.setCharacterEncoding("utf-8");  // 응답의 인코딩을 utf-8로 지정
        PrintWriter out = response.getWriter();  // 브라우저로의 출력 스트림(out)을 얻는다.
        out.println("<html>");
        out.println("<head>");
        out.println("</head>");
        out.println("<body>");
        out.println(year + "년 " + month + "월 " + day + "일은 ");
        out.println(yoil + "요일입니다.");
        out.println("</body>");
        out.println("</html>");
        out.close();
	}
}

톰캣서버 실행 후
http://localhost:8090/ch2/getYoil?year=2022&month=9&day=3 로 값을 넘겨 확인


03. HTTP요청과 응답 실습

서버란?
서비스를 제공하는 애플리케이션

클라리언트란?
서버를 요청하는 애플리케이션

주사위 굴리기 예제

랜덤한 주사위를 굴리는 프로그램
실행 할때마다 결과가 변하는 동적리소스.
html, js, css처럼 리소스내용이 고정되어 있는 리소스는 정적리소스에 해당한다.
위에서 사용한 ch2프로젝트에 클래스를 추가함

-TwoDice.java-

package com.fastcampus.ch2;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletResponse;

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

@Controller		// ctrl + shift + o => 자동 import
public class TwoDice {
	@RequestMapping("/rollDice")
	public static 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();
    }

}



자바에서 제공하는 랜덤함수를 이용하여 1~6사이의 수를 구하여 해당 숫자에 해당하는 resources > img 폴더의 Dice.jpg이미지를 꺼내어 html로 출력해줌.


04. 클라이언트와 서버

getQueryString() : ?name1=value1&name2=value2
=> QueryString이므로 name과 value모두 String이므로, 형변환이 필요할 수 있다.

getParameterValues("name") 을 이용하면 모든 value값을 배열로 가져올 수 있음.

클라이언트와 서버

서버란?
서비스를 제공하는 애플리케이션 (응답하는 역할)

클라리언트란?
서버를 요청하는 애플리케이션 (요청하는 역할)

서버는 종류에 따라 email server, file server, web server 등으로 구분되는데, 요청의 ip주소만으론 이를 구분할 수 없다.
이를 구분하기 위해서 사용하는것이 port번호가 이다.
web server의 경우 기본적으로 포트번호 80번을 사용하지만 기본설정과 다른 포트번호로 설정해둘 경우 생략이 불가능함.

웹 애플리케이션 서버(WAS)

  • 웹 애플리케이션을 서비스하는 서버
  • 클라이언트가 원격 프로그램을 호출했을때 실행결과를 전송하는 역할을 WAS(Web Application Server)가 담당하게 됨.
  • 톰캣역시 WAS에 해당함.

Tomcat의 내부구조

요청이 왔을때 thread

컨트롤러와 서블릿은 비슷한 개념임
서블릿 servlet : 작은 서버프로그램의 개념


톰캣의 설정파일

  • 톰캣설치경로/conf/server.xml : Tomcat 서버 설정 파일
  • 톰캣설치경로/conf/web.xml : Tomcat의 모든 web app의 공통설정
  • 웹앱이름/WEB-INF/web.xml : web app의 개별설정

설정적용순서: 공통설정 적용 -> 개별설정 적용

예전에는 web.xml에서 1) 원격프로그램 등록 2) URL연결을 직접 해줘야 했지만 요즘은 전부 에너테이션@Controller @RequestMapping("/name")으로 처리함.

profile
천 리 길도 가나다라부터

0개의 댓글

Powered by GraphCDN, the GraphQL CDN