✔️ 다른 사람의 컴퓨터에 있는 프로그램 실행
✔️ 브라우저 + WAS ➡️ 원격 프로그램을 실행
브라우저에서 URL을 입력을 하고 엔터를 치면 톰캣포트가 8080을 사용하는데, 이 요청을 톰켓이 받아서 프로그램을 실행하게 된다.
하지만, 다른 컴퓨터의 프로그램을 아무거나 다 실행할 수는 없다. 그래서 웹에서 서버에 있는 원격 프로그램을 실행하기 위해서는 2가지의 일을 해야 한다.
1. 원격 호출이 가능한 프로그램 등록(@Controller)
2. URL과 프로그램을(메서드) 연결(@RequestMapping)
@Controller // 1. 프로그램 등록
public class Hello {
@RequestMapping("/hello") // 2. URL과 main()을 연결 / 이게 중요한 거임
private void main() { // 이름은 아무거나 상관없음. 꼭 main으로 써야되는 것이 아님!
System.out.println("Hello");
}
}
✏️ HomeController.java
이미 생성되어있는 기본 컨트롤러
package org.jipark09.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;
@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";
}
}
직접 만든 컨트롤러
package org.jipark09.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");
}
}
✔️ 구체적인 클래스 타입을 알지 못해도 그 클래스의 정보(메서드, 타입, 변수 등등)에 접근할 수 있게 해주는 자바 API
URL와 연결한 메서드가 private임에도 호출이 가능한 이유
@RequestMapping
은 외부에서 스프링 프레임워크가 java의 Reflection API를 이용해서 객체를 생성해 메서드를 호출하기 때문에 가능
package org.jipark09.ch2;
import java.lang.reflect.Method;
public class Main {
public static void main(String[] args) throws Exception {
// Hello h = new Hello();
// h.main(); // main()은 private라서 외부 호출 불가
// 아까는 Reflection API(클래스 정보를 얻고 다룰 수 있는 강력 기능 제공)를 사용했기 때문에 호출이 가능했던 것이다.
// java.lang.reflect 패키지 제공
// Hello 클래스의 Class 객체(클래스의 정보를 담고 있는 객체) 얻어온다.
// 클래스 파일(*.class)이 메모리에 올라갈 때, 클래스 파일마다 Class 객체가 하나씩 생성된다.
Class helloCass = Class.forName("org.jipark09.ch2.Hello");
Hello hello = (Hello) helloCass.newInstance(); // Class 객체가 가진 정보로 객체 생성
Method main = helloCass.getDeclaredMethod("main"); // main() 메서드의 정보를 가지고온다.
main.setAccessible(true); // private인 main()을 호출 가능하게 한다.
main.invoke(hello); // hello.main()과 동일
}
}
클래스 파일(*.class)이 메모리에 올라갈 때, 클래스 파일마다 Class객체가 하나씩 생성된다.
➡️ java.lang 패키지
스프링 프레임워크가 reflection API를 많이 사용한다.
private인데도 사용가능한 이유이다.
서블릿 URL패턴과 같다.
@WebServlet
: 서블릿@RequestMapping
: 스프링✏️ RequestMappingTest.java
package org.jipark09.Test;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class RequestMappingTest {
// @RequestMapping({"/login/hello.do", "/login/hi.do"})
@RequestMapping("/login/hello.do") // http://localhost:8080/login/hello.do url이 완벽하게 일치하니 얘가 처리함
public void test1() {
System.out.println("urlpattern=/login/hello.do");
}
@RequestMapping("/login/*") // /login/hello, /login/hi
public void test2() {
System.out.println("urlpattern=/login/*");
}
@RequestMapping("/login/**/tmp/*.do") // /login/tmp/hello.do, /login/aaa/tmp/hello.do
public void test3() {
System.out.println("urlpattern=/login/**/tmp/*.do");
}
@RequestMapping("/login/??")
public void test4() { // /login/hi, /login/my.car
System.out.println("urlpattern=/login/??");
}
@RequestMapping("*.do") // /hello.do, /hi.do, /login/hi.do
public void test5() {
System.out.println("urlpattern=*.do");
}
@RequestMapping("/*.???") // /hello.aaa, /abc.txt
public void test6() {
System.out.println("urlpattern=*.???");
}
}