개발툴은 이클립스, db는 MySQL, 서버는 Tomcat 이용
이클립스에서
✓ jdbc 드라이버로드
✓ tomcat 설정
✓ web dynamic project 생성가능한상태
✓ 서블릿생성 가능한상태
이어있어야함
♣︎ 규칙
1.html화면이 필요한 것
2.html화면이 필요없는것,기능만 존재
이 둘로 나뉘고 네이밍시
1은 login.jsp
2는 login에서 _ok 를 붙여준다 login_ok.jsp
또한 빠른 성능을위해 나중에 ok 인 애들은 서블릿화를 해줘야한다
그래서 핵심은
우선 전부 jsp로 만들어주고
나중에 ok들만 서블릿화해준다
다이나믹웹프로젝트를 생성하면 안에
이렇게 자동으로 생성됨
미리말하자면 코드들은 모두 src안에 넣는데
더 자세히 알려드리겠음
main 안에는
java디렉터리와 webapp디렉터리가 존재
1. java디렉터리안에는 뭐가들어갈까??
서블릿파일
- 확장자가 .java
- java디렉토리 안에 바로 넣어도되거나 패키지를 만들어서 넣으면된다
- '_ok'로 끝나는 기능만 들어있는 파일들
2. webapp안에는???
jsp파일
- html 화면이 필요한 페이지
- _ok로 끝나는 기능만 필요한 페이지들도 일단 처음엔 다 jsp로 구현해야한다!
전체적인 구성을 보자
전체 구성은 이렇다!
코드time
0. db연결
jdbc 싱글톤패턴 - Dbconn.java
Dbconn.java (#싱글톤패턴)
package com.koreait.db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class Dbconn {
private static Connection conn; //메모리에 계속 살아있을것임
public static Connection getConnection() throws SQLException, ClassNotFoundException {
String url = "jdbc:mysql://localhost/aidev?useSSL=false&allowPublicKeyRetrieval=true";
String uid = "root";//db계정 아이디
String upw = "1111";//db계정 비번
Class.forName("com.mysql.cj.jdbc.Driver");
conn = DriverManager.getConnection(url, uid, upw);
return conn;
}
}
1. 로그인
로그인 - login.jsp
로그인 체크 - login_ok.jsp
mysql table - tb_member
mysql에서 tb_member 생성
CREATE TABLE `tb_member` (
`mem_userid` varchar(20) NOT NULL,
`mem_userpw` varchar(256) NOT NULL,
`mem_username` varchar(20) NOT NULL,
`mem_hp` varchar(20) NOT NULL,
`mem_email` varchar(50) NOT NULL,
`mem_hobby` varchar(100) DEFAULT NULL,
`mem_ssn1` varchar(6) NOT NULL,
`mem_ssn2` varchar(7) NOT NULL,
`mem_zipcode` varchar(5) DEFAULT NULL,
`mem_address1` varchar(100) DEFAULT NULL,
`mem_address2` varchar(100) DEFAULT NULL,
`mem_address3` varchar(100) DEFAULT NULL,
`mem_regdate` datetime DEFAULT CURRENT_TIMESTAMP,
`mem_gender` enum('남자','여자') DEFAULT NULL,
PRIMARY KEY (`mem_userid`,`mem_username`),
UNIQUE KEY `mem_userid` (`mem_userid`)
);
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String userid = null;
if(session.getAttribute("userid") != null){
userid = (String)session.getAttribute("userid");
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>세션으로 구현한 로그인</title>
</head>
<body>
<h2> 세션으로 구현한 로그인</h2>
<%
if(userid == null){
%>
<form method="post" action="./login_ok.jsp">
<p>아이디: <input type = "text" name = "userid"></p>
<p>비밀번호: <input type = "password" name = "userpw"></p>
<p><button>로그인</button></p>
</form>
<p>아직 회원이 아니신가요? <a href="./member.jsp">회원가입</a></p>
<%
} else{
%>
<h3><%=userid%>님 환영합니다 !!!!</h3>
<p><a href="./logout.jsp"> 로그아웃 </a> | <a href='./info.jsp'>정보수정</a> | <a href="./board/list.jsp"> 게시판</a></p>
<%
}
%>
</body>
</html>
login_ok.jsp
<%@ page import="java.sql.PreparedStatement"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import ="java.sql.*" %>
<%@ page import = "com.koreait.db.Dbconn" %>
<%
String userid = request.getParameter("userid");
String userpw = request.getParameter("userpw"); //name값으로 인식
Connection conn = null;
PreparedStatement pstmt;
ResultSet rs = null;
try{
conn = Dbconn.getConnection();
if(conn != null){
String sql = "select mem_userid, mem_username from tb_member where mem_userid=? and mem_userpw=sha2(?,256)";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1,userid);
pstmt.setString(2,userpw);
rs = pstmt.executeQuery();
if(rs.next()){
session.setAttribute("userid",userid);
session.setAttribute("name",rs.getString("mem_username"));
%>
<script>
alert('로그인 되었습니다');
location.href="./login.jsp" //refresh가됨 새로고침이되는것임
</script>
<%
}else{
%>
<script>
alert('아이디 또는 비밀번호를 확인하세요');
history.back(); // 캐쉬가남음 캐쉬에 있는 정보를 가져다가 앞으로갓다가 뒤로갓다가 할수있는것이라서
</script>
<%
}
}
}catch(Exception e){
e.printStackTrace();
}
%>
2.회원가입
회원가입은 유효성체크가 필요하다! 자바스크립트로 구현가능! - regist.js
이미 가입되어있다면 가입불가 => db조회해서 아이디가 존재하면 가입취소 - idcheck.jsp (ajax사용)
member.jsp (주소는 daum api를 사용)
https://postcode.map.daum.net/guide
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>회원가입</title>
<script defer src="./js/regist.js"></script>
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script>
function sample6_execDaumPostcode() {
new daum.Postcode({
oncomplete: function(data) {
// 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.
// 각 주소의 노출 규칙에 따라 주소를 조합한다.
// 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
var addr = ''; // 주소 변수
var extraAddr = ''; // 참고항목 변수
//사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
addr = data.roadAddress;
} else { // 사용자가 지번 주소를 선택했을 경우(J)
addr = data.jibunAddress;
}
// 사용자가 선택한 주소가 도로명 타입일때 참고항목을 조합한다.
if(data.userSelectedType === 'R'){
// 법정동명이 있을 경우 추가한다. (법정리는 제외)
// 법정동의 경우 마지막 문자가 "동/로/가"로 끝난다.
if(data.bname !== '' && /[동|로|가]$/g.test(data.bname)){
extraAddr += data.bname;
}
// 건물명이 있고, 공동주택일 경우 추가한다.
if(data.buildingName !== '' && data.apartment === 'Y'){
extraAddr += (extraAddr !== '' ? ', ' + data.buildingName : data.buildingName);
}
// 표시할 참고항목이 있을 경우, 괄호까지 추가한 최종 문자열을 만든다.
if(extraAddr !== ''){
extraAddr = ' (' + extraAddr + ')';
}
// 조합된 참고항목을 해당 필드에 넣는다.
document.getElementById("sample6_extraAddress").value = extraAddr;
} else {
document.getElementById("sample6_extraAddress").value = '';
}
// 우편번호와 주소 정보를 해당 필드에 넣는다.
document.getElementById('sample6_postcode').value = data.zonecode;
document.getElementById("sample6_address").value = addr;
// 커서를 상세주소 필드로 이동한다.
document.getElementById("sample6_detailAddress").focus();
}
}).open();
}
</script>
</head>
<body>
<h2>회원가입</h2>
<form action="member_ok.jsp" name="regform" id="regform" method="post" onsubmit="return sendit()">
<!-- onsubmit 값이 false이면 submit안함! -->
<input type="hidden" name="isIdCheck" id="isIdCheck" value="n">
<p>아이디: <input type="text" name="userid" id="userid" maxlength="20" onkeydown="idModify()">
<input type="button" id="btnIdCheck" value= "중복체크" onclick="clickBtn()">
</p>
<p id = "checkmsg"></p>
<p>비밀번호: <input type="text" name="userpw" id="userpw" maxlength="20" ></p>
<p>비밀번호 확인: <input type="text" name="userpw_re" id="userpw_re" maxlength="20" ></p>
<p>이름: <input type="text" name="name" id="name"></p>
<p>휴대폰번호: <input type="text" name="hp" id="hp"></p>
<p>이메일: <input type="text" name="email" id="email"></p>
<p>성별: <label>남자<input type="radio" name="gender" value="남자" checked></label> <label>여자<input type="radio" name="gender" value="여자"></label></p>
<p>취미: <label>등산<input type="checkbox" name="hobby" value="등산"></label>
<label>게임<input type="checkbox" name="hobby" value="게임"></label>
<label>운동<input type="checkbox" name="hobby" value="운동"></label>
<label>드라이브<input type="checkbox" name="hobby" value="드라이브"></label>
<label>독서<input type="checkbox" name="hobby" value="독서"></label></p>
<p>주민등록번호<input type="text" name="ssn1"><input type="text" name="ssn2">
<p>우편번호: <input type="text" id="sample6_postcode" name="zipcode" maxlength="5"><button type="button" onclick="sample6_execDaumPostcode()">검색</button></p>
<p>주소: <input type="text" name="address1" id="sample6_address"></p>
<p>상세주소: <input type="text" name="address2" id="sample6_detailAddress"></p>
<p>참고항목: <input type="text" name="address3" id="sample6_extraAddress"></p>
<p><button>가입완료</button> <button type="reset">다시작성</button> </p>
</form>
<p>이미 회원이신가요? <a href="login.jsp">로그인</a></p>
</body>
</html>
regist.js(유효성검사)
function sendit(){
const userid = document.getElementById('userid');
const isIdCheck = document.getElementById('isIdCheck');
const userpw = document.getElementById('userpw');
const userpw_re = document.getElementById('userpw_re');
const name = document.getElementById('name');
const hp = document.getElementById('hp');
const email = document.getElementById('email');
const hobby = document.getElementsByName('hobby');
// 정규 표현식
const expIdText = /^[A-Za-z\d]{4,20}$/;
const expNameText = /[가-힣]+$/;
const exeHpText = /^\d{3}-\d{3,4}-\d{4}$/;
const expEmailText = /^[A-Za-z0-9\-\.]+@[A-Za-z0-9\-\.]+\.[A-Za-z0-9]+$/;
const expPwText =/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*])[A-Za-z\d!@#$%^&*]{8,}/;
if(userid.value ==''){
alert('아이디를 입력하세요');
userid.focus();
return false;
}
if(!expIdText.test(userid.value)){
alert('아이디는 4자 이상 20자 이하의 대소문자로 시작하는 조합입니다')
userid.focus();
return false;
}
if(isIdCheck.value == 'n'){
alert('아이디 중복체크 버튼을 눌러주세요');
return false;
}
if(userpw.value ==''){
alert('비밀번호를 입력하세요');
userpw.focus();
return false;
}
if(!expPwText.test(userpw.value)){
alert('비밀번호 형식을 확인하세요\n소문자,대문자,숫자,특수문자 1개씩 꼭 입력해야합니다');
userpw.focus();
return false;
}
if(userpw.value != userpw_re.value){
alert('비밀번호와 비밀번호 확인의 값이 다릅니다')
userpw_re.focus();
return false;
}
if(name.value ==''){
alert('이름을 입력하세요');
name.focus();
return false;
}
if(!expNameText.test(name.value)){
alert('이름은 한글로 입력하세요');
name.focus();
return false;
}
if(!exeHpText.test(hp.value)){
alert('휴대폰번호 형식을 확인하세요\n하이픈(-)을 포함해야합니다');
hp.focus();
return false;
}
if(!expEmailText.test(email.value)){
alert('이메일 형식을 확인하세요')
email.focus();
return false;
}
let count = 0;
for(let i in hobby){
if(hobby[i].checked){
count++;
}
}
if(count == 0){
alert('취미는 적어도 하나 이상 선택하세요');
return false;
}
return true;
//return true
//return false
}
function clickBtn(){
const isIdCheck = document.getElementById('isIdCheck');
const xhr = new XMLHttpRequest();
const userid = document.getElementById('userid').value;
xhr.open('get','idcheck.jsp?userid=' + userid, true);
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200){
const result = xhr.responseText;
if(result.trim() == "ok"){//trim하는이유 문자앞뒤로 공백이저절로딸려오는경우가있음
document.getElementById('checkmsg').innerHTML = "<b style='color:blue'>사용할 수 있는 아이디</b>";
isIdCheck.value = 'y';
}else{
document.getElementById('checkmsg').innerHTML = "<b style='color:red'>사용할 수 없는 아이디</b>";
}
}
}
}
function idModify(){
const isIdCheck = document.getElementById('isIdCheck');
isIdCheck.value = 'n';
document.getElementById('checkmsg').innerHTML="";
}
idcheck.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.sql.*"%>
<%@ page import="com.koreait.db.Dbconn"%>
<%
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs =null;
String userid= request.getParameter("userid");
try{
conn = Dbconn.getConnection();
if(conn != null){
String sql = "select mem_userid from tb_member where mem_userid=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1,userid);
rs = pstmt.executeQuery();
if(rs.next()){
out.print("no"); //가입을 할수 없는 경우
}else{
out.print("ok"); //가입을 할수 있는 경우
}
}
}catch(Exception e){
e.printStackTrace();
}
%>
3. 로그아웃
로그아웃은 간단
그냥 세션을 없애면 됨
logout.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
session.invalidate();
%>
<script>
alert('logout되었습니다');
location.href='login.jsp';
</script>
서버xml 에 등록된 세션유지시간에 따라서
아이디정보세션이 남아있는동안 로그인상태가 유지
'웹 개발 > 🎆 JSP' 카테고리의 다른 글
JSP | JSP를이용한 홈페이지구현 - 게시판 (0) | 2022.11.27 |
---|---|
JSP | JSP를이용한 홈페이지구현 - 세션체크, 회원정보수정 (0) | 2022.11.27 |
JSP | include,exception,pageContext,ajax (0) | 2022.11.21 |
JSP | cookie,session,servlet (0) | 2022.11.20 |
JSP | 디렉티브태그,스크립트릿,표현문,선언문,get,post,getParameter (1) | 2022.11.17 |