<JSP (Jasper)>


-html을 java servlet을 사용해 동적 페이지로 편하게 출력해 줄 수 있게 해주는 프로그램
(html 속에 java servlet이 직관적으로 보기 편하게 공존하는 뭐 그런 느낌이다)

-요청할 때마다 달라진 게 있다면 jasper는 다시 만들어주기 때문에 서버를 재시작할 필요가 없다.
(servlet 순수 개발은 재컴파일 과정이 필요하기에 ide 개발을 하더라도 서버를 재시작해줄 필요가 있었다)

-톰캣 프로젝트 명이 Catalina라 경로 폴더에 해당 프로젝트 명이 있다
(톰캣설치폴더\work\Catalina\localhost\ROOT\org\apache\jsp)

-.jsp 확장자를 사용하여 작성하며 파일명_jsp.java (컴파일시 파일명_jsp.class 추가) 로 생성된다
(.jsp 파일명 자체가 url로 맵핑된다)

-html 확장자를 jsp로 만들어 위 파일을 실제로 열어보면 무수한 out.write로 처리된 html 구문을 볼 수 있다
(옛날엔 실제로 일일히 out.write를 쳐줬다고 한다...ㅋ)



<Jasper를 이용한 코드 작성>


출력 코드(html,css)
-그대로 작성

<%! java code %>
-jsp 멤버함수, 멤버변수가 있는 클레스에 java code 사용
-jsp 메소드 밖, jsp 서비스 메소드가 속한 클래스에서의 코드 사용(일반 클래스에서 하는 작업이 모두 가능)

<% java code %> 
-jspService 메소드 내에서 사용하는 java code
-지역변수 알고리즘이 있는 함수 속이라 멤버변수 정의, 함수정의 등이 불가능

<%= 출력변수 %>
-<% out.print(출력변수) %>와 같은 의미

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
-page 지시자
-jsp에서는 인코딩 설정시 출력코드가 입력 지시보다 먼저 이루어지는 경우가 있기에 illegalStateException을 내뱉는다.
-그래서 page 인코딩 등의 설정에 우선 순위를 주기 위해 사용한다



<JSP 내장 객체>


-jasper에는 보이지 않을 뿐 jsp servlet와 내부 service 메소드에는 미리 정의해놓은 변수와 함수들이 존재한다.
-이 내장 객체들과 동일한 이름을 사용하면 오류가 발생한다.


<Servlet, JSP 내장 객체 환기>

 

Request

                                          메서드                                              설명
getParameterNames() 사용자가 전달한 키들을 Enumration 객체로 반환
getParameter(name) 사용자가 전달한 name과 일치하는 값을 반환
getParameterValues(name) 사용자가 전달한 name과 일치하는 값을 배열형식으로 반환
getCookies() 클라이언트에서 전달한 쿠키를 배열 형식으로 반환
getMethod() 현재 요청방식이 GET인지 POST인지를 문자열로 반환
getSession() 현재 세션 객체를 반환
getRemoteaddr() 클라이언트의 IP 주소를 반환
getProtocol() 현재 서버의 프로토콜을 문자열로 반환
setCharacterEncoding() 현재 JSP로 전달되는 내용을 지정한 문자셋으로 변환해준다.
getHeaderNames() 현재 요청이 가지는 헤더의 이름들을 반환
getHeaders(name) 현재 요청한 헤더에서 지정한 이름의 모든 값들을 반환
getQueryString() 현재 요청에 포함된 쿼리문자열을 반환
내장 객체 request : HttpServletRequest

 

Response

                                          메서드                                            설명
setContentType(type) 컨텐트 형식을 설정("test/html; charset=UTF-8")
setHeader(name, value) 클라이언트에게 헤더로 전달할 값을 설정
setDateHeader(name, date) 클라이언트에게 헤더로 전달할 날짜를 설정
sendError(status, msg) 클라이언트에게 에러코드와 메시지를 전달
sendRedirect(url) 클라이언트 요청을 다른 페이지로 전달
addCookie(cookie) 클라이언트에게 전달할 쿠키를 설정
encodeURL(url) URL로 유효하지 않은 문자를 인코딩
setStatus(sc) 상태 코드를 설정
내장 객체 response : HttpServletResponse

 

Out

                                          메서드                                             설명
getBufferSize() output buffer의 크기를 byte로 알려준다
getRemaining() 남아있는 버퍼의 크기중 사용가능한 비율을 알려준다
cleaBuffer() 버퍼에 있는 콘텐츠를 모두 지운다
flush() 버퍼를 비우고 output stream도 비운다
close() output stream을 닫고 버퍼를 비운다
println(content) content의 내용을 newline과 함께 출력한다
print(content) content의 내용을 출력한다
내장 객체 out : javax.servlet.jsp.JspWriter

 

Session

                                         메서드                                             설명
getID() 각 접속에 대한 세션 고유의 id를 문자열 형태로 반환
getCreationTime() 세션이 생성된 시간을 밀리세컨드 값으로 반환
getLastAccessedTime() 현재 세션으로 마지막 작업한 시간을 밀리세컨드 값으로 반환
getMaxInactiveInterval() 세션 유지 시간을 초로 반환
setMaxInactiveInterval(t) 세션 유효시간을 t에 설정된 초 값으로 설정
invalidate() 현재 세션을 종료. 세션과 관련한 값을 모두 지움
getAttribute(attr) 문자열 attr로 설정된 세션값을 object 형태로 반환
setAttribute(name,attr) 문자열 name으로 attr을 설정
removeAttribute(name) 세션에 설정한 속성 값을 삭제
내장 객체 session : javax.servlet.http.HttpSession

 

Application

                                          메서드                                             설명
setAttribute(name, value) application 범위의 값 설정
getAttribute(name) application 범위 값 얻기
getRealPath(path) 실제 물리 경로를 반환
getResource(path) path 경로의 리소스를 가리키는 URL을 반환
getServerInfo() 현재 요청 방식이 GET인지 POST인지를 문자열로 반환
getSession() 현재 세션 객체를 반환
getRemoteAddt() 클라이언트의 IP 주소를 반환
getProtocol() 현재 서버의 프로토콜을 문자열로 반환
setCharacterEncoding() 현재 JSP로 전달되는 내용을 지정한 문자셋으로 변환해준다
내장 객체 application : javax.servlet.ServletContext

 

 

'Development > Java' 카테고리의 다른 글

JSP EL(Expression Language) #6  (0) 2022.08.14
JSP MVC model #5  (0) 2022.08.14
Servlet (service, doGet, doPost) #3  (0) 2022.08.13
Servlet (Application, Session, Cookie) #2  (0) 2022.08.12
Servlet #1  (0) 2022.08.11



서버에서 페이지 전환 Redirection
response.sendRedirect("calc2");


쿠키 삭제하기
if(operator != null && operator.equals("C"))
expCookie.setMaxAge(0);


Java에서 자바스크립트 엔진 사용하여 구문 분석하기
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
try {
exp = String.valueOf(engine.eval(exp));
} catch (ScriptException e) {
e.printStackTrace();
}
-jdk11 이후부터는 nashorn 엔진은 지원되지 않는다. 
-자바에서 자바스크립트를 사용하고 싶다면 GraalVM 엔진을 사용하자.

 

엔진 변경 방법
1. 프로젝트 우클릭 -> configure -> convert to maven project 클릭
2. 생성된 pom.xml 파일에 
  <dependencies>
  <dependency>
    <groupId>org.graalvm.js</groupId>
    <artifactId>js</artifactId>
    <version>19.2.0.1</version>
</dependency>  
<dependency>
    <groupId>org.graalvm.js</groupId>
    <artifactId>js-scriptengine</artifactId>
    <version>19.2.0.1</version>
</dependency>
  </dependencies>
삽입 ( <build> 바로 위 )
ScriptEngine engine = new ScriptEngineManager().getEngineByName("graal.js"); 

graal.js 삽입



                         service                            doGet                             doPost


HttpServlet을 상속받은 서블렛 클래스는 클라이언트에서 요청받은 메소드 방식에 따라 doGet, doPost 등 기타 다른 서비스 메소드를 자동으로 호출한다.
이때 해당 서비스 메소드가 오버라이드 되어있지 않으면 405 에러를 출력한다.
(URL을 찾을 수 없으면 404 에러)

동일한 서블렛 조각에서 GET 방식과 POST 방식을 한꺼번에 처리하는 방식을 원하면 service 메소드를 오버라이드 해서 super.service(req, resp);는 지우고 조건문 if(request.getMethod().equals("GET")){}등을 통해 원하는 서비스를 오버라이드 하도록 하고.

GET과 POST 요청을 따로 처리하길 원한다면 service 메소드를 오버라이드 하지 않고 doGet, doPost 메소드를 오버라이드 하여 사용한다.

또는 service 메소드 오버라이드에 super.service(req, resp); 호출을 통해 선택적으로 메소드 오버로드처럼 사용할 수도 있긴 하다.


Servlet 계산기 (JSP의 필요성)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import java.io.IOException;
import java.io.PrintWriter;
 
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
@WebServlet("/calculator")
public class Calculator extends HttpServlet {
    
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        Cookie[] cookies = request.getCookies();
        
        String exp = "0";
        if(cookies != null)
            for(Cookie c : cookies)
                if(c.getName().equals("exp")) {
                    exp = c.getValue();
                    break;
                }
        
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=UTF-8");
        PrintWriter out = response.getWriter();
        
        out.write("<!DOCTYPE html>");
        out.write("<html>");
        out.write("<head>");
        out.write("<meta charset=\"UTF-8\">");
        out.write("<title>Insert title here</title>");
        out.write("<style>");
        out.write("input{");
        out.write("    width:50px;");
        out.write("    height:50px;");
        out.write("}");
        out.write(".output{");
        out.write("    height:50px;");
        out.write("    background: #e9e9e9;");
        out.write("    font-size:24px;");
        out.write("    font-weight: bold;");
        out.write("    text-align: right;");
        out.write("    padding:0px 5px;");
        out.write("}");
        out.write("</style>");
        out.write("</head>");
        out.write("<body>");
        out.write("    <form method=\"post\">");
        // POST를 폼에서 요청하고 있기 때문에 input 버튼을 누르면 doPost 메소드를 호출
        // 자기 자신의 페이지를 요청하기에 action 속성은 필요없다
        out.write("        <table>");
        out.write("            <tr>");
        out.printf("                <td class=\"output\" colspan=\"4\">%s</td>", exp);
        out.write("            </tr>");
        out.write("            <tr>");
        out.write("                <td><input type=\"submit\" name=\"operator\" value=\"CE\" /></td>");
        out.write("                <td><input type=\"submit\" name=\"operator\" value=\"C\" /></td>");
        out.write("                <td><input type=\"submit\" name=\"operator\" value=\"BS\" /></td>");
        out.write("                <td><input type=\"submit\" name=\"operator\" value=\"/\" /></td>");
        out.write("            </tr>");
        out.write("            <tr>");
        out.write("                <td><input type=\"submit\" name=\"value\" value=\"7\" /></td>");
        out.write("                <td><input type=\"submit\" name=\"value\" value=\"8\" /></td>");
        out.write("                <td><input type=\"submit\" name=\"value\" value=\"9\" /></td>");
        out.write("                <td><input type=\"submit\" name=\"operator\" value=\"*\" /></td>");
        out.write("            </tr>");
        out.write("            <tr>");
        out.write("                <td><input type=\"submit\" name=\"value\" value=\"4\" /></td>");
        out.write("                <td><input type=\"submit\" name=\"value\" value=\"5\" /></td>");
        out.write("                <td><input type=\"submit\" name=\"value\" value=\"6\" /></td>");
        out.write("                <td><input type=\"submit\" name=\"operator\" value=\"-\" /></td>");
        out.write("            </tr>");
        out.write("            <tr>");
        out.write("                <td><input type=\"submit\" name=\"value\" value=\"1\" /></td>");
        out.write("                <td><input type=\"submit\" name=\"value\" value=\"2\" /></td>");
        out.write("                <td><input type=\"submit\" name=\"value\" value=\"3\" /></td>");
        out.write("                <td><input type=\"submit\" name=\"operator\" value=\"+\" /></td>");
        out.write("            </tr>");
        out.write("            <tr>");
        out.write("                <td></td>");
        out.write("                <td><input type=\"submit\" name=\"value\" value=\"0\" /></td>");
        out.write("                <td><input type=\"submit\" name=\"dot\" value=\".\" /></td>");
        out.write("                <td><input type=\"submit\" name=\"operator\" value=\"=\" /></td>");
        out.write("            </tr>");
        out.write("        </table>");
        out.write("    </form>");
        out.write("</body>");
        out.write("</html>");
    
    }
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 
        Cookie[] cookies = request.getCookies();
 
        String value = request.getParameter("value");
        String operator = request.getParameter("operator");
        String dot = request.getParameter("dot");
        
        String exp = "";
        if(cookies != null)
            for(Cookie c : cookies)
                if(c.getName().equals("exp")) {
                    exp = c.getValue();
                    break;
                }
        
        if(operator != null && operator.equals("=")) {
            ScriptEngine engine = new ScriptEngineManager().getEngineByName("graal.js");
            try {
                exp = String.valueOf(engine.eval(exp));
            } catch (ScriptException e) {
                e.printStackTrace();
            }
        }
        else if(operator != null && operator.equals("C")) {
            exp = "";
        }
        else {
            exp += (value == null)?"":value;
            exp += (operator == null)?"":operator;
            exp += (dot == null)?"":dot;
        }
        
        Cookie expCookie = new Cookie("exp", exp);
        if(operator != null && operator.equals("C"))
            expCookie.setMaxAge(0);
        
        expCookie.setPath("/calculator");
        // 다른 url에는 쿠키가 전달되지 않음
        response.addCookie(expCookie);
        response.sendRedirect("calculator");
        //response.sendRedirect("./"); 자기자신 호출
        //sendRedirect 함수 자체가 GET을 요청하기 때문에 doGet 메소드를 호출
        
    }
 
}
 
cs

 

out.write 노가다를 대신해 줄 JSP가 필요하게 됨 

'Development > Java' 카테고리의 다른 글

JSP MVC model #5  (0) 2022.08.14
Servlet & JSP (method) #4  (0) 2022.08.13
Servlet (Application, Session, Cookie) #2  (0) 2022.08.12
Servlet #1  (0) 2022.08.11
Tomcat  (0) 2022.08.11

Servlet



<Eclipse IDE EE 버전으로 웹개발 환경 구축>
(WAS로는 tomcat 9 버전 사용)

Dynamic Web project로 프로젝트 생성
Target runtime에 사용할 tomcat 등록
Java Resources\src -여기에 java 패키지와 소스코드 작성
src\main\webapp  -여기에 html 작성
(버전에 따라 폴더 이름 또는 구성은 달라질 수 있다)

가동되는 브라우저를 변경하고 싶다면 window > web browser 변경
프로젝트 명이 url에 드러나지 않게 하려면 file > Properties > web project settings > Context root를 / 로 변경

 

웹 브라우저에서 실행되는 실제 파일은 위와 같은 이클립스 개발 디렉토리나 톰캣 폴더가 아닌
배포시 workspace\.metadata\.plugins\org.eclipse.wst.server.core 에서 복제되어 생성된다.



<Annotaion을 이용한 URL 맵핑>


@WebServlet("/hello")
public class Nana extends HttpServlet {}

-위처럼 어노테이션을 클래스 위에 붙여주면 web.xml 등 외부파일에서 설정할 필요없이 적용된다.
(Servlet 어노테이션 임포트 해야함)
-어노테이션을 사용해 url을 맵핑할 시 web.xml의 metadata-complete은 false로 바꿔주어야 한다.
(true로 되어 있으면 web.xml 의 설정이 우선된다)



<한글과 콘텐츠 형식>


브라우저에 response 하는 콘텐츠의 형식을 알려주지 않을 경우 브라우저는 자의적으로 해석한다.

ex) 익스플로러는 response한 문자열의 "<br>"을 html로 해석해 한줄을 내리지만 크롬은 text로 해석해 그대로 출력한다.
(tomcat 기본 인코딩은 ISO-8859-1)


=서버에서 한글을 지원하지 않는 문자코드로 인코딩 될 경우= 
(ex) ISO-8859-1 문자코드
한국어 출력 : ??:???????

해결법)
response.setCharacterEncoding("UTF-8");


=서버에서는 한국어를 지원하는 UTF-8로 인코딩해서 보냈지만 브라우저가 다른 코드로 잘못 해석한 경우=
(ex) EUC_KR 문자코드
한국어 출력 : 뒹귥◆땗뺎◆

해결법)
response.setContentType("text/html; charset=UTF-8");


이클립스에서 소스 파일 생성시 인코딩 방식 미리 설정하기
window > preference > web > files... > encoding 변경



<GET 요청과 쿼리스트링>


=쿼리스트링에 따른 request.getParameter("cnt");  반환 값=

http://localhost/hello?cnt=3   =GET=>

hello?cnt=3 =>   "3"
hello?cnt= =>   ""
hello? =>   null
hello =>   null

테스트용 html)
<body>
환영합니다.<br >
<a href="hi">인사하기</a><br >
<a href="hi?cnt=3">인사하기</a><br >
</body>



<POST 요청>


<form action="notice-reg" method = "post">
-url에 쿼리가 표시되지 않고 요청바디를 통해 요청됨

post 요청 시 title=abc&content=abcdefg 이러한 형태로 전달된다

=한글 포스트 시 깨짐 문제=
한국어 출력 : dsad ì•ˆë…•하세요

해결법)
request.setCharacterEncoding("UTF-8");

(tocat\conf\server.xml 외부 설정 파일에서 기본 인코딩 설정을 UTF-8로 가능하지만 권장되지 않는다)
(톰캣으로 운영하는 모든 서버가 UTF-8 이 되기 때문)



<Servlet Filter>


서블릿 request, respond가 실행되기 전 먼저 선행되어
인코딩 설정, 유효성 검사, 다른 url로 우회시키는 등의 일을 시킬 수 있는 필터 인터페이스.

public class CharacterEncodingFilter implements Filter {
@Override
  public void doFilter(ServletRequest request
    , ServletResponse response
    , FilterChain chain)
    throws IOException, ServletException {
      request.setCharacterEncoding("UTF-8");
      chain.doFilter(request, response);
    }
}

FilterChain 객체
필터가 언제 실행될 지, 어떻게 실행될지 흐름을 제어하는 용도
chain.doFilter(request, response);
다음 url로 진행시킨다



=Annotaion을 이용한 Filter URL 맵핑=

import javax.servlet.annotation.WebFilter;

@WebFilter("/*")
public class CharacterEncodingFilter implements Filter {}



=web.xml 설정을 통한 url맵핑=

  <filter>
   <filter-name>characterEncodingFilter</filter-name>
   <filter-class>패키지.CharacterEncodingFilter</filter-class>
  </filter>
  <filter-mapping>
   <filter-name>characterEncodingFilter</filter-name>
   <url-pattern>/*</url-pattern>
  </filter-mapping>

->   /* 모든 url에 대해 필터를 적용시킬 경우

 

 

 

<입력 데이터 배열로 받기>

[html]

<body>
<form action="add2" method="post">
<div>
<input type="text" name="num" />
<input type="text" name="num" />
<input type="text" name="num" />
<input type="text" name="num" />
</div>
<div>
<input type="submit" value="덧셈" />
</div>
<div>
결과 : 0
</div>
</form>
</body>


[servlet]
String[] num_ = request.getParameterValues("num");
int result = 0;
for (int i = 0; i < num_.length; i++) {
  int num = Integer.parseInt(num_[i]);
  result += num;
}
response.getWriter().printf("result is : %d\n", result);



'Development > Java' 카테고리의 다른 글

Servlet (service, doGet, doPost) #3  (0) 2022.08.13
Servlet (Application, Session, Cookie) #2  (0) 2022.08.12
Tomcat  (0) 2022.08.11
JDBC  (0) 2022.08.07
Java Thread & Sync  (0) 2022.08.04

+ Recent posts