서블릿 공부를 하면서 WAS를 직접 만들어보는 시간을 가지고 있다.
아직 완성되지는 않았지만 중간점검(?) 느낌으로 기록하려고 한다.
먼저 코드를 작성하기 전에 아이패드로 그림을 그려서 설계를 해보았다.
(설계라고 말하기도 민망ㅎㅅㅎ)
전체적인 시나리오? 작성을 하면서 계속 생각한 것이 "먼저 숲을 보고 나무를 보자" 였다.
그래서 일단 나의 목표는!!!!
각 클래스의 역할, 클래스 간의 관계, 전체적인 흐름을 이해하는 것이었다.
그리고 그 안에 내부적인 기능에 대한 코드 작성은 나중에 더 신경쓰는 방향으로 결정했다.
(그냥 ....... 그래서 메소드 안에 코드가 깔끔하지 않을 수 있다는 것..ㅎ)
깃허브 : github.com/YuJinSong412/Mini_WAS
설계
일단 GET 요청을 처리하는 것으로 생각하고 작성했다. 그리고 클래스로더도 사용하지 않았다.
이렇게 적어보면서 코드를 작성한다고 했을 때는 어떤식으로 접근해야되는지 생각해봤다.
(필요한 클래스, 메소드 등 생각해봄.. 코드적으로 생각함..)
이렇게 정리해보니까 빨리 코드 작성하고 싶은 마음이 생겼었다.
이래서 설계하라는건가~~~~~~~?ㅋㅋ큐ㅠㅜㅜㅎㅎ
결과 화면
제출 누르면
자바 소스 코드
설계한 것처럼 일단 트리구조는 아래 사진과 같다.
설계에서 적었던 순서대로 코드 진행을 했다.
0) 서버 실행할 때 컨테이너 실행도 같이 하면서 서블릿 생성하고 초기화(init())를 한다.
import container.Container;
import server.WebServer;
public class ServerLaunch {
public static void main(String[] args) {
Container container = new Container();
container.start(); //컨테이너 실행
WebServer webServer = new WebServer();
webServer.start(); //웹서버 실행
}
}
container.start() 메소드를 보면 서블릿을 인스턴스화 하고 초기화를 합니다.
package container;
public class Container {
ServletInit servletInit;
public Container() {
servletInit = new ServletInit();
}
public void start() {
servletInit.startServletInit();
}
}
package container;
import java.io.File;
import java.util.ArrayList;
public class ServletInit {
static ArrayList<String> servletNames;
static ArrayList<Servlet> servletClasses;
public ServletInit() {
servletNames = new ArrayList<String>();
servletClasses = new ArrayList<Servlet>();
}
public void startServletInit() {
getServletName();
for (String servletName : servletNames) {
try {
Class c = Class.forName("servlet." + servletName);
Servlet my = (Servlet) c.newInstance();
servletClasses.add(my);
my.init();
} catch (ClassNotFoundException e1) {
//클래스를 찾지 못했을 경우에 대한 예외사항
e1.printStackTrace();
} catch(InstantiationException e2) {
//인스턴스(new) 실패 시에 대한 예외사항
e2.printStackTrace();
} catch(IllegalAccessException e3) {
//파일접근에 대한 예외사항
e3.printStackTrace();
}
}
}
private void getServletName() {
String path = "C:/Users/kev/eclipse-workspace/WebProject/src/servlet";
File dir = new File(path);
File[] files = dir.listFiles();
for (File file : files) {
int lastSeparator = file.toString().lastIndexOf("\\");
int startExtension = file.toString().indexOf(".");
String servletName = file.toString().substring(lastSeparator + 1, startExtension);
servletNames.add(servletName);
}
}
}
여기서 try 부분을 보면 Servlet 인터페이스가 왜 필요한지 알게된 것 같다.
만약 Servlet 인터페이스 없이 (정해진 규격없이) 서블릿 클래스를 만들면 하나씩 직접 다 인스턴스화 해줘야 했다. (for문을 사용할 수 없었음)
그래서 Servlet 인터페이스를 만들고 "Servlet my = (Servlet) c.newInstance();" 이렇게 형변환할 때 Servlet으로 주면 그 Servlet 인터페이스의 구현 클래스들을 순서대로 인스턴스화할 수 있었다.
이제 웹서버 실행을 보면
// 클래스 역할 : 1) 요청을 받음 2)정적,동적파일 구분 3)응답
public class WebServer {
private static final int PORT = 5027;
private final String SERVER_PATH = "C:\\Users\\kev\\eclipse-workspace\\WebProject\\WebContent\\basic";
public static ExecutorService executorService; // 스레드풀인 ExecutorService 선언
private ServerSocket serverSocket;
public void start() {
ExecutorService threadPool = new ThreadPoolExecutor(10, // 코어 스레드 개수
100, // 최대 스레드 개수
120L, // 놀고 있는 시간
TimeUnit.SECONDS, // 놀고 있는 시간 단위
new SynchronousQueue<Runnable>() // 작업 큐
); // 초기 스레드 개수 0개,
executorService = threadPool;
try {
serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress(PORT));
// 연결을 수락하는 코드
while (true) {
System.out.println("서버가 연결을 기다림");
Socket socket = serverSocket.accept();
// socket.setSoTimeout(1000);
// 스레드 풀의 작업 생성 - 따로 빼고 싶음.. 고민..
Runnable runnable = new Runnable() {
@Override
public void run() {
InputStream inputStream = null;
BufferedReader bufferedReader = null;
OutputStream outputStream = null;
try {
// 요청을 받는 역할 - 요청을 읽어서 request 객체에 정보를 넣음
Request request = new Request();
inputStream = socket.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
receiveRequest(request, bufferedReader);
System.out.println("오청받기 성공");
outputStream = socket.getOutputStream();
Response response = new Response(outputStream);
// 정적 파일인지 아닌지 구분
File file = getFile(request);
if (file.isFile()) {
sendResponse(file, response); // 정적파일이면 Response 응답을 보냄
} else {
new ContainerController(request, response).start(); // 동적파일이면 컨테이너 역할을 하는
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
bufferedReader.close();
outputStream.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
};
executorService.submit(runnable);
}
} catch (Exception e) {
e.printStackTrace();
}
if (!serverSocket.isClosed()) {
stopServer();
}
}
.....이어서
서버가 연결을 기다리다가 요청을 받으면 Runnable 작업 생성을 한다. WebServer 클래스의 역할인 요청 받고, 파일 구분하고, 응답하는 것 모두 runnable 안에서 이루어진다.(이 3가지 수행이 하나의 작업 단위임)
runnable 안에 있는 이 두 부분을 아래 설명과 같이 볼 것!
// 요청을 받는 역할 - 요청을 읽어서 request 객체에 정보를 넣음
Request request = new Request();
inputStream = socket.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
receiveRequest(request, bufferedReader);
System.out.println("오청받기 성공");
outputStream = socket.getOutputStream();
Response response = new Response(outputStream);
// 정적 파일인지 아닌지 구분
File file = getFile(request);
if (file.isFile()) {
sendResponse(file, response); // 정적파일이면 Response 응답을 보냄
} else {
new ContainerController(request, response).start(); // 동적파일이면 컨테이너 역할을 하는
}
1) 받은 HTTP Request 부분을 클래스 Request에 정보를 담는다.
앞에 Runnable 안에 있는 receiveRequest()메소드가 Request 객체 안에 요청받은 정보를 넣는 행동을 한다.
private void receiveRequest(Request request, BufferedReader bufferedReader) {
try {
String line = "tmp";
Map<String, String> requestHeaderMap = new HashMap<String, String>();
for (int i = 1; (line = bufferedReader.readLine()) != null && !line.equals(""); i++) {
// System.out.println(line);
if (i == 1) {
int firstBlank = line.indexOf(" ");
int lastBlank = line.lastIndexOf(" ");
request.setMethod(line.substring(0, firstBlank));
request.setRequestUrl(line.substring(firstBlank + 1, lastBlank).trim());
request.setHttpVersion(line.substring(lastBlank + 1).trim());
} else {
int indexOfColon = line.indexOf(": ");
if (indexOfColon == -1) {
continue;
} else {
String headerName = line.substring(0, indexOfColon).trim();
String headerValue = line.substring(indexOfColon + 1).trim();
requestHeaderMap.put(headerName, headerValue);
}
}
}
request.setHeaderMap(requestHeaderMap);
} catch (IOException e) {
e.printStackTrace();
}
}
Request 클래스를 보면 아래 코드와 같다.
package communication;
import java.util.HashMap;
import java.util.Map;
public class Request {
private String method;
private String requestUrl;
private String httpVersion;
private String connection;
private String accept;
private String acceptEncoding;
private Map<String, String> headerMap;
public Request() {
headerMap = new HashMap<String, String>();
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public String getRequestUrl() {
return requestUrl;
}
public void setRequestUrl(String requestUrl) {
this.requestUrl = requestUrl;
}
public String getHttpVersion() {
return httpVersion;
}
public void setHttpVersion(String httpVersion) {
this.httpVersion = httpVersion;
}
public String getConnection() {
return connection;
}
public void setConnection(String connection) {
this.connection = connection;
}
public String getAccept() {
return accept;
}
public void setAccept(String accept) {
this.accept = accept;
}
public String getAcceptEncoding() {
return acceptEncoding;
}
public void setAcceptEncoding(String acceptEncoding) {
this.acceptEncoding = acceptEncoding;
}
public Map<String, String> getHeaderMap() {
return headerMap;
}
public void setHeaderMap(Map<String, String> headerMap) {
this.headerMap = headerMap;
}
}
2) 정적 페이지, 동적 페이지 구분하기 (isFile) -> 경로 안에 파일이 있으면 정적!
3) 정적 페이지는 index.html(해당 페이지)를 읽는다.
private File getFile(Request request) {
String changeRequestUrl = request.getRequestUrl().replace("/", "\\");
String requestUrl = SERVER_PATH + changeRequestUrl + ".html";
File file = new File(requestUrl);
return file;
}
이 메소드를 이용해서 파일을 return하고 isFile()이 true이면 정적파일이므로 Response 응답을 보낸다. => sendResponse(file, response);
4) 클래스 Response로 응답하여 화면을 보여준다.
public void sendResponse(File file, Response response) throws IOException {
response.setFirstLine("HTTP/1.1 200 OK");
response.setContentType("Content-Type: text/html; charset=UTF-8");
response.setContentLength("Content-Length: " + file.length());
response.showScreen(file);
System.out.println("정적 파일 응답 보내줌");
}
여기서도 Response 클래스를 보면 아래와 같다.
package communication;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
public class Response {
private String firstLine;
private String contentType;
private String contentLength;
OutputStream outputStream;
public Response() {}
public Response(OutputStream outputStream) {
this.outputStream = outputStream;
}
public OutputStream getOutputStream() {
return outputStream;
}
public void setOutputStream(OutputStream outputStream) {
this.outputStream = outputStream;
}
public String getFirstLine() {
return firstLine;
}
public void setFirstLine(String firstLine) {
this.firstLine = firstLine;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public String getContentLength() {
return contentLength;
}
public void setContentLength(String contentLength) {
this.contentLength = contentLength;
}
public void showScreen(File file) throws IOException {
PrintWriter out = new PrintWriter(outputStream);
out.println(firstLine);
out.println(contentType);
out.println(contentLength);
out.println();
out.flush();
ArrayList<Byte> fileBytes = getFileBytes(file);
byte[] byteArr = new byte[fileBytes.size()];
int writeCount = 0;
for (byte fileByte : fileBytes) {
byteArr[writeCount] = fileByte;
writeCount++;
}
outputStream.write(byteArr);
outputStream.flush();
}
private ArrayList<Byte> getFileBytes(File file) {
ArrayList<Byte> fileBytes = new ArrayList<Byte>();
try {
FileInputStream fis = new FileInputStream(file);
int data = 0;
while ((data = fis.read()) != -1) {
fileBytes.add((byte) data);
}
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
return fileBytes;
}
}
5) 동적페이지는 컨테이너의 역할을 하는 클래스인 ContainerController로 Request와 Response객체를 넘긴다. 그리고 HTTPServletRequest와 HTTPServletResponse 객체를 생성한다.
앞 코드 다시 보면 "new ContainerController(request, response).start();" 이것이 있다. 이것이 실행된다.
package container;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import communication.Request;
import communication.Response;
// 클래스 역할 : httpServletRes,req 객체 생성, xml 분석, 스레드 실행 후 서블릿 실행, httpServletReq 응답 처리(?)
public class ContainerController {
private static final String XML_PATH = "C:\\Users\\kev\\eclipse-workspace\\WebProject\\WebContent\\WEB-INF\\web.xml";
private static final String FOLDER_NAME = "/basic";
private static final String SERVLET_FOLDER_NAME = "servlet.";
HTTPServletRequest httpServletRequest;
HTTPServletResponse httpServletResponse;
Map<String, String> servletMap;
String foundServletName;
public ContainerController(Request request, Response response) {
System.out.println("컨테이너 로직까지 왔음");
httpServletRequest = new HTTPServletRequest(request);
httpServletResponse = new HTTPServletResponse(response);
servletMap = new HashMap<String, String>();
}
public void start() {
// xml분석
servletMap = readDeploymentDescriptor();
if (servletMap.size() == 0) {
System.out.println("서블릿이 없습니다.");
} else {
foundServlet();
executeServlet();
}
}
....이어서
여기는 start() 메소드 안을 볼 것!
<기억할 메소드>
readDeploymentDescriptor();
foundServlet();
executeServlet();
6번인 XML 파일 분석하기 전에 HTTPServletRequest와 HTTPServletResponse 클래스를 먼저 보겠다.
package container;
import java.util.HashMap;
import java.util.Map;
import communication.Request;
public class HTTPServletRequest {
Request request;
private String method;
private String queryString;
private String requestUrl;
public HTTPServletRequest(Request request) {
this.request = request;
reApply();
}
private void reApply() {
method = request.getMethod();
String[] separationUrl = request.getRequestUrl().split("\\?");
if (separationUrl.length != 0) {
requestUrl = separationUrl[0];
queryString = separationUrl[1];
}
}
public Request getRequest() {
return request;
}
public void setRequest(Request request) {
this.request = request;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public String getQueryString() {
return queryString;
}
public void setQueryString(String queryString) {
this.queryString = queryString;
}
public String getRequestUrl() {
return requestUrl;
}
public void setRequestUrl(String requestUrl) {
this.requestUrl = requestUrl;
}
public String getParameter(String name) {
Map<String, String> queryStringValue = new HashMap<String, String>();
queryStringValue = divideQueryString();
String result = "";
for (String key : queryStringValue.keySet()) {
if (key.equals(name)) {
result = queryStringValue.get(key);
} else {
result = null;
}
}
return result;
}
private Map<String, String> divideQueryString() {
Map<String, String> queryStringValue = new HashMap<String, String>();
String[] separationQuery = queryString.split("=");
queryStringValue.put(separationQuery[0], separationQuery[1]);
return queryStringValue;
}
}
package container;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import communication.Response;
public class HTTPServletResponse {
Response response;
private String contentType;
OutputStream outputStream;
private int contentLength;
public HTTPServletResponse(Response response) {
this.response = response;
reApply();
}
private void reApply() {
this.outputStream = response.getOutputStream();
}
public PrintWriter headerInfo() {
PrintWriter out = new PrintWriter(outputStream);
out.println("HTTP/1.1 200 OK");
out.println("Content-Type: text/html; charset=UTF-8");
out.println();
out.flush();
return out;
}
public PrintWriter getWriter() throws IOException {
PrintWriter out = headerInfo();
return out;
}
public void showScreen(ByteArrayOutputStream bout) throws IOException {
headerInfo();
bout.writeTo(outputStream);
}
public int getContentLength() {
return contentLength;
}
public void setContentLength(int contentLength) {
this.contentLength = contentLength;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public OutputStream getOutputStream() {
return outputStream;
}
public void setOutputStream(OutputStream outputStream) {
this.outputStream = outputStream;
}
}
6) XML 파일을 분석하여
readDeploymentDescriptor() 메소드를 이용해서 분석한다.
<?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"
id="WebApp_ID" version="4.0">
<display-name>Mini_WAS</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>index2</servlet-name>
<servlet-class>servlet.MyServlet</servlet-class>
<init-param>
<param-name>adminEmail</param-name>
<param-value>ujsong4@naver.com</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>index2</servlet-name>
<url-pattern>/basic/SelectBeer.do</url-pattern>
</servlet-mapping>
</web-app>
private Map<String, String> readDeploymentDescriptor() {
Map<String, String> servletMap = new HashMap<String, String>();
File file = new File(XML_PATH);
try {
FileInputStream fis = new FileInputStream(file);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
String line = "";
String oldLine = "";
String servletClass = "";
String servletName = "";
for (int i = 1; (line = br.readLine()) != null; i++) {
if (oldLine.contains("<servlet-name>") && line.contains("<servlet-class>")) {
int name_firstText = oldLine.indexOf(">") + 1;
int name_lastText = oldLine.indexOf("</") - 1;
int firstText = line.indexOf(">") + 1;
int lastText = line.indexOf("</") - 1;
servletName = oldLine.substring(name_firstText, name_lastText + 1);
servletClass = line.substring(firstText, lastText + 1);
servletMap.put(servletName, servletClass);
} else if (oldLine.contains("<servlet-name>") && line.contains("<url-pattern>")) {
int name_firstText = oldLine.indexOf(">") + 1;
int name_lastText = oldLine.indexOf("</") - 1;
String servletName2 = oldLine.substring(name_firstText, name_lastText + 1);
if (servletName2.equals(servletName)) {
int firstText = line.indexOf(">") + 1;
int lastText = line.indexOf("</") - 1;
String servletUrl = line.substring(firstText, lastText + 1);
servletMap.put(servletUrl, servletClass);
}
}
oldLine = line;
}
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
return servletMap;
}
7) 찾을 서블릿을 찾으면 그 서블릿의 service(HTTPServletRequest, HTTPServletResponse) 메소드를 실행한다.
foundServlet()메소드에서 찾는 서블릿을 찾고 executeServlet()메소드에서 service()메소드를 실행한다.
private void foundServlet() {
String requestUrl_new = FOLDER_NAME + httpServletRequest.getRequestUrl();
String servletName = "";
for (String key : servletMap.keySet()) {
if (key.equals(requestUrl_new)) {
servletName = servletMap.get(key);
System.out.println(servletName + " 서블릿 찾았다.");
}
}
foundServletName = servletName;
}
private void executeServlet() {
try {
int i = 0;
for (String servletName : ServletInit.servletNames) {
if (foundServletName.equals(SERVLET_FOLDER_NAME + servletName)) {
ServletInit.servletClasses.get(i).service(httpServletRequest, httpServletResponse);
}
i++;
}
} catch (Exception e) {
e.printStackTrace();
}
}
8) service()는 내가 작성한 서블릿의 오버라이딩된 doGet()를 자동 호출하여 실행한다.
Servlet 인터페이스 , HttpServlet 추상 클래스, MyServlet 클래스 순서대로..
package container;
public interface Servlet {
public void init(ServletConfig servletConfig);
public void init();
public void service(HTTPServletRequest httpServletRequest, HTTPServletResponse httpServletResponse);
public void destroy();
public String getServletInfo();
public ServletConfig getServletConfig();
}
package container;
public abstract class HttpServlet implements Servlet {
private static final String METHOD_GET = "GET";
ServletConfig servletConfig;
@Override
public void init(ServletConfig config) {
servletConfig = config;
this.init();
}
public void init() {
System.out.println("서블릿 init()초기화!");
}
public void destroy() {}
// public String getInitParameter(String name) {
//
// return getServletConfig().getInitParameter(name);
// }
@Override
public void service(HTTPServletRequest httpServletRequest, HTTPServletResponse httpServletResponse) {
System.out.println("service() 메소드는 HttpServlet 클래스 여기로");
String method = httpServletRequest.getMethod();
if (method.equals(METHOD_GET)) {
System.out.println("doGet() 메소드 실행");
doGet(httpServletRequest, httpServletResponse);
}
}
public void doGet(HTTPServletRequest httpServletRequest, HTTPServletResponse httpServletResponse) {}
@Override
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
}
@Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return null;
}
}
package servlet;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import container.HTTPServletRequest;
import container.HTTPServletResponse;
import container.HttpServlet;
public class MyServlet extends HttpServlet {
private static final String ENCODING = "utf-8";
@Override
public void doGet(HTTPServletRequest httpServletRequest, HTTPServletResponse httpServletResponse) {
ByteArrayOutputStream bout = new ByteArrayOutputStream(8192);
PrintWriter out;
try {
out = new PrintWriter(new OutputStreamWriter(bout, ENCODING));
// out = httpServletResponse.getWriter();
out.println("<html><head><style>body{background-color: #F8F4BD;}</style></head><body>" + "<h1 align=center>유진스의 선택은!!!!???<br></h1>");
String result = httpServletRequest.getParameter("kind");
out.println("<br><h3>맛도 좋고 몸에도 좋은 ~ <span style = 'color: red'>" + result + "</span></h3></body></html>");
out.flush();
httpServletResponse.setContentLength(bout.size());
System.out.println(bout.size());
httpServletResponse.showScreen(bout);
} catch (IOException e) {
e.printStackTrace();
}
}
}
9) HTTPServletResponse 객체로 응답을 보내서 화면을 보여준다.
여기서 2가지 방법을 적용시켜봤다.
1. 처음에는 동적페이지는 응답 헤더에 content-Length를 주지 않아도 된다고 해서 content-Length를 주지 않는 방법
2. 임시 바이트 버퍼를 사용하여 길이를 먼저 측정하고 출력하는 방법
MyServlet의 doGet()메소드와 HTTPServletResponse 2개만 다시 보면 된다. HTTPServletResponse 부분은 다른 메소드를 사용함
[첫 번째 방법!!!]
public class MyServlet extends HttpServlet {
private static final String ENCODING = "utf-8";
@Override
public void doGet(HTTPServletRequest httpServletRequest, HTTPServletResponse httpServletResponse) {
//ByteArrayOutputStream bout = new ByteArrayOutputStream(8192);
PrintWriter out;
try {
//out = new PrintWriter(new OutputStreamWriter(bout, ENCODING));
out = httpServletResponse.getWriter();
out.println("<html><head><style>body{background-color: #F8F4BD;}</style></head><body>" + "<h1 align=center>유진스의 선택은!!!!???<br></h1>");
String result = httpServletRequest.getParameter("kind");
out.println("<br><h3>맛도 좋고 몸에도 좋은 ~ <span style = 'color: red'>" + result + "</span></h3></body></html>");
out.flush();
// httpServletResponse.setContentLength(bout.size());
// System.out.println(bout.size());
//
// httpServletResponse.showScreen(bout);
} catch (IOException e) {
e.printStackTrace();
}
}
}
[두 번째 방법!!!]
public class MyServlet extends HttpServlet {
private static final String ENCODING = "utf-8";
@Override
public void doGet(HTTPServletRequest httpServletRequest, HTTPServletResponse httpServletResponse) {
ByteArrayOutputStream bout = new ByteArrayOutputStream(8192);
PrintWriter out;
try {
out = new PrintWriter(new OutputStreamWriter(bout, ENCODING));
// out = httpServletResponse.getWriter();
out.println("<html><head><style>body{background-color: #F8F4BD;}</style></head><body>" + "<h1 align=center>유진스의 선택은!!!!???<br></h1>");
String result = httpServletRequest.getParameter("kind");
out.println("<br><h3>맛도 좋고 몸에도 좋은 ~ <span style = 'color: red'>" + result + "</span></h3></body></html>");
out.flush();
httpServletResponse.setContentLength(bout.size());
System.out.println(bout.size());
httpServletResponse.showScreen(bout);
} catch (IOException e) {
e.printStackTrace();
}
}
}
이렇게 다 하면 앞에 캡쳐한 결과 화면이 실행된다~!
아직 ServletConfig 적용도 못했고 GET 메소드 처리하는 것밖에 안했고,, 코드도 정리해야하고,, 사실 이 모든 것이 이상할 수도 있는데...
상무님 검사를 받아야한당,,,
검사를 받고 또 작성할 것임😤😭🥺
'IT > Servlet & JSP' 카테고리의 다른 글
[Servlet & JSP] 3. 속성과 리스너 (0) | 2020.11.09 |
---|---|
[Servlet & JSP] 2. Servlet 따라가보기 (0) | 2020.11.05 |