일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Calendar
- Properties
- javascript
- spring boot
- Java
- List
- alter
- set
- union_find
- priority_queue
- CSS
- 리소스모니터링
- date
- 큐
- NIO
- GC로그수집
- html
- math
- map
- 스택
- scanner
- sql
- dfs
- JPA
- deque
- 힙덤프
- BFS
- Union-find
- string
- 스프링부트
- Today
- Total
매일 조금씩
12/22 - JSP(3) : 데이터베이스 연결, 커넥션 풀, 게시판 만들 준비 본문
실습) 달력 검색
JSPEx02
calendar04.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.Calendar" %>
<%
request.setCharacterEncoding("utf-8");
String strYear = request.getParameter("year");
String strMonth = request.getParameter("month");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form name="frm" method="post" action="calendar04.jsp">
<select name="year">
<option value="2019">2019</option>
<option value="2020">2020</option>
<option value="2021">2021</option>
</select>
<select name="month">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
</select>
<input type="submit" value="보기"/>
</form>
<%
if(strYear != null && strMonth != null){
int year = Integer.parseInt(strYear);
int month = Integer.parseInt(strMonth);
int START_DAY_OF_WEEK = 0;
int END_DAY_OF_WEEK = 0;
int END_DAY = 0;
Calendar sDay = Calendar.getInstance();
Calendar eDay = Calendar.getInstance();
sDay.set(year, month-1, 1);
eDay.set(year, month, 1-1);
START_DAY_OF_WEEK = sDay.get(Calendar.DAY_OF_WEEK);
END_DAY_OF_WEEK = eDay.get(Calendar.DAY_OF_WEEK);
END_DAY = eDay.get(Calendar.DATE);
out.println("<table width='800' border='1'>");
out.println("<tr>");
out.println(" <td colspan='7'>" + year + "년" + month + "월</td>");
out.println("</tr>");
out.println("</tr>");
for(int i=1; i<START_DAY_OF_WEEK; i++){
out.print("<td></td>");
}
for(int i=1, n=START_DAY_OF_WEEK; i<=END_DAY ; i++,n++){
if(n % 7 == 1) out.println("<tr>");
out.println( " <td>" + i + "</td>");
if(n % 7 == 0) out.println("</tr>");
}
for(int i=END_DAY_OF_WEEK; i<=6; i++){
out.print("<td></td>");
}
out.println("</tr>");
out.println("</table>");
}
%>
</body>
</html>
데이터베이스 연결
실습1) 데이터베이스 연결 + 구동
1. WebContent > WEB-INF > lib 에 jdbc 드라이버 추가하기
2. 코드 작성
Jdbc01.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.sql.DriverManager" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.SQLException" %>
<%
String url="jdbc:mysql://localhost:3307/sample";
String user ="root";
String password ="!123456";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
StringBuffer html = new StringBuffer();
try{
Class.forName("org.mariadb.jdbc.Driver");
// out.println("드라이버 로딩 성공");
conn = DriverManager.getConnection(url, user,password);
String sql = "select deptno, dname, loc from dept";
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
//out.println("<table width='800' border='1'>");
//out.println("<tr>");
//out.println("<td>deptno</td>");
//out.println("<td>dname</td>");
//out.println("<td>loc</td>");
//out.println("</tr>");
html.append("<table width='600' border='1'>");
while(rs.next()){
//out.println("<tr>");
//out.println("<td>" + rs.getString("deptno")+"</td>");
//out.println("<td>" + rs.getString("dname")+"</td>");
//out.println("<td>" + rs.getString("loc")+"</td>");
//out.println("</tr>");
html.append("<tr>");
html.append("<td>" + rs.getString("deptno")+"</td>");
html.append("<td>" + rs.getString("dname")+"</td>");
html.append("<td>" + rs.getString("loc")+"</td>");
html.append("</tr>");
}
//out.println("</table>");
html.append("</table>");
} catch(ClassNotFoundException e){
out.println("[에러] " + e.getMessage());
} catch(SQLException e){
out.println("[에러] " + e.getMessage());
} finally{
if(rs != null) rs.close();
if(pstmt != null) pstmt.close();
if(conn != null) conn.close();
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
//out.println(html);
%>
<%= html %>
</body>
</html>
실습2) 동이름 검색하여 해당 주소 테이블로 출력하기
submit은 바로 값을 request로 넘기고
button은 onlick 일때 <script>의 함수로 가게 해서 값 검사를 한후
그 함수에서 submit()을 하면 request로 가는거다.
js로 값 검사를 하는 이유는 클라이언트에서 값을 입력받고 그 값이 유효한 값이 아니면 굳이 서버까지 보낼 필요가 없기 때문이다. 따라서, js로 클라이언트에서 값 검사를 한다.
script문은 js인데 js는 클라이언트 동작을 제어하기 위한 것이다.
JSP는 서버 동작을 제어하기 위한 것이다.
따라서 JSP는 Java와 다를것이 없는데 값검사는 js로 하고 실제 동적인 화면 제어는 Java가 한다고 보면된다.
'신사동' 검색 시 다음과 같이 출력됨
1. Jdbc02.jsp - 내가 한거
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.sql.DriverManager" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.SQLException" %>
<%
request.setCharacterEncoding("utf-8");
String strDong = request.getParameter("dong");
String url="jdbc:mysql://localhost:3307/sample";
String user ="root";
String password ="!123456";
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form name="frm" method="post" action="Jdbc02.jsp">
<input type="text" name="dong"/>
<input type="submit" value="검색"/>
</form>
<%
if(strDong != null){
Connection conn = null;
PreparedStatement pstmt1 = null;
PreparedStatement pstmt2 = null;
ResultSet rs1 = null;
ResultSet rs2 = null;
StringBuffer html = new StringBuffer();
try{
Class.forName("org.mariadb.jdbc.Driver");
// out.println("드라이버 로딩 성공");
conn = DriverManager.getConnection(url, user,password);
String sql1 = "select dong from zipcode where dong = ?";
pstmt1 = conn.prepareStatement(sql1);
pstmt1.setString(1,strDong);
rs1 = pstmt1.executeQuery();
if(!rs1.next()){
out.println("동이름이 아닙니다.");
}
else{
String sql2 = "select sido, gugun, dong, ri, bunji from zipcode where dong = ?";
pstmt2 = conn.prepareStatement(sql2);
pstmt2.setString(1, strDong);
rs2 = pstmt2.executeQuery();
html.append("<table width='600' border='1'>");
html.append("<tr>");
html.append("<td>시도</td>");
html.append("<td>구군</td>");
html.append("<td>동</td>");
html.append("<td>리</td>");
html.append("<td>번지</td>");
html.append("</tr>");
while(rs2.next()){
html.append("<tr>");
html.append("<td>" + rs2.getString("sido")+"</td>");
html.append("<td>" + rs2.getString("gugun")+"</td>");
html.append("<td>" + rs2.getString("dong")+"</td>");
html.append("<td>" + rs2.getString("ri")+"</td>");
html.append("<td>" + rs2.getString("bunji")+"</td>");
html.append("</tr>");
}
html.append("</table>");
}
} catch(ClassNotFoundException e){
out.println("[에러] " + e.getMessage());
} catch(SQLException e){
out.println("[에러] " + e.getMessage());
} finally{
if(rs1 != null) rs1.close();
if(rs2 != null) rs2.close();
if(pstmt1 != null) pstmt1.close();
if(pstmt2 != null) pstmt2.close();
if(conn != null) conn.close();
}
out.println(html);
}
%>
</body>
</html>
2. zipcode01.jsp - 강사님 코드
값 확인을 script로 한다는 것이 내것과 차이가있음
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.sql.DriverManager"%>
<%@ page import="java.sql.Connection"%>
<%@ page import="java.sql.ResultSet"%>
<%@ page import="java.sql.PreparedStatement"%>
<%@ page import="java.sql.SQLException"%>
<%
request.setCharacterEncoding("utf-8");
String strDong = request.getParameter("dong");
// if문 밖에서 출력되니까 if문 밖에 선언
StringBuffer html = new StringBuffer();
if(strDong != null){
String url = "jdbc:mysql://localhost:3307/sample";
String user = "root";
String password = "!123456";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
Class.forName("org.mariadb.jdbc.Driver");
// out.println("드라이버 로딩 성공");
conn = DriverManager.getConnection(url, user, password);
String sql = "select sido, gugun, dong, ri, bunji from zipcode where dong like ?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, strDong);
rs = pstmt.executeQuery();
html.append("<table width='600' border='1'>");
html.append("<tr>");
html.append("<td>시도</td>");
html.append("<td>구군</td>");
html.append("<td>동</td>");
html.append("<td>리</td>");
html.append("<td>번지</td>");
html.append("</tr>");
while (rs.next()) {
html.append("<tr>");
html.append("<td>" + rs.getString("sido") + "</td>");
html.append("<td>" + rs.getString("gugun") + "</td>");
html.append("<td>" + rs.getString("dong") + "</td>");
html.append("<td>" + rs.getString("ri") + "</td>");
html.append("<td>" + rs.getString("bunji") + "</td>");
html.append("</tr>");
}
html.append("</table>");
} catch (ClassNotFoundException e) {
out.println("[에러] " + e.getMessage());
} catch (SQLException e) {
out.println("[에러] " + e.getMessage());
} finally {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
}
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
const checkfrm = function(){
if(document.frm.dong.value.trim() == ""){
alert('동이름을 입력하세요');
return;
}
document.frm.submit();
};
</script>
</head>
<body>
<form name="frm" method="post" action="zipcode01.jsp">
<input type="text" name="dong" />
<input type="button" value="동이름 검색" onclick="checkfrm()"/>
</form>
<%
out.println(html);
%>
</body>
</html>
지금까지 한건 was -> jsp -> db
여기서부턴 was -> db
connection pool
커넥션 풀 (Connection Pool)
▷p360
▷p416 커넥션 풀
커넥션 풀 기법이란, 데이터베이스와 연결된 커넥션을 미리 만들어서 풀(pool) 속에 저장해 두고 있다가 필요할 때에 커넥션을 풀에서 가져다 쓰고 다시 풀에 반환하는 기법을 의미한다.
- was에서 만들고 이걸 가져다 쓴다.
- 이걸 JNDI(자바 네이밍 데이터 인터페이스) 라고 한다.
- 네임을 가지고 있어서 자바에서 가져다 쓸수 있다.
- context.sml이라는 파일안에 데이터베이스 설정에 대한 얘기를 해줘야한다.
JNDI로 커넥션 풀 집어 오는 방법 순서 !
- 먼저 jdbc드라이버를 프로젝트에 추가한 후
- META-INF에 context.xml 파일을 만든후
- 그파일로 들어가면 design창으로 되어있는데
- 아래 탭에서 source창으로 바꿔준 후, 데이터베이스 연결 설정 코드를 작성한다.
context.xml
<?xml version="1.0" encoding="utf-8" ?>
<Context>
<!-- 데이터베이스 연결 설정 -->
<Resource
name="jdbc/mariadb1"
auth="Container"
type="javax.sql.DataSource"
driverClassName="org.mariadb.jdbc.Driver"
url = "jdbc:mysql://localhost:3307/sample"
username = "root"
password = "!123456" />
</Context
<주의 사항>
1. 제대로 적용시키려면 tomcat을 껐다켜야한다.
2. name, username이 서로 매칭되어 있다. 그래서 username 등이 바뀌면 name도 같이 바꿔줘야한다.
실습1) 커넥션풀을 사용한 데이터베이스 연결
JDBCEx03
1. jndi01.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="javax.naming.Context" %>
<%@ page import="javax.naming.InitialContext" %>
<%@ page import="javax.naming.NamingException" %>
<%@ page import="javax.sql.DataSource" %>
<%@ page import="java.sql.Connection"%>
<%@ page import="java.sql.ResultSet"%>
<%@ page import="java.sql.PreparedStatement"%>
<%@ page import="java.sql.SQLException"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
Connection conn = null;
try{
Context initCtx = new InitialContext();
// 자바 환경변수 검색
Context envCtx = (Context)initCtx.lookup("java:comp/env");
// name 값으로 찾고 type(데이터소스)이 return됨
// 반드시 context.xml의 name값이여야함
DataSource dataSource = (DataSource)envCtx.lookup("jdbc/mariadb1");
conn = dataSource.getConnection();
out.println("연결 성공");
} catch(NamingException e){
out.println("[에러]" + e.getMessage());
} catch(SQLException e){
out.println("[에러]" + e.getMessage());
}finally{
if(conn != null) conn.close();
}
%>
</body>
</html>
2. jndi02.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="javax.naming.Context" %>
<%@ page import="javax.naming.InitialContext" %>
<%@ page import="javax.naming.NamingException" %>
<%@ page import="javax.sql.DataSource" %>
<%@ page import="java.sql.Connection"%>
<%@ page import="java.sql.ResultSet"%>
<%@ page import="java.sql.PreparedStatement"%>
<%@ page import="java.sql.SQLException"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs= null;
try{
Context initCtx = new InitialContext();
// 자바 환경변수 검색
Context envCtx = (Context)initCtx.lookup("java:comp/env");
// name 값으로 찾고 type(데이터소스)이 return됨
// 반드시 context.xml의 name값이여야함
DataSource dataSource = (DataSource)envCtx.lookup("jdbc/mariadb1");
conn = dataSource.getConnection();
out.println("연결 성공");
// 아래는 모두 원래와 동일
String sql = "select deptno, dname, loc from dept";
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
while(rs.next()){
out.println(rs.getString("deptno") + "<br />");
}
} catch(NamingException e){
out.println("[에러]" + e.getMessage());
} catch(SQLException e){
out.println("[에러]" + e.getMessage());
}finally{
if(conn != null) conn.close();
}
%>
</body>
</html>
실습2) 커넥션풀을 사용한 동이름 검색으로 주소 출력하기
JDBCEx03
zipcode01.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="javax.naming.Context" %>
<%@ page import="javax.naming.InitialContext" %>
<%@ page import="javax.naming.NamingException" %>
<%@ page import="javax.sql.DataSource" %>
<%@ page import="java.sql.Connection"%>
<%@ page import="java.sql.ResultSet"%>
<%@ page import="java.sql.PreparedStatement"%>
<%@ page import="java.sql.SQLException"%>
<%
request.setCharacterEncoding("utf-8");
String strDong = request.getParameter("dong");
// if문 밖에서 출력되니까 if문 밖에 선언
StringBuffer html = new StringBuffer();
if(strDong != null){
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
Context initCtx = new InitialContext();
// 자바 환경변수 검색
Context envCtx = (Context)initCtx.lookup("java:comp/env");
// name 값으로 찾고 type(데이터소스)이 return됨
// 반드시 context.xml의 name값이여야함
DataSource dataSource = (DataSource)envCtx.lookup("jdbc/mariadb1");
conn = dataSource.getConnection();
// out.println("연결 성공");
String sql = "select sido, gugun, dong, ri, bunji from zipcode where dong like ?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, strDong);
rs = pstmt.executeQuery();
html.append("<hr />");
html.append("<table width='600' border='1'>");
html.append("<tr>");
html.append("<td>시도</td>");
html.append("<td>구군</td>");
html.append("<td>동</td>");
html.append("<td>리</td>");
html.append("<td>번지</td>");
html.append("</tr>");
while (rs.next()) {
html.append("<tr>");
html.append("<td>" + rs.getString("sido") + "</td>");
html.append("<td>" + rs.getString("gugun") + "</td>");
html.append("<td>" + rs.getString("dong") + "</td>");
html.append("<td>" + rs.getString("ri") + "</td>");
html.append("<td>" + rs.getString("bunji") + "</td>");
html.append("</tr>");
}
html.append("</table>");
} catch (NamingException e) {
out.println("[에러] " + e.getMessage());
} catch (SQLException e) {
out.println("[에러] " + e.getMessage());
} finally {
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
}
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
const checkfrm = function(){
if(document.frm.dong.value.trim() == ""){
alert('동이름을 입력하세요');
return;
}
document.frm.submit();
};
</script>
</head>
<body>
<form name="frm" method="post" action="zipcode01.jsp">
<input type="text" name="dong" />
<input type="button" value="동이름 검색" onclick="checkfrm()"/>
</form>
<%
out.println(html);
%>
</body>
</html>
게시판 만들기
Page Navigation (페이지간의 흐름) - 데이터의 흐름도 포함 시켜야한다.
→ 웹페이지짤때 가장 먼저 해줘야하는 부분
1. 흐름상 숨겨진 페이지 찾기 (디자인이 없는 페이지)
ㅇ 글목록 (board_list1.jsp)
ㅇ 글쓰기 (board_write1.jsp) - db에 input하는 페이지가 숨겨짐 - 자료가 필요
ㅇ 글보기 (board_view1.jsp) - 글목록에서 올때 글번호가 필요.
ㅇ 글수정 (board_modify1.jsp) - db를 update하는 페이지가 숨겨짐 -> 글보기로 감 - 글 번호, 자료 필요
ㅇ 글삭제 (board_delete1.jsp) - db를 delete하는 페이지가 숨겨짐 -> 글목록으로 감 - 글 번호, 자료 필요
ㅇ 글목록 (board_list1.jsp)
(없음)
ㅇ 글쓰기 (board_write1.jsp)
(글자료)
board_write_ok1.jsp -> (없음) -> board_list1.jsp
(글번호)
ㅇ 글보기 (board_view1.jsp)
(글번호)
ㅇ 글수정 (board_modify1.jsp)
(글번호, 글자료)
board_modify_ok1.jsp -> (글번호) -> board_view1.jsp
(글번호)
ㅇ 글삭제 (board_delete1.jsp)
(글번호, 글자료)
board_modify_ok1.jsp -> (글번호) -> board_list1.jsp
브라우저에서 입력을 받고 그것을 토대로 데이터베이스와 작업이 이루어 지는 페이지는 ok 페이지가 필요하다.
2. 디자인에서 테이블 구성(컬럼)을 뽑기
테이블 구성
글번호 seq int not null primary key
제목 subject varchar(150) not null
글쓴이 writer varchar(12) not null
이메일 mail varchar(50)
비밀번호 password varchar(12) not null
내용 content varchar(2000)
조회수 hit int not null
IP wip varchar(15) not null
등록일 wdate datetime not null
create table board1(
seq int not null primary key auto_increment,
subject varchar(150) not null ,
writer varchar(12) not null,
mail varchar(50),
password varchar(12) not null,
content varchar(2000),
hit int not null,
wip varchar(15) not null,
wdate datetime not null
);
insert into board1 values(0,'제목','이름','test@test.com','1234','내용',0,'000.000.000.000',now());
- auto_increment : 중복되지 않게 자동 증가 primary key인 int컬럼만 가능하다. 테이블에서 하나만 줄수 있다.
- <script> 안의 js 코드에선 html의 값들을 다루는데 그 값을 가져오기 위해서 document 키워드를 사용해야한다.
- document.js코드의 함수를 부르는 태그의이름.값의이름.value : 값을 가져옴
- document.js코드의 함수를 부르는 태그의이름.값의이름.checked : 값이 체크박스일때 체크 유무를 가져옴
- document.wfrm.info.~
글쓰기에 성공했을 때와 같이 성공 후에 자동으로 목록 페이지로 돌아간다든가 그런작업은 아래와 같이 script를 사용한다.
out.println("<script type='text/javascript'>");
if(flag == 0){
out.println("alert('글쓰기에 성공했습니다.');");
out.println("location.href='board_list1.jsp';");
} else{
out.println("alert('글쓰기에 실패했습니다.');");
out.println("history.back()");
}
out.println("</script>");
jsp는 html안에 java를 쓰는것이다.
따라서, jsp의 java코드에서 out.println()은 <% %> 태그를 밖에 괄호안의 내용을 쓰는 거라고 보면된다.
※ <button>과 <input>의 차이
(1) <button>과 <input>의 submit 타입
<form action="board_write1_ok.jsp" method="post" name="wfrm" onsubmit="return checkfrm()">
<!-- button태그와 input태그의 submit타입은 둘다 실행과 동시에 submit함 -->
<button id="wbtn" class="btn_write btn_txt01" style="cursor: pointer;">등록</button>
<input type="submit" id="wbtn" value="등록" class="btn_write btn_txt01" style="cursor: pointer;" />
(2) <input>의 button 타입
<form action="board_write1_ok.jsp" method="post" name="wfrm" >
<!-- input 태그의 button 타입 -->
<input type="button" id="wbtn" value="등록" class="btn_write btn_txt01" style="cursor: pointer;" onclick="checkfrm()" />
BoardEx01 > simple1
코드를 작성하기 전에 먼저 jdbc 드라이버를 추가하고 커넥션 풀 사용을 위한 context.xml을 추가한다.
게시판 페이지 코드 작성 순서는 다음과 같다.
- write
- list
- view
- delete
- modify
'빅데이터 플랫폼 구축을 위한 자바 개발자 양성과정' 카테고리의 다른 글
12/24 - JSP(5) : 최신글 표시, 페이징 있는 게시판 만들기 (0) | 2021.01.04 |
---|---|
12/23 - JSP(4) : 게시판 만들기 (0) | 2021.01.04 |
12/21 - JSP(2) : JSP 문법 <%@ %>,<% %>, <%= %> 와 request, 달력만들기(Date, Calendar) (0) | 2020.12.22 |
12/18 - JSP(1) : 이클립스 + 톰캣 설정, 작성, 실행 방법 (0) | 2020.12.22 |
12/14 - Java로 메일 발송 (텍스트, html, 이미지, 첨부파일) (0) | 2020.12.15 |