728x90

프로젝트를 진행 중에 한 리스트에서 연속된 두 VO를 사용해야 하는데

어떻게 할 수 있을까 고민하다가 생각난 것을 적용해보니 잘 되길래 공유해봅니다.

 

JSTL core의 foreach 태그에는 여러 속성이 있지만 주로 사용하는 방법은 아래와 같습니다.

<c:foreach var="vo" items="${List}">
	<div> ${vo.title} </div>
</c:foreach>

 이렇게 되면 items에 있는 변수가 인덱스 순으로 vo에 담겨서 진행하게 되는데 여기에 속성 몇 개를 추가하면 됩니다.

 

<c:foreach var="vo" items="${List}" varStatus="status" step="2">
	<div> ${vo.title} </div>
    <div> ${List[status.index + 1].title} </div>
</c:foreach>

varStatus 속성으로 설정한 status로 현재 반복문의 인덱스를 받아올 수 있습니다.

step 속성으로는 반복문을 첫 번째 항목부터 시작하여 스텝마다 진행한다는 뜻입니다.

이를 활용하면 세 개씩도 한 반목문 안에 사용할 수 있습니다.

 

예를 들어 아래와 같이 10까지의 숫자가 들어있는 리스트가 있다고 했을 때

String[] list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

아래의 코드를 사용하면 1, 3, 5 ,7, 9만 출력합니다.

<c:foreach var="num" items="${list}" varStatus="status" step="2">
	<div> ${num} </div>
</c:foreach>

여기서 step 속성만 3으로 바꾸면 1, 4, 7, 10이 출력됩니다.

728x90
728x90

만들려는 사이트가 주식 커뮤니티인 만큼 자신의 자산 추이를 한눈에 볼 수 있는 그래프를 추가하고 싶었는데

그 방법으로 구글차트를 이용해 보겠습니다.

 

 

그래프 하단에 날짜를 지정하고 자산을 입력한 다음 추가 버튼을 누르면 그 정보가 데이터베이스 입력되고 동시에 

그래프와 하단의 목록에 뜨게됩니다.

우선 구글 차트에 들어가서 원하는 차트 타입을 누릅니다.

https://developers.google.com/chart/interactive/docs

저는 선 그래프를 이용했기 때문에 line chart로 설명을 하겠습니다.

왼쪽에 line charts를 눌러주시고 Code it yourself on JSPFiddle을 누르면

예제 코드를 볼 수 있고 데이터도 바꾸면서 확인할 수 있습니다. 

 

html의 script를 본인 html head태그 안에 넣어주시고 

div 태그는 그래프가 그려질 장소이니 그래프를 보여줄 곳에 넣어주면 됩니다.

 

google.charts.load('current', {packages: ['corechart', 'line']});
google.charts.setOnLoadCallback(drawchart);
function drawchart() {
      var data = new google.visualization.DataTable();
      data.addColumn('number', 'X');
      data.addColumn('number', 'Dogs');

      data.addRows([ ]);

      var options = { };

      var chart = new google.visualization.LineChart(document.getElementById('chart_div'));

      chart.draw(data, options);
    }

구글 차트의 기본적인 구조입니다. 

차트를 로드하고 .setOnLoadCallback(); 함수로 html이 전부 로드된 후 매개변수에 들어간 함수를 호출합니다.

data 변수에 데이터 테이블을 생성하고 .addColumn으로 열을 추가합니다

열의 데이터 타입은 많이 있으니 직접 검색해보시면 됩니다.  

.addRows는 만들어진 열에 데이터를 추가하는 것으로 배열 형식으로 추가할 수 있습니다.

options는 그래프의 옵션을 정하는 변수로 x축, y축, 그래프 사이즈 등 여러 옵션을 설정할 수 있습니다.

chart에 그래프가 그려질 곳을 설정하고 .draw로 데이터와 옵션을 추가해 그립니다.

 

저는 oracle db에 있는 데이터를 받아와 출력할 생각이기 때문에 .addRow만 좀 다르게 해 주면 됩니다.한 번에 그리는 방법도 있을 수 있는데 저는 제 실력이 부족해서 한번에 데이터를 받아와 그리는 것을 못했습니다.그래서 html이 전부 그려지고  빈 차트를 그린 후에 거기에 데이터를 추가하는 방법을 선택했습니다.

google.charts.load('current', {packages: ['corechart', 'line'], callback: drawBasic});	
google.charts.setOnLoadCallback(addData);
var data;
var chart;
var options;
function drawBasic() { 
      data = new google.visualization.DataTable();
      data.addColumn('datetime', 'year');
      data.addColumn('number', 'Property');

      data.addRows([
      ]);
      options = {
              width:'100%'
      }

      chart = new google.visualization.LineChart(document.getElementById('chart_div'));
      chart.draw(data, options);
    }

먼저 빈 차트를 그리는 코드입니다.

변수를 두 번째에 그릴 때도 사용할 것이기 때문에 함수 밖에 변수를 설정해줍니다.

저는 x축을 날짜별로 보여줄 거라 데이터 타입을 datetime으로 설정했습니다.

data 행은 두 번째 그릴 때 추가할 거라 빈 값으로 설정해주고 그려주면 끝납니다.

 

var year = [];
var month = [];
var day = [];
var value = [];	 	
<%for(GraphVO gv : glist){%>
year.push(<%=gv.getYear()%>);
month.push(<%=gv.getMonth()%>);
day.push(<%=gv.getDay()%>);
value.push(<%=gv.getMoney()%>);
<% }%>
var len = year.length;
function addData(){
    var arr = new Array();
    for(let i = 0; i<len; i++){
         arr = [new Date(year[i],month[i]-1,day[i]),value[i]];
         data.addRow(arr);
     }
    options = {
            pointSize: 5,
            width:'100%',
            hAxis: {
              title: 'Time',
              format:'yy-MM',
              ticks: [new Date(year[0],month[0]-1,day[0]),new Date(year[len-1],month[len-1]-1,day[len-1])]
            },
            explorer: { axis: 'horizontal' }
          };
    chart.draw(data, options);
}

데이터를 전부 출력하기 위해 컨트롤러에서 받아온 데이터를 변수 배열에 추가해주시고요

for문으로 위에 설정해둔 data 변수에 .addRow해서 일일이 추가해줍니다.

원하는 옵션도 추가해주시고 다시 그려주면 끝납니다.

 

더 쉬운 방법도 물론 있을 수 있으나 처음 사용하다 보니 미숙해서

빈 차트에 새로운 데이터를 덮어 씌우는 방법을 사용해봤습니다.

 

 

아래는 전체 코드입니다.

전체 코드 - https://github.com/seohakman/stockCommu/blob/main/src/main/webapp/member/FinancialGraph.jsp

 

GitHub - seohakman/stockCommu: 커뮤니티 사이트 만들기/ 개인 프로젝트

커뮤니티 사이트 만들기/ 개인 프로젝트. Contribute to seohakman/stockCommu development by creating an account on GitHub.

github.com

 

728x90
728x90

글쓰기 페이지는 로그인했을 때만 이동할 수 있게 만들어뒀다.

제목과 내용을 작성하고 첨부파일을 하나 넣을 수 있다.

 

 

아래는 jsp에서 컨트롤러로 값을 보내는 코드

이미지 사이즈를 재설정하는 imgscalr-lib와 첨부파일 기능을 만들기 위해서 cos.jar 라이브러리를 다운로드하여 사용했다.

파일을 업로드하기 위해서 form enctype 속성을 "multipart/form-data"로 설정해주었다.

이렇게 설정해주면 폼 값을 보낼때 인코딩하지 않고 값을 보낸다.

// 컨트롤러로 내용을 보낸다. 
<script>
    function mainSubmit(){
        document.fm.action="<%=request.getContextPath()%>이동할 컨트롤러";
        document.fm.method="post";
        document.fm.enctype="multipart/form-data"; 
    }
</script>
<form name=fm>
<table>
    <thead>
        <tr>
            <th><input id="subject" name="subject" type="text" placeholder="제목을 입력하세요" required></th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><textarea id="content" name="content" placeholder="내용을 입력하세요" required></textarea></td>
        </tr>
        <tr>
            <td id="filePath"> <input name="filename" type="file"> </td>
        </tr>
    </tbody>
    <tfoot>
        <tr>
            <td>
                <button type="submit" onclick="mainSubmit()">등록</button>
                <button type="button" onclick="history.back();">취소</button>
            </td>
        </tr>
    </tfoot>
</table>
</form>

아래는 컨트롤러에서 글을 DB에 등록하는 코드

sizeLimit는 등록하는 파일의 용량을 제한한다. 이미지 파일일 경우 이렇게 하면 너무 크다...

이전에 form에서 데이터 타입을 multipart/form-data 보냈기 때문에 이전의 request 영역에서 값을 읽어오는 것과 다르게

MultipartRequest 객체를 생성해 여기서 값을 읽는다.

//작성한 글을 DB에 넣는다.
int sizeLimit = 1024*1024*15;
MultipartRequest multi = new MultipartRequest(request, saveFullPath, sizeLimit, "utf-8", new DefaultFileRenamePolicy());

HttpSession session = request.getSession();
String subject = multi.getParameter("subject");
String content = multi.getParameter("content").replace("\r\n", "<br>");
String id = (String) session.getAttribute("id");
int midx = (int)session.getAttribute("midx");

// 열거자에 저장될 파일을 담는 객체를 생성한다.
Enumeration files = multi.getFileNames();
// 담긴 파일객체의 파일 이름을 얻는다.
String file = (String)files.nextElement();
//저장되는 파일 이름
String fileName = multi.getFilesystemName(file);
//원래 파일 이름
String originFileName = multi.getOriginalFileName(file);

MainDAO mdo = new MainDAO();
int value = mdo.insertMain(subject, content, id, midx, fileName);
PrintWriter out = response.getWriter();
if(value == 1) {
    response.sendRedirect(pj+"/main/index.do");
}else{
    out.println("<script>alert('글쓰기 실패');</script>");
}

아래는 DAO의 입력 메서드

public int insertMain(String subject, String content, String ID, int midx, String fileName) {
    // DB에 글을 넣는다.
    int value = 0;
    String sql = "insert into main(bidx,subject,content,midx,writer,viewcount,likecount,filename)" 
    	+ "values(bidx_main.nextval,?,?,?,?,?,?,?)";

    try {
        pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, subject);
        pstmt.setString(2, content);
        pstmt.setInt(3, midx);
        pstmt.setString(4, ID);
        pstmt.setInt(5, 0);
        pstmt.setInt(6, 0);
        pstmt.setString(7, fileName);
        value = pstmt.executeUpdate();

    } catch (SQLException e) {
        e.printStackTrace();
    }
    return value;
}
728x90
728x90

제가 만든 커뮤니티 사이트의 로그인 페이지 입니다. 

기본적인 로그인 기능과 아이디/ 비밀번호 찾기 기능도 구현했습니다.

로그인 버튼으로 데이터를 전송하려면 아이디와 비밀번호 input 박스에 데이터를 필수적으로 작성해야 합니다.

아래는 로그인 기능의 jsp 코드입니다.

<script>
	function clickLogin(){
		document.fm.action="#이동할 컨트롤러";
		document.fm.method="post";
	}
</script>
<form name=fm>
<table>
    <tr>
      <td>아이디 :</td>
      <td><input type="text" required name="ID"></td>
    </tr>
    <tr>
      <td>비밀번호 :</td>
      <td><input type="password" required name="PWD"></td>
    </tr>
    <tr>
      <td colspan="2">
        <a href="#이동할 컨트롤러">아이디찾기</a>  /
        <a href="#이동할 컨트롤러">비밀번호찾기</a>
      </td>
    </tr>
    <tr>
      <td colspan="2"><a href="#이동할 컨트롤러">회원가입</a></td>
    </tr>
    <tr>
      <td colspan="2">
        <button type="submit" id="login-btn" onclick="clickLogin()"><span>로그인</span></button>
      </td>
    </tr>
</table>
</form>

아래는 servlet 컨트롤러에서 받아오는 파라미터와 로그인 기능을 수행하는 메서드입니다.

// 컨트롤러
// 로그인 버튼이 눌렷을때 로그인 기능을 동작시킨다.
// 1. 넘어온 값을 받는다.
String id = request.getParameter("ID");
String pwd = request.getParameter("PWD");
// 2.처리 (쿼리실행)
MemberDAO md = new MemberDAO();
MemberVO mv = null;
mv = md.memberLogin(id, pwd);
PrintWriter out = response.getWriter();

// 세션에 로그인할 때 받아온 값을 저장해 다른 페이지로 이동할 때에도 
// 로그인 상태를 유지하게한다.
HttpSession session = request.getSession();
if(mv != null) {
    session.setAttribute("midx", mv.getMidx());
    session.setAttribute("id", mv.getId());
    session.setAttribute("name", mv.getName());
    session.setAttribute("point", mv.getPoint());
    session.setAttribute("superMember", mv.getSupermember());
    session.setAttribute("password", mv.getPwd());
    // 3.이동
    // saveUrl이라는 로그인 페이지로 이동하기 전 url이 있을경우 그 페이지로 이동
    // 없을 경우 인덱스 페이지로 이동
    if(session.getAttribute("saveUrl") != null) {
        response.sendRedirect((String)session.getAttribute("saveUrl"));
    }else {
        response.sendRedirect(request.getContextPath()+"/main/index.do");
    }
}else {
    out.println("<script>alert('아이디, 비밀번호가 틀렸거나 존재하지 않는 회원입니다.');location.href='"+request.getContextPath()+"/member/memberLogin.do'</script>");

}

// DB에 로그인 기능을 실행하는 메서드
public MemberVO memberLogin(String ID, String PWD) {
    // id와 pwd를 파라미터로 받아온다.
    String sql = "select * from member where id = ? and pwd =?";
    ResultSet rs = null;
    MemberVO mv = null;
    try {
        pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, ID);
        pstmt.setString(2, PWD);
        rs = pstmt.executeQuery();

        if(rs.next()) {
            mv = new MemberVO();
            mv.setMidx(rs.getInt("midx"));
            mv.setName(rs.getString("name"));
            mv.setId(rs.getString("id"));
            mv.setPwd(rs.getString("pwd"));
            mv.setSupermember(rs.getString("supermember"));
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }finally {
        try {
            rs.close();
            pstmt.close();
            conn.close();
        } catch (SQLException e) {

            e.printStackTrace();
        }
    }

    return mv;
}

 


아이디 찾기와 비밀번호 찾기는 같은 로직을 가지고 있다고 보면 됩니다.

아이디를 찾을 때 DB에서 이름과 이메일이 일치하는 값이 있을 경우에 ID를 받아와서 보여주면 되는데

비밀번호의 경우 일치하는 값을 추가하거나 일치했을 때 새로운 비밀번호를 설정하게 하는 등 기존의 로직에서 새로운 방법을 추가하는 것입니다.

jsp에서 form으로 이름과 이메일을 컨트롤러에 파라미터로 넘겨줍니다.

컨트롤러에서는 받은 파라미터를 다시 변수로 설정하고 만들어둔 메서드를 통해

DB와 일치하는 값이 있는지 비교하고 일치하는 값이 있을 경우 결과값을 받아옵니다.

이 값을 다시 웹페이지에 출력해주면 됩니다. 

//아이디 찾기 jsp
<script>
	function findIDbtn(){
		document.fm.action="<%=request.getContextPath()%>이동할 컨트롤러";
		document.fm.method="post";
	}
</script>
<form name=fm>
<table>
    <tr>
      <td>이름 :</td>
      <td><input type="text" name="name" required></td>
    </tr>
    <tr>
      <td>이메일 :</td>
      <td><input type="text" name="email" required></td>
    </tr>
    <tr>
      <td colspan="2">
        <button type="submit" id="findID-btn" onclick="findIDbtn()"><span>아이디 찾기</span></button>
      </td>
    </tr>
</table>
</form>

아래는 컨트롤러와 메서드 코드

sql 구문을 통해 DB에서 값을 검색하는데 여기서 table 이름과 column만 본인걸로 바꿔서 적용하면 될겁니다.

// 컨트롤러
// 아이디찾기 버튼을 클릭했을 때
PrintWriter out = response.getWriter();
String name = request.getParameter("name");
String email = request.getParameter("email");

MemberDAO md = new MemberDAO();
MemberVO mv = null;
mv = md.findID(name, email); // 아이디를 찾는 메서드
if(mv != null) {
    out.println("<script>alert('"+name+"님의 아이디는 "+mv.getId()+"입니다.');"
            + "location.href='"+request.getContextPath()+"이동할 컨트롤러'</script>");
}else {
    out.println("<script>alert('아이디가 존재하지 않습니다.');"
            + "location.href='"+request.getContextPath()+"이동할 컨트롤러'</script>");
}

//메서드
public MemberVO findID(String name, String email) {
    //아이디 찾기 메서드
    String sql = "select * from member where name = ? and email =?";
    ResultSet rs = null;
    MemberVO mv = null; // 회원정보를 저장하는 객체
    try {
        pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, name);
        pstmt.setString(2, email);
        rs = pstmt.executeQuery();

        if(rs.next()) {
            mv = new MemberVO();
            mv.setMidx(rs.getInt("midx"));
            mv.setId(rs.getString("id"));
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }finally {
        try {
            rs.close();
            pstmt.close();
            conn.close();
        } catch (SQLException e) {

            e.printStackTrace();
        }
    }

    return mv;
}

 

728x90
728x90

커뮤니티 사이트를 운영하려면 먼저 회원관리가 필요하겠죠?

때문에 회원가입을 할 수 있는 페이지를 먼저 만들어 보겠습니다.

그전에 앞서 sql을 사용할 수 있는 DB에 회원 테이블을 만들어줍니다. 

회원 테이블

저는 회원번호(midx), 아이디, 비밀번호, 이메일, 회원 가입일, 포인트, 삭제 여부(delyn), 관리자 권한을 회원 테이블 칼럼으로 설정했습니다.  

회원가입 페이지에서 기본적인 로직은 먼저 빈 input값이 없는지 확인합니다.

이후 비밀번호 두 값이 일치하는지 확인합니다. 아이디 중복확인의 경우 가입자 본인이 클릭해야 작동되는데

누르지 않고 생성버튼을 누르더라도 생성 버튼을 눌렀을 때 중복확인 기능이 먼저 작동해서

중복된 아이디가 DB에 있을 경우 회원가입 처리가 되지 않고 경고창을 띄웁니다.

 

<script type="text/javascript">
	// 두 비밀번호 입력값이 일치하는지 확인 후 데이터 전송
	function check() {
		if(document.fm.PWD.value != document.fm.PWDCheck.value){
			alert("비밀번호가 일치하지 않습니다.");
			document.fm.PWDCheck.focus();
			return;
		}
		document.fm.action = "<%=request.getContextPath()%>/member/memberJoinAction.do";
		document.fm.method = "post";
	}
	// DB에 중복 된 아이디가 있는지 확인하는 함수
    // if 절은 없어도 됨 input에 required를 적어놨기 때문에
	function checkedID(){
		if(document.fm.ID.value == ""){
			alert("아이디를 입력하세요.");
			document.fm.ID.focus();
			return;
		}
		
		document.fm.action = "<%=request.getContextPath()%>/member/idCheckAction.do";
		document.fm.method = "post";
		document.fm.submit();
	}
</script>

<!-- main content -->
    <section id="home">
      <h1 id="homeTitle"> 회 원 가 입 </h1>
	  <form name=fm>
	  <table >
        <tr>
          <td>아이디 :</td>
          <td>
			<input type="text" name="ID" required> 
			<button type="button" class="check" onclick="checkedID()"> 중복확인 </button>
		  </td>
        </tr>
		<tr>
          <td>이름 :</td>
          <td><input type="text" name="name" required></td>
        </tr>
        <tr>
          <td>비밀번호 :</td>
          <td><input type="password" name="PWD" required></td>
        </tr>
		<tr>
          <td>비밀번호 확인 :</td>
          <td><input type="password" name="PWDCheck" required></td>
        </tr>
        <tr>
          <td>이메일 :</td>
          <td><input type="email" name="email" required></td>
        </tr>
        <tr>	
          <td colspan="2" class="tdJoin">
            <button type="submit" id="join-btn" onclick="check()"><span>생성</span></button>
          </td>
        </tr>
      </table>
      </form>
    </section>

중복 확인을 누를경우 checkedID() 함수가 작동되고 멤버 컨트롤러  idCheckAction.do로 파라미터가 넘어옵니다.

//servlet MemberController로 id중복확인 
//DB에 회원가입하려는 ID와 같은 ID가 있는지 확인한다.
String ID = request.getParameter("ID");

MemberDAO md = new MemberDAO(); // 메서드 집합 class
boolean bl = md.checkedID(ID);	// 중복확인 메서드
PrintWriter out = response.getWriter();
if(bl) {
    out.println("<script>alert('중복된 아이디가 있습니다.');location.href=
    '"+request.getContextPath()+"/member/memberJoin.do'</script>");
}else{
    out.println("<script>alert('사용해도 되는 아이디입니다.');location.href=
    '"+request.getContextPath()+"/member/memberJoin.do'</script>");
}

// MemberDAO class의 id중복확인 메서드
// private Connection conn;
// private PreparedStatement pstmt; 미리 전역번수로 설정한 변수들
public boolean checkedID(String ID) {
    ResultSet rs = null;
    //입력받은 ID와 같은 ID가 DB에 있는지 조건절로 확인한다.
    String sql = "select id from member where id = ?";
    try {
        pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, ID);
        rs = pstmt.executeQuery();
        if(rs.next()) {
            return true;
        }
    }catch(Exception e) {
        e.printStackTrace();
    }

    try {
        rs.close();
        pstmt.close();
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return false;
}

생성 버튼을 눌렀을 경우 로직

//MemberController
//DB에 회원정보를 추가한다.
String ID = request.getParameter("ID");
String PWD = request.getParameter("PWD");
String name = request.getParameter("name");
String email = request.getParameter("email");

MemberDAO md = new MemberDAO();
boolean bl = md.checkedID(ID);  //id 중복확인을 누르지않고 회원가입을 하는 경우가 있으므로 
PrintWriter out = response.getWriter();
if(bl){
    out.println("<script>alert('중복된 아이디입니다.');location.href=
    '"+request.getContextPath()+"/member/memberJoin.do'</script>");
}else {
	// 중복된 아이디가 없는 경우 미리 생성된 DB테이블에 값을 넣는 메서드
    int value = md.insertMember(ID, PWD, name, email);
    if(value==1){
        response.sendRedirect(pj+"/main/index.do");
    }else{
       response.sendRedirect(pj+"/member/memberJoin.do");
    }
    
//MemberDAO class의 회원가입 메서드
//DB에 member로 테이블을 만들어 뒀다.
public int insertMember(String ID,String PWD,String name,String email){
    int value=0;		
    String sql="insert into member(midx,ID,PWD,name,email,point)"
            + "values(midx.nextval,?,?,?,?,?)";
    try{
    pstmt = conn.prepareStatement(sql);
    pstmt.setString(1, ID);
    pstmt.setString(2, PWD);
    pstmt.setString(3, name);
    pstmt.setString(4, email);
    pstmt.setInt(5, 0);
    value = pstmt.executeUpdate();

    }catch(Exception e){
        e.printStackTrace();
    }

    return value;
}

 

728x90
728x90

저번 시간에 자바 클래스까지 구상했으니 이번에는 초기화면을 만들어 보겠습니다.

우선 만들어본 초기화면을 보여드리고 간단하게 설명하겠습니다.

왼쪽 상단에 stocksophia를 클릭하면 index 페이지로 이동하게 설정해뒀습니다.

로그인 누르면 로그인으로 이동하고 옆에 아이콘을 클릭할 경우 이동할 수 있는 카테고리가 등장합니다. 

로그인한 경우와 아닌 경우 이동할 수 있는 카테고리가 다릅니다.

로그인 안했을 때
로그인 했을 때

해당 아이디는 관리자 권한까지 가지고 있어서 관리 페이지까지 보입니다.

로그인하지 않았을 경우 게시판의 글을 클릭할 수 없고 글쓰기 버튼이 보이지 않습니다.

게시판 글 자체는 가장 최근에 작성한 글 순서대로 DB에서 가져오고 검색과 페이징 기능을 추가했습니다.

페이지 자체는 반응형 웹사이트로 만들었는데 최대 사이즈는 1200px로 설정해뒀습니다.

 


저는 이 페이지를 만들면서 토글 버튼을 누르면 이동할 수 있는 카테고리를 보여주는 게 가장 어려웠습니다.

때문에 다른사람에게 혹시 도움이 될까 하여 코드를 남겨보겠습니다.

<!-- HTML -->
	<div class="dropdown">
        <button class="navbar__toggle-btn">
          <i class="fas fa-bars fa-2x"></i>
        </button>
        <div class="navbar__toggle_content" id="myDropdown">
		  <a href='#'>회원가입</a>
          <a href="#">자유게시판</a>
          <a href="#">추천게시판</a>
          <a href="#">공지사항</a>
        </div>
      </div>
      
 <script>
// 토글버튼 사용
//javascript
const navbarToggleBtn = document.querySelector('.navbar__toggle-btn');
navbarToggleBtn.addEventListener('click', () => {
	document.getElementById("myDropdown").classList.toggle('show');
});
 </script>
 
 <style>
 .navbar__toggle_content {
  display: none;
  position: absolute;
  right: 0;
  min-width: 10px;
  float: right;
  background-color: var(--color-light-green);
  box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}

.show {
  display: block;
}
 </style>

처음에 css 스타일로 토글 컨텐츠에 display : none값을 주어 안 보이게 한 후에 

스크립트로 토글 버튼을 누를때 마다 토글 콘텐츠의 디스플레이 값을 변경하게 만들었습니다.

 

728x90
728x90

각 페이지별 화면 구성을 짜 봤습니다.

index 페이지면서 추천 게시판의 글 목록을 보여줍니다. 

사이트 전체에서 글의 내용을 보고 싶으면 로그인을 해야 하고

로그인하지 않은 상태에서 글을 누르면 로그인 페이지로 이동합니다.

 

회원가입할 때 닉네임도 설정 가능하게 해서 로그인 이후에는 닉네임이 보이게 할까 고민입니다.

우선은 ID로 표시되게 할 예정입니다.

 

 아이디 찾기만 적어놓았는데 비밀번호 찾기도 이메일로 발송해 변경하게 구현할까 합니다.

로그인 버튼을 눌렀을 때 아이디와 비밀번호가 DB에 있으면 index 혹은 그 전 페이지로 이동하고

없을 경우 로그인 페이지에서 경고창만 띄웁니다.

 

아이디 찾기 페이지입니다. 일치하는 ID와 email이 있을 경우 새 페이지로 이동해서 보여줄지 

경고창같은 팝업을 띄워서 보여줄지 고민입니다. 일치하는 경우에는 새 페이지로 이동해서 보여주고

없는 경우에만 경고창을 띄워 알려주는 게 지금은 제일 나아 보입니다.

가벼운 사이트를 원하기 때문에 입력받는 내용이 별로 없습니다.

DB에 같은 ID가 있는지 체크하는 버튼을 만들고,

빠진 내용이 없었을 때 확인 버튼을 누르면 DB에 데이터를 추가합니다.

 

글 목록에서 글을 클릭할 경우 보이는 페이지입니다.

추천, 비추천 버튼과 신고버튼을 구현하고,

작성자 본인인 경우에 글을 수정할 수 있는 수정 버튼을 보이게 만듭니다. 

하단에는 글에 댓글을 달 수 있는 창을 만듭니다. 

댓글의 경우에는 DB를 어떻게 해야 할까요?

생각으로는 table을 하나 만들고 게시판에 글 번호를 외래 키로 받아 표시하면 될 거 같은데...

 

 글 쓰기, 수정하기 페이지입니다.

화면 구성은 같은 모습이지만 실제로 구현할 때 수정하기 페이지의 모습은 좀 다른데

원래 글의 제목과 내용을 그대로 받아올 예정입니다.

글 쓰기의 경우 등록을 누르면 DB에 새로운 데이터가 추가되고 

수정하기의 경우 update 구문을 사용합니다.

 

포트폴리오 페이지입니다.

각 회원마다 자신의 종목을 추가할 수 있고, 다른 회원에게 보여줄지 말지 결정할 수 있습니다.

그리고 자산 추이를 보여주는 그래프가 할당되는데 이 페이지는 구현할지 말지 고민하고 있습니다...

 

 이외에도 마이페이지와 비밀번호 변경 기능, 스크랩 기능, 스크랩 확인 페이지를 만들 생각하고 있습니다. 

728x90
728x90

라이브러리

  • imgscalr-lib.jar

    - JAVA로 구현된 간단하고 효율적인 이미지 크기 조정 및 조작 패키지

  • cos.jar

    - MultipatRequest 및 MultipartParser 클래스를 포함한 패키지

    - 파일 업로드 기능을 구현한다.

HTML

  • document.form.enctype = "multipart/form-data"

    - enctype 속성은 form 태그의 method 속성 값이 post인 경우에만 사용할 수 있고, 폼 데이터가 서버로 제출될 때 해당 데이터가 인코딩 되는 방법을 명시한다.

    - multipart/form-data는 모든 문자를 인코딩하지 않음을 뜻하고 주로 파일이나 이미지를 서버로 전송할 때 사용한다

JAVA

  • MultipartRequest

    - 파일 업로드 및 폼 요소를 처리하는 클래스

    - .getFilesystemName() : 서버에 실제로 업로드된 파일의 이름을 반환한다.

    - .getOriginalFileName() : 클라이언트가 업로드한 파일의 원본 이름을 반환한다.

  • DefaultFileRenamePolicy()

    - 동일한 파일명에 대한 처리 방식을 설정한다.

    - 같은 이름의 파일이 있을경우 test.jpg, test(1). jpg, test(2). jpg 형식으로 설정된다.

  • Enumeration

    - 객체들을 집합의 형태로 관리해주는 인터페이스다.

    - .getFileName() : Enumeration 형식으로 업로드된 파일 이름들을 반환한다.

    - .nextElement() : 다음 요소를 반환한다.

  • Files.probContentType()

    - 파일의 컨텐츠 유형을 파악한다.

  • ServletOutputStream 

    - 이진 데이터를 클라이언트로 보내기 위한 출력 스트림을 제공한다.

    - 자체로는 추상클래스이기 때문에 인스턴스를 생성할 수 없고 ServletResponse 클래스의 getOutputStream()이라는 메서드를 통해 사용한다.

    - 게시판에 파일을 올릴 때 사용할 수 있다.

728x90

'노트' 카테고리의 다른 글

jQuery 필터링 메서드  (1) 2022.05.18
jQuery 개요, 기본 문법  (0) 2022.05.17
5월 3일 JSP 게시판 페이징 학습  (0) 2022.05.03
4월 28일 게시판 글 삭제하기  (0) 2022.04.28
4월 27일 JSP 게시판 글 수정하기  (0) 2022.04.27
728x90

BoardDAO.java

  • boardSelectAll(Criteria cri) 메서드 수정

    - 메서드의 매개변수로 cri를 추가

    - 기존의 DB에서 모든 글을 가져오던 메서드였으나 페이지별로 일정 숫자의 글을 가져오도록 수정

  • boardTotal()

    - DB에서 게시글의 총개수를 가져오는 메서드

    - select count를 사용

Criteria.java

  • 페이지 갯수와 한 화면에 출력되는 글 개수를 담는 객체를 생성하는 클래스

PageMaker.java

  • BoardDAO의 boardTotal() 메서드의 게시글 총개수를 매개변수로 받아서 시작 페이지와 끝 페이지를 계산하고 반환한다. 

boardList.jsp

  • 글 하단의 페이지 번호를 누르면 BoardController의 가상주소에 매핑되고 페이지 번호를 파라미터로 보낸다.
  • 추가로 PageMaker의 속성들을 공유받는다.

BoardController.java

  • boardList로 부터 받은 페이지 숫자와 boardTotal 메서드로 반환받은 게시글 총개수를 변수에 담는다.
  • 두 변수의 값을 PageMaker의 객체에 담는다.
  • BoardDAO의 boardSelectAll 메서드를 실행한다.
728x90

'노트' 카테고리의 다른 글

jQuery 개요, 기본 문법  (0) 2022.05.17
5월 6일 JSP  (0) 2022.05.07
4월 28일 게시판 글 삭제하기  (0) 2022.04.28
4월 27일 JSP 게시판 글 수정하기  (0) 2022.04.27
4월 26일 자바스크립트 객체 개념  (0) 2022.04.26
728x90

BoardDAO.java

  • BoardDelete(int bidx){} 메서드를 만들었다.
  • DB table에서 데이터를 실제로 삭제하지는 않고 delyn 열의 값을 'y'로 바꿔주는 update 구문을 사용했다.
  • 글 목록을 가져올 때 where 조건에 delyn = 'n'값을 주어서 그렇다.

BoardController.java

  • 가상주소 boardDelete.do와 boardDeleteAction.do로 접속할 때 상황을 구현했다.
  • boardDelete.do

    - confirm을 이용해 확인창이 뜨고 누르면 삭제되는 방법이 있는데 구현하는 것을 늦게 알아서

    일단 boardDelete.jsp 파일을 만들어서 이쪽으로 이동하게 했다.

  • boardDeleteAction.do

    - boardDelete.jsp 페이지에서 삭제하기 확인을 누르면 작동

    - BoardDAO의 BoardDelete() 메서드를 이용한다.

    - 성공적으로 삭제된 경우 글 리스트 페이지로 이동, 아닐 경우 다시 글 내용 페이지로 이동한다.

728x90

'노트' 카테고리의 다른 글

5월 6일 JSP  (0) 2022.05.07
5월 3일 JSP 게시판 페이징 학습  (0) 2022.05.03
4월 27일 JSP 게시판 글 수정하기  (0) 2022.04.27
4월 26일 자바스크립트 객체 개념  (0) 2022.04.26
4월 25일 jsp 게시판 글 목록 보이기  (0) 2022.04.25

+ Recent posts