副手


キム・ヨンハンのスプリングMVC 1編-バックエンドWeb開発のキーテクノロジーを見て学習内容をまとめました!
Webとlombokを追加してプロジェクトを作成し、メインクラスに次の項目を追加するだけです.
@ServletComponentScan
@サーブレットComponentScanは、クラスパッケージを含むサブパッケージ内のすべてのテンプレートを検索し、テンプレートとして登録します.
(おしゃべりですが@ComponentScanはAnnotationで、そのクラスのパッケージを含むサブシステムのすべてのbeanを検索し、Contextにbeanを登録することができます...ほほほ復習)

サーブレットの作成


サブアイテムにbasicというパッケージを作成し、HelloServiceというクラスを作成します.
@WebServlet(name = "helloservlet",urlPatterns = "/hello")
public class HelloServlet extends HttpServlet {
    
}
HttpServiceletを継承し、@WebServicelet(name="helloservlet",urlPatterns="/hello")のフレーズを追加すると、ブレードサーバの作成が完了します.
nameは、我々が定義したサーブレットの任意の名前であり、リクエスト/helloの場合、このサーブレットを実行できます.
@Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.service(req, resp);
    }
すなわち、このサービスメソッドを内部に追加すると、メソッドが呼び出されると呼び出されます.
HttpServertRequest reqはクライアント要求のオブジェクトであり、HttpServertResponse応答は応答するオブジェクトである.
http://localhost:8080/hello?username=yoonアドレスがあるとき?username=yoonはクエリーパラメータです.
サーブレットの特徴は、クエリーパラメータを簡単に使用できることです.
String username=reqは、サービスメソッドに使用されます.getParameter("username");入力し、上のアドレスを入力します.ユーザー名にyoonが含まれています.
今度返事しましょう.
resp.setContentType("text/plain");//text타입의 응답을 보낸다
resp.setCharacterEncoding("utf-8");//utf-8로 인코딩해서
resp.getWriter().write("hello "+username);//응답 보낼 값

このように送信された応答であることが確認できます.
開発時にリクエストをより詳細に表示したい場合->アプリケーション.ツールバーの
logging.level.org.apache.coyote.http11=debug 추가

HttpServeretRequest-概要


HttpServiceletRequestロール
HTTPリクエストメッセージを開発者に直接割り当てることができますが、これは非常に不便です.
サーブレットは、開発者がHTTPリクエストメッセージを容易に使用できるように、HTTPリクエストメッセージを開発者の一部としてグループ化する.
次に、結果をHttpServertRequestオブジェクトに含めます.
HttpServiceletRequestを使用すると、次のHTTPリクエストメッセージを簡単に検索できます.

HTTPリクエストメッセージ


POST/save HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
username=kim&age=20
START LINE
HTTPメソッド
URL
クエリー文字列
シナリオ
見出し
クエリータイトル
本体
クエリーformパラメータフォーマット
メッセージbodyデータを直接表示
HttpServiceletRequestオブジェクトには、追加の機能も多数用意されています.

一時記憶機能


一時リポジトリ機能、開始から終了までのHTTPリクエスト
保存:request.setAttribute(name, value)
クエリー:request.getAttribute(name)

セッション管理機能


ログインを保持します.
request.getSession(create: true)
HttpServeretRequest、HttpServeretResponseを使用する場合、最も重要なのは、これらのオブジェクトがHTTPリクエストメッセージ、HTTPレスポンスメッセージを容易に使用するのに役立つオブジェクトであることです.
したがって,この機能を深く理解するには,HTTP specが提供する要求,応答メッセージそのものを理解する必要がある.

HttpServeretRequest-基本的な使い方


RequestHeaderServiceという名前のサーブレットを作成します.
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();
    }
ヘッダに関する値は以下の方法で知ることができる.
private void printHeaders(HttpServletRequest request) {
        System.out.println("--- Headers - start ---");

        request.getHeaderNames().asIterator()
                .forEachRemaining(headerName -> System.out.println(headerName + ": " + request.getHeader(headerName)));
                        System.out.println("--- Headers - end ---");
        System.out.println();
    }

HTTP要求データ-GETクエリーパラメータ


HTTP要求メッセージを通じてクライアントからサーバGET-クエリーパラメータにデータを転送する方法について
主に検索、フィルタリング、ページングなどの面でよく使われる方法です.
メッセージボディがない場合は、URLのクエリーパラメータを使用してデータを渡すことができます.
クエリー・パラメータはURLに次のように表示されます.最初から送信できます.
追加パラメータは&で区切ります.
ex) http://localhost:8080/request-param?username=hello&age=20

クエリー・パラメータのクエリー・メソッド

String username = request.getParameter("username"); //단일 파라미터 조회 username이라는 파라미터를 조회
Enumeration<String> parameterNames = request.getParameterNames(); //파라미터 이름들 모두 조회
Map<String, String[]> parameterMap = request.getParameterMap(); //파라미터를 Map으로 조회
String[] usernames = request.getParameterValues("username"); //복수 파라미터 조회 username파라미터의 값들이 여러개일 때
username=hello&username=kimのようにパラメータ名は1つしかありませんが、値が繰り返されるとどうなりますか?
request.getParameter()は、1つのパラメータ名に1つの値しかない場合に使用する必要があります.
今のように繰り返す時requestgetParameterValue()を使用する必要があります.
参考としてこのように繰り返す場合はrequestgetParameter()リクエストを使用します.getParameterValue()の最初の値のみが返されます.

HTTP要求データ-POST HTMLフォーム


HTTPリクエストメッセージを介してクライアントからサーバPOST HTML Formにデータを転送する方法について

主に会員加入、商品注文などで使われる方式です.
メッセージ・ボディにはクエリー・セパレータ形式(username=hello&age=20)で渡されるためcontent-type(アプリケーション/x-www-form-urlencoded)がある.
すなわち、content-typeはアプリケーション/x-www-form-urlcodedであるため、メッセージボディはクエリーパラメータタイプ(username=hello&age=20)である.
クエリーパラメータのクエリー方法は、POST HTML Formでも使用できます.

HTTP要求データ-HTTPメッセージ本文に直接データを入れて要求する


主にHTTP APIに用いられ、データはJSON、XML、TEXTである.
データフォーマットは主にJSONを使用します.(POST, PUT, PATCH)

APIメッセージマスター-単純テキスト


まず,最も簡単なテキストメッセージをHTTPメッセージ本体に転送し,次に読む.
InputStreamを使用して、HTTPメッセージ本体のデータを直接読み込むことができます.
ServletInputStream inputStream = request.getInputStream();
getInputStreamメソッドを使用すると、メッセージ本体のコンテンツをバイトコードで受信できます.
String messageBody = StreamUtils.copyToString(inputStream,
StandardCharsets.UTF_8);
String typeに変えて使用します.
この場合、どのようなコードを入力する必要がありますか(ここではStandardCharsets.UTF 8).

APIメッセージ主体-JSON


今回はHTTP APIでよく使われるJSON形式でデータを渡してみましょう.
JSON形式でパーティション化するオブジェクトを作成する必要があります.
@Getter @Setter
public class HelloData {
    private String username;
    private int age;
}
postmanを使用してjsonメッセージを送信します.
JSON結果をスライス可能なJavaオブジェクトに変換するには、JacksonやGsonなどのJSON変換ライブラリを追加して使用する必要があります.
Spring BootとしてSpring MVCを選択した場合、デフォルトではJacksonライブラリ(ObjectMapper)が同時に提供されます.
private ObjectMapper objectMapper = new ObjectMapper();

@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	HelloData helloData = objectMapper.readValue(messageBody, HelloData.class);
        System.out.println("helloData.username = " + helloData.getUsername());
        System.out.println("helloData.age = " + helloData.getAge());
}

HttpServeretResponse-基本的な使い方


HttpServeretResponseはHTTP応答メッセージの生成を担当する.
HTTP応答コードの指定
タイトルの作成
ボディの作成
便宜を図る
コンテンツ-タイプ、Cookie、Redirect
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //[status-line]
        response.setStatus(HttpServletResponse.SC_OK); //200

        //[response-headers]
        response.setHeader("Content-Type", "text/plain;charset=utf-8");
        response.setHeader("Cache-Control", "no-cache, no-store, mustrevalidate");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("my-header","hello");

        //[Header 편의 메서드]
        content(response);
        cookie(response);
        redirect(response);

        //[message body]
        PrintWriter writer = response.getWriter();
        writer.println("ok")
}
private void content(HttpServletResponse response) {
        //Content-Type: text/plain;charset=utf-8
        //Content-Length: 2
        //response.setHeader("Content-Type", "text/plain;charset=utf-8");
        response.setContentType("text/plain");
        response.setCharacterEncoding("utf-8");
        //response.setContentLength(2); //(생략시 자동 생성)
}
private void cookie(HttpServletResponse response) {
        //Set-Cookie: myCookie=good; Max-Age=600;
        //response.setHeader("Set-Cookie", "myCookie=good; Max-Age=600");
        Cookie cookie = new Cookie("myCookie", "good");
        cookie.setMaxAge(600); //600초
        response.addCookie(cookie);
}
private void redirect(HttpServletResponse response) throws IOException {
        //Status Code 302
        //Location: /basic/hello-form.html
        //response.setStatus(HttpServletResponse.SC_FOUND); //302
        //response.setHeader("Location", "/basic/hello-form.html");
        response.sendRedirect("/basic/hello-form.html");
}

HTTP応答データ


HTTPレスポンスメッセージは、簡単なテキストレスポンス(前のWriter.println(「OK」;).HTML応答、HTTP API-MessageBody JSON応答あり.
簡単なテキスト応答に加えて、2つの問題があります.

HTMLレスポンス

@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//Content-Type: text/html;charset=utf-8
response.setContentType("text/html");
response.setCharacterEncoding("utf-8");
PrintWriter writer = response.getWriter();
writer.println("<html>");
writer.println("<body>");
writer.println(" <div>안녕?</div>");
writer.println("</body>");
writer.println("</html>");
}
writerにhtmlコードを追加して応答できます.
Javaコードなので動的に変更できます.
HTTP応答としてHTMLを返す場合はcontent-typeをtext/htmlとして指定する必要があります.

API JSON応答

private ObjectMapper objectMapper = new ObjectMapper();
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //Content-Type: application/json
        response.setHeader("content-type", "application/json");
        response.setCharacterEncoding("utf-8");
        HelloData data = new HelloData();
        data.setUsername("kim");
        data.setAge(20);
        //{"username":"kim","age":20}
        String result = objectMapper.writeValueAsString(data);
        response.getWriter().write(result);
}
HTTP応答としてJSONに戻る場合はcontent-typeをアプリケーション/jsonとして指定する必要があります.
Jacksonライブラリが提供するObjectMapper.オブジェクトをJSON文字に変更するには、writeValueAsString()を使用します.