Servlet : JSP 가 Servlet으로 바뀌어서 실행된다.
Servlet : 웹페이지 요청을 처리하기 위한 자바클래스
request를 전달받아서 response를 반환하는 형식이다.
HttpServlet 클래스를 상속받은 새로운클래스를 작성한다.
메서드는 오버라이딩으로 작성하기 때문에, 비교적 쉽게 작성이 가능하다.
마우스 오른쪽 클릭 > Source > Override /implement Methods
HttpServlet이나 Generic이나 Object에 대한 오버라이딩으로 함수를 생성할 수 있다.
요청이 get이나 post로 들어와도 jsp로처리할 수 있다.
노란색아이콘은 : 접근제한자가 protected
반환형이 없기때문에 매개변수로 들어와있는 request,response로 작업을 해주면 된다.
package ex01;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Ex01Servlet extends HttpServlet{
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest reguest , HttpServletResponse response) throws ServletException, IOException {
reguest.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
String name = reguest.getParameter("name");
String html = "";
html += "<!DOCTYPE html>\n";
html += "<html>";
html += " <head>";
html += " <meta charset=\"UTF-8\">";
html += " <title>Ex01Servlet</title>";
html += " </head>";
html += " <body>";
html += " <h1>Ex01Servlet</h1>";
html += " <hr>";
html += " <h3>Hello, %s</h3>\n";
html += " <form>\n";
html += " <p><input type=\"text\" name\" placeholder=\"이름\"></p>\n";
html += " <p><input type=\"submit\"></p>\n";
html += " </form>\n";
html += " </body>\n";
html += " </html>\n";
html = String.format(html, name != null ? name: "Guest");
PrintWriter out = response.getWriter();
out.write(html);
out.flush();
out.close();
}
}
프로젝트우클릭 JAVA EE tools 클릭 > Generate Deploy...클릭
WEB_INF에 생성된 web.xml을 확인하고
web.xml에 servlet 태그를 추가해준다.
서블릿클래스에서 지정한 이름으로 서블릿을 지정하고 , 작동할 주소를 연결시켜준다.
<servlet>
<servlet-name>ex01</servlet-name>
<servlet-class>ex01.Ex01Servlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ex01</servlet-name>
<url-pattern>/ex01</url-pattern>
</servlet-mapping>
servlet-mapping으로 생성시킬 주소와 jsp이름을 지정해준다.
Ex01Servlet실행
하지만 이처럼 문자열로 모든 태그를 쓰기에는 상당히 불편하고 시간 소모가 많다.
다른 방식으로 작성해보자.
Ex02Servlet.java
public class Ex02Servlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Ex02Servlet으로 요청이 들어왔음");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
String cpath = req.getContextPath();
String viewName = "ex02.jsp";
//요청은 서블릿이 받았지만. 응답은 jsp로 하겠다(포워딩)
RequestDispatcher rd = req.getRequestDispatcher(cpath + "/" + viewName);
rd.forward(req, resp);
}
Ex02Servlet을 실행시키면
포워딩해서 요청이 들어왔지만 ex02.jsp가 없기 때문에 페이지가 뜨지않는다.
webContent에서 ex02.jsp를 생성
<h1>ex02.jsp</h1>
<hr>
<h3>Hello, ${empty name ? 'Guest' : name}</h3>
<!-- 서블릿에서 request에 담아둔 값을 참조할 수 있다. -->
<form>
<p><input type="text" name="name" placeholder="이름"></p>
<p><input type="submit"></p>
</form>
예제 ex01과 ex02의 차이는
ex01에서는 일일이 html태그들을 문자열로 작성해서 요청과 응답을 전부처리해줬지만 ,
ex02에서는 요청을 서블릿으로 받아서 기능적인부분은 모두 자바서블릿에서 처리한다. 이후
포워딩으로 받게되는 jsp에서는 화면에 출력하는 html 요소들에 대해서만 작업을 해주면된다 .
이전에 쓰던 jsp에서는
클래스에서 만든 객체를 jsp파일에서 불러와서 함수를 선언해서 써줘야 하니
요청을 주게 되면 jsp파일 > 자바 클래스 내 함수 > 객체 리턴 > 다시 jsp파일을 통해
서버에 요청하면서 왔다갔다하는 번거로운 과정을 거쳐야했었다.
GET과 POST를분리해서 ex03예제를 만들어보자.
Ex03Servlet
요청방식을 get으로 하는 doGet을 오버라이딩
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
n1 = ran.nextInt(10)+1;
n2 = ran.nextInt(10)+1;
String msg = String.format("%d + %d = ", n1,n2);
System.out.println("msg :" + msg);
request.setAttribute("msg", msg);
RequestDispatcher rd = request.getRequestDispatcher(prefix + "ex03"+ suffix);
rd.forward(request, response);
}
attribute에 msg가 담김
WEB-INF/views폴더 내의 ex03.jsp로 포워딩
<h1>ex03.jsp</h1>
<hr>
<form method="POST">
<p>${msg }
<input type="number" name="answer" min="0" max="100" autofocus>
<input type="submit">
</form>
ex03.jsp에서 form태그에 요청방식을 POST로 요청하면
Ex03Servlet의 요청방식을 POST로 하는 오버라이딩된 함수인 doPost를 실행
answer를 파라미터로 받고 int형으로 형변환
flag를 attribute에 담아줌.
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
String answer = request.getParameter("answer");
int a = Integer.parseInt(answer);
boolean flag = n1 + n2 == a;
request.setAttribute("flag", flag);
RequestDispatcher rd = request.getRequestDispatcher(prefix + "ex03-action" + suffix);
rd.forward(request, response);
}
WEB-INF/views폴더 내의 ex03-action.jsp로 포워딩
ex03-action.jsp
<body>
<script>
const flag = '${flag}'
if(flag == 'true'){
alert('정답')
location.href = '${pageContext.request.contextPath}/ex03'
}
else {
alert('오답')
history.go(-1)
}
</script>
</body>
전달받은 flag가 정답이면 ex03으로 다시요청(doGet)
왼쪽 doGet > 포워딩 > ex03.jsp
오른쪽 doPost > 포워딩 >ex03-action.jsp
servlet을 쓰므로써 요청 응답방식이 한결 간단하고 깔끔해졌다.
하지만 servlet은 web.xml에 매번 추가해줘야한다는 단점이 있다.
@webServlet 어노테이션을 쓰면 일일이 web.xml에 추가하지않아도 된다.
servlet이 해당클래스와 어노테이션에 등록된 주소로 자동으로 맵핑하기 때문이다.
@WebServlet("/ex05")
public class Ex05Servlet extends HttpServlet {
'JSP' 카테고리의 다른 글
session (0) | 2023.08.18 |
---|---|
Connection Pool (커넥션 풀) , singleton(싱글톤) (0) | 2023.08.10 |
JSTL (0) | 2023.08.07 |
EL 태그 (1) | 2023.08.04 |
영화정보를 El태그, action태그를 사용해서 추가하기 (0) | 2023.08.04 |