본문 바로가기
SPRING

[SPRING] 09/13 글쓰기 기능, 수정 추가

by KhyeonS 2022. 9. 13.

글쓰기 insert기능 추가

 

VisitController 수정

package com.korea.vs;

import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import dao.VisitDAO;
import vo.VisitVO;

@Controller
public class VisitController {
	VisitDAO visit_dao;

	public void setVisit_dao(VisitDAO visit_dao) {
		this.visit_dao = visit_dao;
	}

	@RequestMapping(value = {"/", "/list.do"})
	public String list(Model model) {
		//방명록 조회를 위한 dao의 메서드 호출
		List<VisitVO> list =visit_dao.selectList();
		model.addAttribute("list",list);
		
		//sendRedirect(/aaa.do);
		//return "redirect:list.do"
		return "/WEB-INF/views/visit/visit_list.jsp";
	}
	
	//삭제 메써드
	@RequestMapping("/delete.do")
	@ResponseBody //return값을 jsp등으로 인식하지 않고, 콜백 메서드로 전달하기 위한 키워드
	public String delete(int idx) {
		int res = visit_dao.delete(idx);

		String result = "no";
		if (res==1) {
			result="yes";
		}
		//@REsponseBody가 적용되어 있으므로
		//result에 no 또는 yes데이터는 콜백 메서드로 돌아간다
		return result;
	}
	@RequestMapping("/insert_form.do")
	public String insert_form() {
		return "/WEB-INF/views/visit/visit_insert_form.jsp";
	}
	
	// 새글등록하기
	@RequestMapping("/insert.do")
	public String insert(VisitVO vo) {
		
		int res = visit_dao.insert(vo);
		//sendRedirect("list.do");
		return "redirect:list.do"; //list.do매핑을 호출하는 방법
		
	}
}

 

visit_insert_form.jsp 생성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>

<script>
	function send(f){
		
		let name = f.name.value;
		let content = f.content.value;
		let pwd = f.pwd.value;
		
		// 유효성체크 했다치고
		
		f.action = "insert.do";
		f.method = "post";
		f.submit();//전송
	}
</script>
</head>
<body>
<form action="">
	<table border="1" align="center">
	<caption>:::새글쓰기:::</caption>
	
	<tr>
	<th>작성자</th>
	<td><input name="name"></td>
	</tr>
	<tr>
	<th>내용</th>
	<!-- wrap='on' : textarea에서 작성된 글이 길어서 다음줄로 넘어갔을때 
	엔터값으로 인지할 수 있도록 해주는 속성 -->
	<td><textarea name="content" rows="5" cols="50" wrap="on">
	
	</textarea></td>
	</tr>
	<tr>
	<th>비밀번호</th>
	<td><input type="password" name="pwd"></td>
	</tr>
	<tr>
	<td colspan="2" align="center">
		<input type="button" value="글쓰기" onclick="send(this.form);">
		<input type="button" value="목록으로" onclick="location.href='list.do'">
		
	</td>
	</tr>
	</table>
</form>

</body>
</html>

VisitDAO 추가

package dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import vo.VisitVO;

public class VisitDAO {
	SqlSession sqlSession;
	
	public void setSqlSession(SqlSession sqlSession) {
		this.sqlSession = sqlSession;
	}
	
	//방명록 전체 조회 
	public List<VisitVO> selectList(){
		List<VisitVO> list=sqlSession.selectList("v.visit_list");
		return list;
	}
	
	//게시글 삭제
	public int delete(int idx) {
		int res =sqlSession.delete("v.visit_delete", idx);
		return res;
	}
	//새글쓰기
	public int insert(VisitVO vo) {
		
		int res=sqlSession.insert("v.visit_insert", vo);
		//insert에는 파라미터엔 파라미터 하나 
		return res;
	}
}

visit.xml 추가

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
	<mapper namespace="v">
	
		<!-- 방명록 전체 조회 -->
		<select id="visit_list" resultType="visit">
			select * from visit order by
			idx DESC
	
		</select>
		
		<!-- 게시글 삭제 -->
		<delete id="visit_delete" parameterType="int">
			delete from visit where idx =#{idx}
		</delete>
		
		<!-- 게시글 추가 -->
		<insert id="visit_insert" parameterType="visit">
			insert into visit values(seq_visit_idx.nextVal, #{name}, #{content},#{pwd}, sysdate)
		</insert>
	</mapper>

visit_list 수정

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
* {
	magin: 0;
	padding: 0
}

#main_box {
	width: 330px;
	margin: 0 auto;
}

h1 {
	text-align: center;
	font-size: 20px;
	margin: 10px 0 10px 0;
	color: #ffffff;
	text-shadow: 2px 2px 2px black;
}

.visit_box {
	margin: 0 auto;
	width: 330px;
	margin-top: 30px;
	box-shadow: 2px 2px 2px black;
	border: 1px solid gray;
}

.type_content {
	min-height: 100px;
	height: auto;
	background: #fcc;
}

.type_name {
	background: #cfc;
}

.type_regdate {
	background: #ccf;
}
</style>
<!-- Ajax사용을 위한 httprequest참조 -->
<script src="/vs/resources/js/httpRequest.js"></script>
<script>

	/* 삭제 버튼 클릭*/
	function del(f) {
		var pwd = f.pwd.value; //원본 비밀번호
		var c_pwd = f.c_pwd.value;//비교를 위한 번호

		if (pwd != c_pwd) {
			alert('비밀번호가 다릅니다');
			return;
		}
		//Ajax를 통해 idx를 서버로 전송
		var url = "delete.do";
		var param = "idx="+f.idx.value;
		sendRequest(url, param, resultFunc, "Post");
		


	}//del()
	
	/*삭제 결과를 확인랑 콜백 메서드*/
	function resultFunc(){
		if(xhr.readyState == 4 && xhr.status==200){
			//컨트롤러에서 삭제후 return해준 데이터를 받는다
			var data= xhr.responseText;
			
			if(data =='no'){
				alert("삭제실패");
				return;
			}else{
				alert("삭제성공");
				location.href="list.do";
			}
		}
	}

	/* 수정 버튼 클릭*/
	function modify(f) {
		var pwd = f.pwd.value; //원본 비밀번호
		var c_pwd = f.c_pwd.value;//비교를 위한 번호

		if (pwd != c_pwd) {
			alert('비밀번호가 다릅니다');
			return;
		}

	}
</script>
</head>
<body>
	<div id="main_box">
		<h1>:::방명록 리스트:::</h1>
		<div align="center">
			<input type="button" value="글쓰기"
				onclick="location.href='insert_form.do'">
		</div>

		<c:forEach var="vo" items="${list}">
			<div class="visit_box">
				<div class="type_content"><pre>${vo.content}</pre></pre></div>
				<div class="type_name">${vo.name}</div>
				<div class="type_regdate">작성일:${vo.regdate}</div>

				<div>
					<form>
						<input type="hidden" name="idx" value="${vo.idx}"> <input
							type="hidden" name="pwd" value="${vo.pwd}"> 비밀번호<input
							type="password" name="c_pwd"> <input type="button"
							value="수정" onclick="modify(this.form);"> <input
							type="button" value="삭제" onclick="del(this.form);">

					</form>
				</div>
			</div>
		</c:forEach>
	</div>
</body>
</html>

이렇게 해주면 ㅇ글쓰기 기능이 완성된다.

 


글 수정 하기 추가

visit_list.jsp  추가

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
* {
	magin: 0;
	padding: 0
}

#main_box {
	width: 330px;
	margin: 0 auto;
}

h1 {
	text-align: center;
	font-size: 20px;
	margin: 10px 0 10px 0;
	color: #ffffff;
	text-shadow: 2px 2px 2px black;
}

.visit_box {
	margin: 0 auto;
	width: 330px;
	margin-top: 30px;
	box-shadow: 2px 2px 2px black;
	border: 1px solid gray;
}

.type_content {
	min-height: 100px;
	height: auto;
	background: #fcc;
}

.type_name {
	background: #cfc;
}

.type_regdate {
	background: #ccf;
}
</style>
<!-- Ajax사용을 위한 httprequest참조 -->
<script src="/vs/resources/js/httpRequest.js"></script>
<script>

	/* 삭제 버튼 클릭*/
	function del(f) {
		var pwd = f.pwd.value; //원본 비밀번호
		var c_pwd = f.c_pwd.value;//비교를 위한 번호

		if (pwd != c_pwd) {
			alert('비밀번호가 다릅니다');
			return;
		}
		//Ajax를 통해 idx를 서버로 전송
		var url = "delete.do";
		var param = "idx="+f.idx.value;
		sendRequest(url, param, resultFunc, "Post");
		


	}//del()
	
	/*삭제 결과를 확인랑 콜백 메서드*/
	function resultFunc(){
		if(xhr.readyState == 4 && xhr.status==200){
			//컨트롤러에서 삭제후 return해준 데이터를 받는다
			var data= xhr.responseText;
			
			if(data =='no'){
				alert("삭제실패");
				return;
			}else{
				alert("삭제성공");
				location.href="list.do";
			}
		}
	}

	/* 수정 버튼 클릭*/
	function modify(f) {
		var pwd = f.pwd.value; //원본 비밀번호
		var c_pwd = f.c_pwd.value;//비교를 위한 번호

		if (pwd != c_pwd) {
			alert('비밀번호가 다릅니다');
			return;
		}
		f.action = "modify_form.do";
		f.method = "post";
		f.submit();

	}
</script>
</head>
<body>
	<div id="main_box">
		<h1>:::방명록 리스트:::</h1>
		<div align="center">
			<input type="button" value="글쓰기"
				onclick="location.href='insert_form.do'">
		</div>

		<c:forEach var="vo" items="${list}">
			<div class="visit_box">
				<div class="type_content"><pre>${vo.content}</pre></pre></div>
				<div class="type_name">${vo.name}</div>
				<div class="type_regdate">작성일:${vo.regdate}</div>

				<div>
					<form>
						<input type="hidden" name="idx" value="${vo.idx}"> <input
							type="hidden" name="pwd" value="${vo.pwd}"> 비밀번호<input
							type="password" name="c_pwd"> <input type="button"
							value="수정" onclick="modify(this.form);"> <input
							type="button" value="삭제" onclick="del(this.form);">

					</form>
				</div>
			</div>
		</c:forEach>
	</div>
</body>
</html>

VisitController 수정

package com.korea.vs;

import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import dao.VisitDAO;
import vo.VisitVO;

@Controller
public class VisitController {
	VisitDAO visit_dao;

	public void setVisit_dao(VisitDAO visit_dao) {
		this.visit_dao = visit_dao;
	}

	@RequestMapping(value = {"/", "/list.do"})
	public String list(Model model) {
		//방명록 조회를 위한 dao의 메서드 호출
		List<VisitVO> list =visit_dao.selectList();
		model.addAttribute("list",list);

		//sendRedirect(/aaa.do);
		//return "redirect:list.do"
		return "/WEB-INF/views/visit/visit_list.jsp";
	}

	//삭제 메써드
	@RequestMapping("/delete.do")
	@ResponseBody //return값을 jsp등으로 인식하지 않고, 콜백 메서드로 전달하기 위한 키워드
	public String delete(int idx) {
		int res = visit_dao.delete(idx);

		String result = "no";
		if (res==1) {
			result="yes";
		}
		//@REsponseBody가 적용되어 있으므로
		//result에 no 또는 yes데이터는 콜백 메서드로 돌아간다
		return result;
	}
	@RequestMapping("/insert_form.do")
	public String insert_form() {
		return "/WEB-INF/views/visit/visit_insert_form.jsp";
	}

	// 새글등록하기
	@RequestMapping("/insert.do")
	public String insert(VisitVO vo) {

		int res = visit_dao.insert(vo);
		//sendRedirect("list.do");
		return "redirect:list.do"; //list.do매핑을 호출하는 방법

	}
	//글수정 폼으로 이동
	@RequestMapping("/modify_form.do")
	public String modify_form(Model model, int idx) {
		
		VisitVO vo = visit_dao.selectOne(idx);
		
		if (vo != null) {
			model.addAttribute("vo", vo);
			
		}
		return "/WEB-INF/views/visit/visit_modify_form.jsp";
	}
	
	//게시글 수정
	@RequestMapping("/modify.do")
	public String modify(VisitVO vo) {
		int res=visit_dao.update(vo);
		
		return "redirect:list.do";
		
	}
}

 

VisitDAO 추가

package dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import vo.VisitVO;

public class VisitDAO {
	SqlSession sqlSession;
	
	public void setSqlSession(SqlSession sqlSession) {
		this.sqlSession = sqlSession;
	}
	
	//방명록 전체 조회 
	public List<VisitVO> selectList(){
		List<VisitVO> list=sqlSession.selectList("v.visit_list");
		return list;
	}
	
	//게시글 삭제
	public int delete(int idx) {
		int res =sqlSession.delete("v.visit_delete", idx);
		return res;
	}
	//새글쓰기
	public int insert(VisitVO vo) {
		
		int res=sqlSession.insert("v.visit_insert", vo);
		//insert에는 파라미터엔 파라미터 하나 
		return res;
	}
	
	//수정할 게시글 한건 검색
	public VisitVO selectOne(int idx) {
		VisitVO vo = sqlSession.selectOne("v.visit_one", idx);
		return vo;
	}
	
	//수정 시작
	public int update(VisitVO vo) {
		int res = sqlSession.update("v.visit_update", vo);
		return res;
	}
}

visit.xml 추가 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
	<mapper namespace="v">
	
		<!-- 방명록 전체 조회 -->
		<select id="visit_list" resultType="visit">
			select * from visit order by
			idx DESC
	
		</select>
		
		<!-- 게시글 삭제 -->
		<delete id="visit_delete" parameterType="int">
			delete from visit where idx =#{idx}
		</delete>
		
		<!-- 게시글 추가 -->
		<insert id="visit_insert" parameterType="visit">
			insert into visit values(seq_visit_idx.nextVal, #{name}, #{content},#{pwd}, sysdate)
		</insert>
		
		<!-- 수정을 위한 게시글 한건 조회 -->
		<select id="visit_one" resultType="visit" parameterType="int">
		 select * from visit where idx=#{idx}
		</select>
		
		<!-- 게시글 수정 -->
		<update id="visit_update" parameterType="visit">
			update visit set name=#{name}, content=#{content}, pwd=#{pwd}, regidate=sysdate
			where idx=#{idx}
		</update>
	</mapper>

 

modify_form.jsp 생성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script>
	function send(f){
		let name= f.name.value;
		let content = f.content.value;
		let pwd = f.pwd.vlaue;
		// 유효성 검사를 위해서 받아옴
		
		f.action="modify.do";
		f.method="post";
		f.submit();
	}
</script>
</head>
<body>
<form>
	<input type="hidden" name="idx" value="${vo.idx}">
	
	<table boder="1" align="center">
	<caption>:::수정하기::::</caption>
	
	<tr>
	<th>작성자</th>
	<td><input name="name" value="${vo.name}"></td>
	</tr>
	<tr>
	<th>내용</th>
	<td><pre><textarea rows="5" cols="50" name="content">${vo.content}</textarea></pre></td>
	
	</tr>
	<tr>
	<th>비밀번호</th>
	<td><input type="password" name="pwd" value="${vo.pwd}"></td>
	</tr>
	<tr>
	<td colspan="2" align="center">
	<input type="button" value="수정" onclick="send(this.form);">
	<input type="button" value="목록" onclick="location.href='list.do'">
	</td>
	</tr>
	</table>
</form>

</body>
</html>


로그인 체크

vo 패키지 생성후 MemberVO 클래스 생성

package vo;

public class MemberVO {
	private String name;
	private String id;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
	private String pwd;
	
}

MemberDAO 클래스 생성

package dao;

import org.apache.ibatis.session.SqlSession;

import vo.MemberVO;

public class MemberDAO {
	SqlSession sqlSession;
	public void setSqlSession(SqlSession sqlSession) {
		this.sqlSession= sqlSession;
	}
	public MemberVO select(MemberVO vo) {
		MemberVO baseVo = sqlSession.selectOne("u.id_check", vo);
		return baseVo;
	}
}

MemberController 클래스 생성

package controller;

import java.io.OutputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import dao.MemberDAO;
import vo.MemberVO;

@Controller
public class MemberController {
	
	final String PATH= "/WEB-INF/views/";
	
	MemberDAO member_dao;
	public void setMember_dao(MemberDAO member_dao) {
		this.member_dao = member_dao;
	}
	
	@RequestMapping(value= {"/", "/main.do"})
	public String checkLogin() {
		return PATH + "main.jsp";
	}
	
	@RequestMapping("/login_form.do")
	public String loginForm() {
		return PATH +"login_form.jsp";
	}
	
	// 로그인 가능여부 판단
		@RequestMapping("/login.do")
		@ResponseBody
		public String loginCheck(MemberVO vo, HttpServletRequest request) {
			MemberVO baseVO = member_dao.select(vo);
			
			String resultStr = "";
			
			//id가 존재하지 않는 경우
			if(baseVO==null) {
				resultStr ="no_id";
				System.out.println(resultStr);
				return resultStr; //no_id를 콜백메서드로 전달
			}
			//비밀번호 불일치
			if(!baseVO.getPwd().equals(vo.getPwd())) {
				resultStr ="no_pwd";
				return resultStr; //no_pwd를 콜백 매서드로 전달
			}
			
			//아이디와 비밀번호에 문제가 없다면 세션에 MemberVO객체를 저장
			//세션에 저장된 데이터는 현재 프로젝트의 모든 jsp에서 사용 가능
			HttpSession session = request.getSession();
			session.setAttribute("user",baseVO);
			
			resultStr="clear";
			return resultStr;//로그인 성공시 clear가 콜벡메서드로 전달
			
		}
		@RequestMapping("/logout.do")
		public String logout(HttpServletRequest request) {
			HttpSession session = request.getSession();
			//user로 저장해둔 데이터를 세션에서 제거
			session.removeAttribute("user");
			
			return"redirect:login_form.do";
		}

}

main.jsp 생성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<jsp:include page="check_login.jsp"/>
	메인페이지<br>
	${user.name }님 환영합니다.<!-- 세션에 user라는 이름 저장된 객체에서 이름을 가져온다 -->
	<input type="button" value="로그아웃" onclick="location.href='logout.do'">
	
</body>
</html>

check_login.jsp생성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 
<c:if test="${ empty user }">
<script>
	alert("로그인후 이용가능한 페이지 입니다.");
	location.href="login_form.do";
</script> 
</c:if> 
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	로그인체크
</body>
</html>

login_form.jsp 생성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>

<script src="/session/resources/js/httpRequest.js"></script>
<script>
	function send(f){
		let url="login.do";
		let param = "id="+f.id.value+"&pwd="+f.pwd.value;
		
		sendRequest(url, param, resultFn, "POST");
	}
	function resultFn(){
		if(xhr.readyState==4&&xhr.status==200){
			//no_id, no_pqd, clear중 하나를 받는다
			let data = xhr.responseText;
			
			if(data=='no_id'){
				alert("아이디가 없습니다.");
				
			}else if( data =='no_pwd'){
				alert("비밀번호가 불일치");
			}else{
				location.href="main.do";
			}
		
		}
	}
	
</script>
</head>
<body>
	<form>
		<table border="1" align="center">
			<caption>:::로그인:::</caption>
			
			<tr>
			<th>아이디</th>
			<td><input name="id"></td>
			</tr>
			<tr>
			<th>비밀번호</th>
			<td><input type="password" name="pwd"></td>
			</tr>
			<tr>
			<td colspan="2" align="center">
			<input type="button" vlaue="로그인" onclick="send(this.form);">
			</td>
			</tr>
		</table>
	</form>
</body>
</html>

servlet-context.xml 수정

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	
	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/resources/**" location="/resources/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
	<!-- <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean> -->
	
	<!-- 
	com.korea.db패키지의 컨트롤러를 자동으로 만들어주는 코드
	<context:component-scan base-package="com.korea.db" /> -->
	
	<!-- 컨트롤러 수동생성 컴트롤러엔 id가 없어도 됨!-->
	<beans:bean id="c" class="controller.MemberController">
		<beans:property name="member_dao" ref="member_daoBean"/>
	</beans:bean>  
</beans:beans>

로그인및 게시판.7z
0.02MB

'SPRING' 카테고리의 다른 글

[SPRING] 0915 게시판 만들기-1  (0) 2022.09.15
[SPRING] 09/14 방명록에 사진 첨부  (0) 2022.09.14
[SPRING] 09/08  (0) 2022.09.08
[SPRING] 09/07  (0) 2022.09.07
[SPRING]09/06  (0) 2022.09.06

댓글