주의!
servlet에 html 을 넣는 불편함을 해결하기 위해 jsp 가 등장하게 되었다.
따라서, 여기에서 servlet 에 html 태그를 넣는 방식은 이론적인 부분에서의 공부일 뿐임을 참고 바란다.
/WEB-INF
는 웹 서버가 사용하는 파일들이 들어있는 디렉터리이며, 외부에 있는 클라이언트가 직접적으로 바로 접근할 수는 없도록 막아놓았다. (404 에러가 발생할 것이다.)
에러가 발생하지 않고 해당 웹페이지로 연결되기 위해서는(클라이언트가 우회로 연결되기 위해서는) 2가지 방식이 있다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>서버로 데이터 전송하기</title>
</head>
<body>
<h3>서버로 데이터 전송</h3>
<form id="userinfoform" action="MyServlet">
<table>
<tr>
<td>번호 : </td>
<td><input type="text" size="3" name="num"></td>
<td>이름 : </td>
<td><input type="text" size="7" name="name"></td>
<td>나이 : </td>
<td><input type="text" size="3" name="age"></td>
<td>성별 : </td>
<td>
<select name="sex">
<option value="남성">남성</option>
<option value="여성">여성</option>
</select>
</td>
<td><input type="submit" width="10" id="btn" value="등록"></td>
</tr>
</table>
</form>
</body>
</html>
package com.servlet;
import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
@WebServlet("/MyServlet")
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html"); // 컨텐츠 타입
response.setCharacterEncoding("UTF-8"); // 인코딩 타입
// 웹 브라우저에 데이터를 전송
PrintWriter out = response.getWriter();
System.out.println("웹 브라우저에서 요청이 왔습니다.");
// 웹 브라우저에서 사용자가 입력한 데이터 가져오기
int num = Integer.parseInt(request.getParameter("num")); // int 타입
String name = request.getParameter("name"); // String 타입
int age = Integer.parseInt(request.getParameter("age"));
String sex = request.getParameter("sex");
out.println("<html><head><title>사용자 목록 페이지</title>");
out.println("<style>th {color: blue;}</style></head>");
out.println("<body><h3>사용자 목록</h3>");
out.println("<table border=\"1\" width=\"300\" height=\"10\">"
+ " <tr>"
+ " <th>번호</th>"
+ " <th>이름</th>"
+ " <th>나이</th>"
+ " <th>성별</th>"
+ " </tr>");
out.println("<tr><td>" + num + "</td>");
out.println("<td>" + name + "</td>");
out.println("<td>" + age + "</td>");
out.println("<td>" + sex + "</td></tr>");
out.println("</table>");
}
}
response.setContentType("text/html"), response.setCharacterEncoding("UTF-8")
PrintWriter out = response.getWriter()
System.out.println() 은 console.log 와 동일한 역할을 한다.
<style>
태그도 적용 가능하다.
out.println() 로 사용해야한다.
System.out.println() 으로 html 태그를 사용할 경우, 화면에 반영되지 않는다.
\ (백슬래시)의 사용
out.println("<table border=\"1\" width=\"300\" height=\"10\">\r\n" + 이하 생략...
를 보면
table 태그를 감싸는 ""큰따옴표와 table 태그에 속성(border, width, height)값을 구분하기 위해서,\"값\"
형태로 사용이 된다.
URL 매핑
현재는 /MyServlet 으로 매핑되어 있으나, 특정 확장자를 가진 모든 URL 패턴을 지정된 페이지로 이동시키도록 할 수도 있다.예를 들어,
@WebServlet("*.do")
은 .do 확장자(작업이름.do) 패턴을 가진 것들을 이동시키도록 하는 것이다.
'방법 1. @WebServlet("/URL매핑") 사용하기' 와 다른 부분만 간단히 작성했다.
생략...
<form id="userinfoform" action="hello">
<table>
<tr>
<td>번호 : </td>
<td><input type="text" size="3" name="num"></td>
<td>이름 : </td>
<td><input type="text" size="7" name="name"></td>
<td>나이 : </td>
<td><input type="text" size="3" name="age"></td>
<td>성별 : </td>
<td>
<select name="sex">
<option value="남성">남성</option>
<option value="여성">여성</option>
</select>
</td>
<td><input type="submit" width="10" id="btn" value="등록"></td>
</tr>
</table>
</form>
</body>
</html>
form 태그에 action 속성을 보면 hello
로 변경되었다.
(변경 이유는 '3) web.xml' 에서 확인 가능)
package com.servlet;
import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
public class MyServlet extends HttpServlet {
생략...
}
@WebServlet("/URL매핑") 을 사용하지 않는 대신, web.xml 에서 설정해준다.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0">
생략...
<servlet>
<servlet-name>servlet_test</servlet-name>
<servlet-class>com.servlet.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servlet_test</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
hello 로 요청할 경우, com.servlet 패키지에 MyServlet 서블릿 클래스가 실행되도록 매핑된 설정이다.
servlet 태그 : HttpServlet 을 상속받고 있는 클래스를 web.xml 에 등록할 때 사용
servlet-mapping 태그 : 실행할 Servlet 지정. 단, 이때 servlet 태그에서 지정해둔 서블릿 이름(servlet-name 태그에 있는)으로 지정해야 한다.
servlet 태그에 servlet-class 태그
클래스명(MyServlet) 뿐만 아니라, 패키지명을 포함한 클래스명을 함께 적어줘야한다.
서블릿 매핑
full path : 해당 경로를 통해서 포트번호, 서블릿이름, 위치가 보이지만, 보안에 취약함 --> 대안으로 mapping 을 사용즉, mapping 은 닉네임을 지어준다는 느낌.
Caused by: java.lang.IllegalArgumentException: 이름이 [myServlet]과 [com.servlet.MyServlet]인 두 서블릿들 모두 url-pattern [/MyServlet]에 매핑되어 있는데, 이는 허용되지 않습니다.
서블릿에 매핑된 URL 을 servelt-mapping 태그에 url-pattern 태그를 통해 대신 설정하게 되기 때문에,
서블릿에 매핑된 URL 과 url-pattern 태그에 설정된 URL 이 같으면 위와 같은 에러가 발생하게 된다.
따라서, 여기에서는 /hello 로 설정해주었다.
값을 입력하고 [등록]을 누르면
다음 페이지로 이동하면서, 입력한 값이 뜨게 된다.
jsp 에서 서버를 실행해야한다.
jsp 파일이 아닌, servlet 파일에서 Ctrl+F11 로 서버를 실행할 경우(이클립스 기준), 404 에러가 발생한다.
servlet의 경우, 서버 재실행을 해야만 수정 사항이 반영된다.
jsp로만 2개의 페이지를 만들어 데이터를 주고 받았을 때는 새로고침만으로도 변경 사항이 반영되었으나
servlet을 사용할 경우엔 tomcat(서버)의 재실행이 필요하다.
쿼리 스트링을 통해 값을 넘겨주게 된다.
구성을 보면 다음과 같다.
localhost:8080/프로젝트명/매핑된URL?변수1=값1&변수2=값2&변수3=값3&변수4=값4&
참고: Servlet - 데이터 전송/이미지 띄우기 실습
참고: 서블릿 구현 및 실행 (web.xml, @WebServlet 설정)
참고: [JSP/Servlet] 서블릿 구현하기 (HttpServlet, web.xml, 매핑이란?)