국비/JSP

2023.03.27 42일차 Java & JSP

춘핑이 2023. 3. 27. 18:26

42일차

19장네트워크

톰캣에서 이런 것들이 일어난다.
브라우저에서 서버로 소켓을 열어달라고 한다.
브라우저는 html코드를 받기 위해 이런일을 한다.
html은 서버에서 클라이언트에게 요청하기 위한 목적으로 한다.
클라이언트와 서버거 html을 주고받을 목적으로 하고 이것을 주고받는 약속을 한다.

이것을 HTTP Hypertext Transfer Porotocol이다.
하이퍼텍스트 통신 규약이다.
서버와 클라이언트간 하이퍼텍스트를 어떻게 주고 받는지에 대한 약속이다.

소켓으로 Http Request(요청) Http Response(응답)을 통해 데이터를 주고받는다.
http는 이 요청과 응답을 어떻게 작성해야하는지에 대한 명세서이다.
이 메시지에 규약이 있다.

19.1 request 요청

요청의 구성요소는 3가지로 되어있다.다음과 같다.
첫줄의 구성요소
http메소드 / url / 버전

두번째 줄부터는 헤더내용이 온다.
헤더명 : 해더값 으로 여러값들이 온다.

헤더들이 나오고 한줄띄고 요청 본문이 나온다.

접속을 하면 다음과 같이 나온다.
첫번째줄
GET / HTTP / 1.1

두번째줄~
Host: 172.30.1.60
Connection: keep-alive
Cache-Control: max-age=0
DNT: 1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: ko-KR,ko;q=0.9

간단하게 서버를 만들어볼수 잇는데 톰캣이 이런걸 해결해준다.
웹서버의 통신은 80번부터 시작한다.

19.2 response 응답

서버가 브라우저로 보내는 response응답도 세줄로 이루어진다.

첫번째 줄은 상태줄이다.
버전 / 상태코드 / 상태 텍스트

두번째줄부터는 응답메시지 헤더들이다.
헤더명 : 값으로 보내진다.
Content-Type과 Content-Length는 꼭받아야한다. 길이는 보낼 데이터의 바이트 길이이다.

빈줄

세번째 줄부터 본문이 들어온다.

public class C02Server {
    public static void main(String[] args) {
        int port = 80;

        try (ServerSocket serverSocket = new ServerSocket(port);) {
            System.out.println("요청 기다리는 중");
            try (Socket socket = serverSocket.accept();
                    OutputStream os = socket.getOutputStream();
                    PrintStream ps = new PrintStream(os);) {

                String body = """
                        <h1>This is Naver!!</h1>
                        <h3>다른 사이트로 이동</h3>
                        <ul>
                            <li><a href = "https://www.daum.net">daum</a></li>
                            <li><a href = "https://www.google.com">google</a></li>
                        </ul>
                        """;
                int length = body.getBytes().length;
                //첫줄
                ps.println("HTTP/1.1 200 OK");

                //두번째 줄 헤더들
                ps.println("Content-Type: text/html; charset=UTF-8");
                ps.println("Content-Length: " + length); //바이트배열의 길이
                //빈줄
                ps.println();
                //응답본문
                ps.println(body);

                ps.flush();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("서버 종료");
    }
}

19.3 thread

서버는 이 요청을 항상 기다리기 위해서 반복하고 있다.
또한 여러 요청을 동시에 처리하기 위해서스레드를 이용해야한다.

톰캣에서 위 일들이 일어나는 것이다.
공부를 하면서 서버도 브라우저도 나로 돌아갈 것이다.

우리는 html만 적어서 보내고 싶은데 소켓 열고 닫고 등 부가적인 것을 하기 힘들다.
그래서 서버 프로그램을 미리 만들어 놓았다. 그것이 톰캣이다.
근데 그 html이 뭔가? 바로 JSP이다.

톰캣을 사용하면 우리는 html에만 집중할 수 있게 되는 것이다.

12. JAVA BASE모듈

12.11 리플렉션

Reflection 반사라는 뜻을 가지고 있는데 클래스에 관한 정보를 리턴한다.

클래스 정보를 가진 객체 생성해야하는데 세가지 방법이 있다.

1.클래스의 .class 속성으로 얻기
Class<String> class1 = String.class;
2.forName static method로 얻기
Class<String> class2 = (Class<String>) Class.forName("java.lang.String");
3.객체로부터얻기
String s1 = "java";
Class<String> class3 = (Class<String>) s1.getClass();

이 얻은거로 무엇을 할 수 있느냐
클래스의 필드 생성자 메소드가 무엇인지 무엇을 상속받고있는지 등등을 알 수 있다.

getName() : 이름(full name) 얻기
getSimpleName() : 간단한 이름 얻기
getPackageName() : 패키지 얻기
getConstructors() : 생성자 배열얻기
getFields() : 필드 배열얻기
getMethods() : 메소드 배열얻기
등등이 있다.

public class C02Reflection {
    public static void main(String[] args) throws Exception {
        Class<String> class1 = String.class;

        // 이름(full name) 얻기
        System.out.println(class1.getName());

        //이름(simple)
        System.out.println(class1.getSimpleName());

        //패키지
        System.out.println(class1.getPackageName());

        //생성자
        Constructor[] constructors = class1.getConstructors();

        //필드
        Field[] fields = class1.getFields();

        //메소드
        Method[] methods = class1.getMethods();
    }
}

정보를 얻어내서 필드에 관한 메소드 메소드의 메소드 등등으로 알아 낼 수 있다.
클래스 타입의 인스턴스로부터 정보를 얻어서 사용하는 것이다.

public class ReflectionExamle {
    public static void main(String[] args) {
        // how1
        Class clazz = Car.class;

        System.out.println("[생성자 정보]");
        Constructor[] constructors = clazz.getDeclaredConstructors();
        for(Constructor constructor : constructors) {
            System.out.print(constructor.getName() + "(");
            Class[] parameters = constructor.getParameterTypes();
            printParameters(parameters);
            System.out.println(")");
            }
        System.out.println();

        System.out.println("[필드 정보]");
        Field[] fields = clazz.getDeclaredFields();
        for(Field field : fields) {
            System.out.println(field.getType().getName() + " " + field.getName());
        }
        System.out.println();

        System.out.println("[메소드 정보]");
        Method[] methods = clazz.getDeclaredMethods();
        for(Method method : methods) {
            System.out.print(method.getName() + "(");
            Class[] parameters = method.getParameterTypes();
            printParameters(parameters);
            System.out.println(")");
        }
    }

    private static void printParameters(Class[] parameters) {
        for(int i=0; i<parameters.length; i++) {
            System.out.print(parameters[i].getName());
            if(i<(parameters.length-1)) {
                System.out.print(",");
            }
        }
    }
}

12.12 어노테이션

직접 작성할일은 없고 이미 만들어진 것을 사용하는 일이 많다.
어노테이션은 주석 comment의 의미를 가지고 있다.
어노테이션을 달아놓으면 어떤일을 하게 된다.
스프링에서 많이 사용된다.

12.12.1 어노테이션 생성

@interface로 어노테이션을 만들고
필드 생성자 지역변수 메소드 파라미터 등등에 붙일 수있다.
붙어있는 거에 따라 컴파일러나 특정기능을 처리할때 정보를 전달한다.

@MyAnnotation01
class MyClass {
    @MyAnnotation01
    String filed;

    @MyAnnotation01
    public MyClass() {
    }

    @MyAnnotation01
    void method1() {
        @MyAnnotation01
        int var;
    }

    void method2(@MyAnnotation01 int param) {
    }
}

@interface MyAnnotation01 {
}

12.12.2 어노테이션 유지정책

어노테이션은 3가지 방식으로 적용된다.
컴파일 할때 적용
로딩된 이후 적용
실행할때 적용
어노테이션에 Retention 어노테이션을 달아서 유지 정책을 결정할 수 있다.

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation02 {
}

12.12.3 어노테이션 적용대상

어노테이션에 Target 어노테이션을 달아서 적용할 대상을 정할 수 있다.
여러군데 적용하고 싶다면 {}배열에 넣어서 작성해주면 된다.

@MyAnnotation04
class MyClass04 {
    @MyAnnotation04
    String filed;

    @MyAnnotation04
    public MyClass04() {
    } 

    @MyAnnotation04
    public void method1() {
    }
}

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR , ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation04 {
}

12.12.4 어노테이션 속성

어노테이션에 속성(attribute, element)을 부여할 수 있다.
부가적인 정보가 달려있는지 등등으로 또 다른일을 할 수 있다.
속성 default 으로 기본값을 적용할 수도 있다.

class MyClass06{
    @MyAnnotation06
    String field1;

    @MyAnnotation06(myAttr = 10)
    int field2;

    @MyAnnotation06(myAttr = 20)
    boolean field3;
}

@interface MyAnnotation06 {
    int myAttr() default 0;
}

12.12.5 특별한 속성

value()라는 속성이 있다면 속성부여시 생략하고 적을 수 있다.
단 한번에 여러 속성에 값을 넣어주면 value=을 해줘야한다.

class MyClass08 {
    @MyAnnotation08
    int f1;

    @MyAnnotation08(100) // == @MyAnnotation08(value = 100)
    int f2;

    @MyAnnotation08(value = 100, name = "lee")
    int f3;
}

@interface MyAnnotation08 {
    int value() default 0;
    String name() default "kim";
    int age() default 0;
}

12.12.6 어노테이션속성-2

속성이 여러개의 값을 가지면 배열로 받을 수 있다.
배열로 넣는 값이 하나면 중괄호를 생략할 수 있다.

class MyClass09 {
    @MyAnnotation09(val1 = "hi", val2 = { "a", "b" })
    int f1;
    @MyAnnotation09(val1 = "hi", val2 = { "a" })
    int f2;
    @MyAnnotation09(val1 = "hi", val2 = "a")
    int f3;
}

@interface MyAnnotation09 {
    String val1();
    String[] val2();
}

jsp

jsp 시작
톰캣 다운로드
톰캣 9버전 사용예정임.
https://tomcat.apache.org/download-90.cgi
다운로드

이클립스 marketplace
jsp검색
Eclipse Enterpirse java and web dev tools 3.28다운 받아야한다.

윈도우-속성 html jsp css utf-8로 변경해주기

우리가 이전에 java코드로 작성한 서버소켓 등등의 설정을 톰캣이 해주는 것이다.

왜 하필 JSP여야하는가?
VIEW를 JSP로 만들어야하는가? 결론은 아니다.
JSP가 점점 내려가고 있는 추세이다.
우리는 목적이 취업이다. JSP가 아직은 많다.
요새 리액트가 뜨고 있다. 과도기에 잇다.
JSP는 언젠간 안쓰인다는 확실하다 하지만 아직은 알 수없다.

1. FISRT-JSP

http://localhost:8080/JSP2023/index.jsp
요청받은 JSP를 받아오는 것이다.

이클립스에 emmet plugin을 다운받아보자.
구글 emmet eclipse검색 깃허브
http://download.emmet.io/eclipse/updates/

help-install new software

2. JSP페이지의 구성요소

디렉티브 - 3장
스크립트 릿 - 3장 SEC04
표현 언어 - 11장 ->중요
표준액션태그 - 7~8장
기본객체 - 3장 5장
정적데이터(HTML)
커스텀태그 - 16장
표준태그라이브러리 12장 ->중요

3. 스크립트 릿

JAVA코드를 작성할 수 있다.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h1>스트립트릿(scriptlet)</h1>
    <h2>책 65쪽</h2>

    <p>자바 코드 작성 가능</p>

    <%
    String a = "hello jsp";
    out.println("<h1>");
    out.println(a);
    out.println("</h1>");
    %>
</body>
</html>

이 html코드가 톰캣으로 어떻게 실행되는지을 알아보자.
톰캣이 자바코드로 바꾸고 이것을 컴파일하고 톰캣이 컴파일한것을 브라우저가 보여주는 것이다.

workspace -> .metadata -> .plugins -> org.eclipse.wst.server.core
-> tmp1 -> work -> Catalina ->localhost ->JSP2023

service 메소드를 봐야한다.
기본객체 request와 response를 파라미터로 받는다.
지역변수 6개도 선언되어 있다. 프린트하는 out 세션관련 session등등

톰캣이 제공하는 outputStream에 우리가 작성한 html코드가 나오게 된다.
우리가 직접 작성했으면 하나하나 작성해야햇었다.
작성한 스크립트 릿은 자바코드 그대로 메소드에 들어가게 된다.

2023.03.27 후기

자바가 마무리 되었다. 혼자 햇을때 보다 많은 것을 넘겼고 혼자했을때보다 새로운 것도 배우긴 했지만 가볍게 배워서 걱정이 된다.
네트워크 파트 이해를 못햇엇는데 왜 배우는 지는 톰캣이 이런일들을 대신해준다는 것을 이해하기 위해 배운다는 점을 깨달았다.
emmet다운받아 html을 작성하는 것이 매우 편해졌다.
vscode의 기본 기능이 아니라는것을 기억해냈다.