Hyper-Text MarkUp Language
고수준의 논문을 작성할 수 있는 제어 문법 언어
Hyper-Text Transfer Protocol
(Hyper link로 Client가 여러 Server를 넘나든다.)
= 앨리먼트(element)
Server Application + let
⇒ Server Application의 한 조각
PrintWriter out에 글을 쓰면 StringWriter에 글이 쌓이고 이 쌓인 글은 OutputStream out = HttpExchange를 통해 out.write()해서 웹 브라우저로 전송할 수 있다.
com/search.naver(App name)?
com.bitcamp.board.MiniWebServer 클래스 정의
MiniWebServer class
public class MiniWebServer {
public static void main(String[] args) throws Exception{
Connection con = DriverManager.getConnection(
"jdbc:mariadb://localhost:3306/studydb","study","1111");
BoardDao boardDao = new MariaDBBoardDao(con);
MemberDao memberDao = new MariaDBMemberDao(con);
WelcomeHandler welcomeHandler = new WelcomeHandler();
ErrorHandler errorHandler = new ErrorHandler();
BoardHandler boardHandler = new BoardHandler(boardDao);
MemberHandler memberHandler = new MemberHandler(memberDao);
class MyHttpHandler implements HttpHandler{
@Override
public void handle(HttpExchange exchange) throws IOException { // client가 요청할 때 마다 실행되는 method
System.out.println("클라이언트가 call함");
URI requestUri = exchange.getRequestURI();
String path = requestUri.getPath();
String query = requestUri.getQuery();
byte[] bytes = null;
try(StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter)) // try()
{
Map<String, String> paramMap = new HashMap<>();
if(query != null && query.length() > 0) { // 예)no =1 & title=aaaa&content=bbb
String[] entries = query.split("&");
for(String entry:entries) { // 예) no=1
String[] kv = entry.split("=");
paramMap.put(kv[0], kv[1]);
}
}
System.out.println(paramMap);
// path에 따라 메소드를 호출하여 페이지 변경하기
if(path.equals("/")) {
welcomeHandler.service(paramMap, printWriter);
}
else if(path.equals("/board/list")) {
boardHandler.list(paramMap, printWriter);
}
else if(path.equals("/board/detail")) {
boardHandler.detail(paramMap, printWriter);
}
else if(path.equals("/board/update")) {
boardHandler.update(paramMap, printWriter);
}
else if(path.equals("/board/delete")) {
boardHandler.delete(paramMap, printWriter);
}
else {
errorHandler.error(paramMap, printWriter);
}
bytes = stringWriter.toString().getBytes("UTF-8");
} catch(Exception e) {
bytes = "요청 처리 중 오류 발생!".getBytes("UTF-8");
e.printStackTrace(); // 서버 콘솔창에 오류에 대한 자세한 내용을 출력한다. -> 클라이언트에게 전송
} //try(){}catch{}
// 보내는 콘텐트의 MIME 타입이 무엇인지 응답 헤더를 추가로 설정한다.
Headers responseHeaders = exchange.getResponseHeaders();
responseHeaders.add("Content-Type", "text/html; charset=UTF-8");
exchange.sendResponseHeaders(200, bytes.length);
OutputStream out = exchange.getResponseBody();
out.write(bytes);
out.close();
}
}
HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
server.createContext("/", new MyHttpHandler());
server.setExecutor(null);
server.start();
System.out.println("서버 시작!");
}
}
public class BoardHandler {
private BoardDao boardDao;
public BoardHandler(BoardDao boardDao) {
this.boardDao = boardDao;
}
public void list(Map<String, String> paramMap, PrintWriter out) throws Exception {
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<meta charset=\"UTF-8\">");
out.println("<title>JWS</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>지민이의 게시글 상세정보!</h1>");
out.println("<h2>지민이테이블><</h2>");
out.println("<table border = '1'>");
out.println(" <tr>");
out.println(" <th>번호</th>");
out.println(" <th>제목</th>");
out.println(" <th>조회수</th>");
out.println(" <th>작성자</th>");
out.println(" <th>등록일</th>");
out.println(" </tr>");
List<Board> boards = boardDao.findAll();
for (Board board : boards) {
out.printf(" <tr>");
out.printf(" <td>%d</td>", board.no);
out.printf(" <td><a href='detail?no=%d'>%s</a></td>", board.no, board.title); // href = hyperlink-reference -> 하이퍼링크 생성
out.printf(" <td>%d</td>", board.viewCount);
out.printf(" <td>%d</td>", board.memberNo);
out.printf(" <td>%s</td>", board.createdDate);
out.printf("</tr>");
}
out.println("</table>");
out.println("</body>");
out.println("</html>");
}
public void detail(Map<String, String> paramMap, PrintWriter out) throws Exception {
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<meta charset=\"UTF-8\">");
out.println("<title>JWS</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>지민이의 게시글 상세정보!</h1>");
int boardNo = Integer.parseInt(paramMap.get("no"));
System.out.println(boardNo);
Board board = boardDao.findByNo(boardNo);
if(board == null) {
out.println("<p>해당 번호의 게시글이 없습니다!.</p>");
}else {
out.println("<form action='update'>");
out.println("<h2>지민이게시글 상세보기>o<</h2>");
out.println("<table border = '1'>");
out.println(" <tr>");
out.printf(" <th>번호</th>\n <td><input name ='no' type='text' value='%d' readonly></td>", board.no);
out.println(" </tr>");
out.println(" <tr>");
out.printf(" <th>제목</th>\n <td><input name='title' type='text' value='%s' size='60'></td>", board.title);
out.println(" </tr>");
out.println(" <tr>");
out.printf(" <th>내용</th>\n <td><textarea name='content' rows='10' cols='60'>%s</textarea></td>", board.content);
out.println(" </tr>");
out.println(" <tr>");
out.printf(" <th>조회수</th>\n <td>%d</td>", board.viewCount);
out.println(" </tr>");
out.println(" <tr>");
out.printf(" <th>작성자</th>\n <td>%s</td>", board.memberNo);
out.println(" </tr>");
out.println(" <tr>");
out.printf(" <th>등록일</th>\n <td>%s</td>", board.createdDate);
out.println(" </tr>");
out.println("</table>");
out.println("<p>");
out.println("<button type='submit'>변경</button>");
out.printf("<a href='delete?no=%d'>삭제</a>", board.no);
out.println("</p>");
out.println("</form>");
}
out.println("</body>");
out.println("</html>");
}
private void onInput(DataInputStream in, DataOutputStream out) throws Exception {
Prompt prompt = new Prompt(in, out);
Board board = new Board();
board.title = prompt.inputString("제목? ");
board.content = prompt.inputString("내용? ");
board.memberNo = prompt.inputInt("작성자? ");
boardDao.insert(board);
out.writeUTF("게시글을 등록했습니다.");
}
public void delete(Map<String, String> paramMap, PrintWriter out) throws Exception {
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<meta charset=\"UTF-8\">");
out.println("<title>JWS</title>");
// 3초뒤에 list페이지로 돌아가게 하는 코드
out.println("<meta http-equiv='Refresh' content ='3; url=list'>");
out.println("</head>");
out.println("<body>");
out.println("<h1>지민이의 게시글 삭제하기!</h1>");
int no = Integer.parseInt(paramMap.get("no"));
if(boardDao.delete(no) == 0) {
out.println("<p>해당 번호의 게시글이 없습니다!.</p>");
}else {
out.println("<p>해당 게시물을 삭제했습니다.</p>");
}
out.println("</body>");
out.println("</html>");
} // delete()
public void update(Map<String, String> paramMap, PrintWriter out) throws Exception {
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<meta charset=\"UTF-8\">");
out.println("<title>JWS</title>");
out.println("<meta http-equiv='Refresh' content ='3; url=list'>");
out.println("</head>");
out.println("<body>");
out.println("<h1>지민이의 게시글 변경하기!</h1>");
Board board = new Board();
board.no = Integer.parseInt(paramMap.get("no"));
board.title = paramMap.get("title");
board.content = paramMap.get("content");
if(boardDao.update(board) == 0) {
out.println("<p>해당 번호의 게시글이 없습니다!.</p>");
}else {
out.println("<p>해당 게시물을 변경했습니다.</p>");
}
out.println("</body>");
out.println("</html>");
} // update()
}