자바 스프링 게시판(@Controller, @RequestMapping을 이용하여 Controller변경)
Spring 게시판 구현(게시판 컨트롤러 변경, @Controller, @RequestMapping)
:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
1. 시작하기
지금까지 게시판에서 사용했던 BoardMultiController를 Spring2.5이상에서 지원하는 @Controller, @RequestMapping, @RequestParam을 이용하여 변경하자.
2, 4번과 같이 두 개의 파일을 수정하자.
1. 기존 BoardMultiController.java
2. 새로 작성할 BoardMultiController.java
3. 기존 action-servlet.xml
4. 새로 작성할 action-servlet.xml
1. 기존 BoardMultiController.java
package onj.board.controller;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.List;
import java.util.Enumeration;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponse;
import onj.board.model.BoardDTO;
import onj.board.model.CommentDTO;
import onj.board.service.BoardService;
import onj.board.model.CommentDTO;
import onj.board.service.BoardService;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;
public class BoardMultiController extends MultiActionController {
private BoardService boardService;
public void setBoardService(BoardService boardService) {
this.boardService = boardService;
}
this.boardService = boardService;
}
// 게시판 리스트 보기, 페이징 기능은 구현 안함
public ModelAndView list(HttpServletRequest req, HttpServletResponse res)
throws Exception {
public ModelAndView list(HttpServletRequest req, HttpServletResponse res)
throws Exception {
ModelAndView mv = new ModelAndView("list", "list",
boardService.boardList());
boardService.boardList());
return mv;
}
}
// 게시글 읽기
public ModelAndView read(HttpServletRequest req, HttpServletResponse res)
throws Exception {
String seq = req.getParameter("seq");
public ModelAndView read(HttpServletRequest req, HttpServletResponse res)
throws Exception {
String seq = req.getParameter("seq");
ModelAndView mav = new ModelAndView("read", "read",
boardService.readContent(seq));
// 해당 글의 커맨트도 함께 내려 보내자.
mav.addObject("comments", boardService.commentList(seq));
return mav;
boardService.readContent(seq));
// 해당 글의 커맨트도 함께 내려 보내자.
mav.addObject("comments", boardService.commentList(seq));
return mav;
}
// 커맨트쓰기
public ModelAndView comment(HttpServletRequest req, HttpServletResponse res) {
public ModelAndView comment(HttpServletRequest req, HttpServletResponse res) {
String seq = req.getParameter("seq");
CommentDTO commentDTO = new CommentDTO();
commentDTO.setSeq(seq);
commentDTO.setName(req.getParameter("name"));
commentDTO.setComment(req.getParameter("comment"));
commentDTO.setSeq(seq);
commentDTO.setName(req.getParameter("name"));
commentDTO.setComment(req.getParameter("comment"));
boardService.insertComment(commentDTO);
return new ModelAndView("redirect:/read.html?seq=" + seq);
}
}
// 새글(게시글) 입력
public ModelAndView write(HttpServletRequest req, HttpServletResponse res)
throws Exception {
public ModelAndView write(HttpServletRequest req, HttpServletResponse res)
throws Exception {
MultipartRequest multi = new MultipartRequest(req,
"c:\\java\\project\\onjboard1\\upload", 5 * 1024 * 1024,
"euc-kr", new DefaultFileRenamePolicy());
Enumeration formNames = multi.getFileNames();
String formName = (String) formNames.nextElement();
String fileName = multi.getFilesystemName(formName);
"c:\\java\\project\\onjboard1\\upload", 5 * 1024 * 1024,
"euc-kr", new DefaultFileRenamePolicy());
Enumeration formNames = multi.getFileNames();
String formName = (String) formNames.nextElement();
String fileName = multi.getFilesystemName(formName);
String name = multi.getParameter("name");
String passwd = multi.getParameter("passwd");
String title = multi.getParameter("title");
String content = multi.getParameter("content");
String passwd = multi.getParameter("passwd");
String title = multi.getParameter("title");
String content = multi.getParameter("content");
BoardDTO board = new BoardDTO(name, passwd, title, content, fileName);
boardService.insertBoard(board);
return new ModelAndView("redirect:/list.html");
}
}
// 게시글 수정
public ModelAndView update(HttpServletRequest req, HttpServletResponse res)
throws Exception {
public ModelAndView update(HttpServletRequest req, HttpServletResponse res)
throws Exception {
String seq = req.getParameter("seq");
String name = req.getParameter("name");
String passwd = req.getParameter("passwd");
String title = req.getParameter("title");
String content = req.getParameter("content");
String name = req.getParameter("name");
String passwd = req.getParameter("passwd");
String title = req.getParameter("title");
String content = req.getParameter("content");
BoardDTO board = new BoardDTO(name, passwd, title, content, "");
board.setSeq(Integer.parseInt(seq));
board.setSeq(Integer.parseInt(seq));
boardService.updateBoard(board);
return new ModelAndView("redirect:/read.html?seq="
+ req.getParameter("seq"));
}
+ req.getParameter("seq"));
}
// 게시글 삭제
public ModelAndView delete(HttpServletRequest req, HttpServletResponse res)
throws Exception {
String seq = req.getParameter("seq");
String passwd = req.getParameter("passwd");
public ModelAndView delete(HttpServletRequest req, HttpServletResponse res)
throws Exception {
String seq = req.getParameter("seq");
String passwd = req.getParameter("passwd");
int result = boardService.deleteBoard(seq, passwd);
if (result != 1) {
PrintWriter out = res.getWriter();
out.println("<script>alert('password not correct');</script>");
out.println("<script>history.go(-1);</script>");
return null;
} else {
return new ModelAndView("redirect:/list.html");
}
}
PrintWriter out = res.getWriter();
out.println("<script>alert('password not correct');</script>");
out.println("<script>history.go(-1);</script>");
return null;
} else {
return new ModelAndView("redirect:/list.html");
}
}
// 게시물상세보기에서 답변 클릭시 호출되어 답변달 reply.jsp로 연결
public ModelAndView reply(HttpServletRequest req, HttpServletResponse res) throws Exception {
public ModelAndView reply(HttpServletRequest req, HttpServletResponse res) throws Exception {
String seq = req.getParameter("seq");
// 답변달 게시물 내용을 reply.jsp 넘긴다.
ModelAndView mav = new ModelAndView("reply", //view이름
"reply", //readContent가 넘기는 boardDTO의 이름, reply.jsp에서 사용
boardService.readContent(seq));
return mav;
}
ModelAndView mav = new ModelAndView("reply", //view이름
"reply", //readContent가 넘기는 boardDTO의 이름, reply.jsp에서 사용
boardService.readContent(seq));
return mav;
}
// 답글 저장
public ModelAndView replyok(HttpServletRequest req, HttpServletResponse res)
throws Exception {
public ModelAndView replyok(HttpServletRequest req, HttpServletResponse res)
throws Exception {
String seq = req.getParameter("seq");
String name = req.getParameter("name");
String passwd = req.getParameter("passwd");
String title = req.getParameter("title");
String content = req.getParameter("content");
String fileName = "";
String reply = req.getParameter("reply");
String reply_step = req.getParameter("reply_step");
String reply_level = req.getParameter("reply_level");
String name = req.getParameter("name");
String passwd = req.getParameter("passwd");
String title = req.getParameter("title");
String content = req.getParameter("content");
String fileName = "";
String reply = req.getParameter("reply");
String reply_step = req.getParameter("reply_step");
String reply_level = req.getParameter("reply_level");
BoardDTO boardDTO = new BoardDTO(name, passwd, title, content, fileName);
boardDTO.setSeq(Integer.parseInt(seq));
boardDTO.setReply(Integer.parseInt(reply));
boardDTO.setReply_level(Integer.parseInt(reply_level));
boardDTO.setReply_step(Integer.parseInt(reply_step));
boardDTO.setReply(Integer.parseInt(reply));
boardDTO.setReply_level(Integer.parseInt(reply_level));
boardDTO.setReply_step(Integer.parseInt(reply_step));
boardService.replyBoard(boardDTO);
return new ModelAndView("redirect:/list.html");
}
}
}
2. 새로 작성할 BoardMultiController.java
package onj.board.controller;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.List;
import java.util.Enumeration;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponse;
import onj.board.model.BoardDTO;
import onj.board.model.CommentDTO;
import onj.board.service.BoardService;
import onj.board.model.CommentDTO;
import onj.board.service.BoardService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;
@Controllerpublic class BoardMultiController { @Autowired private BoardService boardService;
// 게시판 리스트 보기, 페이징 기능은 구현 안함
@RequestMapping("/list") public ModelAndView list() {
ModelAndView mv = new ModelAndView("list", "list",
boardService.boardList());
@RequestMapping("/list") public ModelAndView list() {
ModelAndView mv = new ModelAndView("list", "list",
boardService.boardList());
return mv;
}
}
// 게시글 읽기
@RequestMapping("/read") public ModelAndView read(@RequestParam("seq") String seq) {
ModelAndView mav = new ModelAndView("read", "read",
boardService.readContent(seq));
// 해당 글의 커맨트도 함께 내려 보내자.
mav.addObject("comments", boardService.commentList(seq));
return mav;
@RequestMapping("/read") public ModelAndView read(@RequestParam("seq") String seq) {
ModelAndView mav = new ModelAndView("read", "read",
boardService.readContent(seq));
// 해당 글의 커맨트도 함께 내려 보내자.
mav.addObject("comments", boardService.commentList(seq));
return mav;
}
// 커맨트쓰기
@RequestMapping("/comment") public ModelAndView comment(
@RequestMapping("/comment") public ModelAndView comment(
@RequestParam("seq") String seq,
@RequestParam("name") String name,
@RequestParam("comment") String comment ) {
@RequestParam("name") String name,
@RequestParam("comment") String comment ) {
CommentDTO commentDTO = new CommentDTO();
commentDTO.setSeq(seq);
commentDTO.setName(name);
commentDTO.setComment(comment);
commentDTO.setSeq(seq);
commentDTO.setName(name);
commentDTO.setComment(comment);
boardService.insertComment(commentDTO);
return new ModelAndView("redirect:/read.html?seq=" + seq);
}
}
// 새글(게시글) 입력
@RequestMapping("/write") public ModelAndView write(HttpServletRequest req, HttpServletResponse res)
throws Exception {
@RequestMapping("/write") public ModelAndView write(HttpServletRequest req, HttpServletResponse res)
throws Exception {
MultipartRequest multi = new MultipartRequest(req,
"c:\\java\\project\\onjboard1\\upload", 5 * 1024 * 1024,
"euc-kr", new DefaultFileRenamePolicy());
Enumeration formNames = multi.getFileNames();
String formName = (String) formNames.nextElement();
String fileName = multi.getFilesystemName(formName);
"c:\\java\\project\\onjboard1\\upload", 5 * 1024 * 1024,
"euc-kr", new DefaultFileRenamePolicy());
Enumeration formNames = multi.getFileNames();
String formName = (String) formNames.nextElement();
String fileName = multi.getFilesystemName(formName);
String name = multi.getParameter("name");
String passwd = multi.getParameter("passwd");
String title = multi.getParameter("title");
String content = multi.getParameter("content");
String passwd = multi.getParameter("passwd");
String title = multi.getParameter("title");
String content = multi.getParameter("content");
BoardDTO board = new BoardDTO(name, passwd, title, content, fileName);
boardService.insertBoard(board);
return new ModelAndView("redirect:/list.html");
}
}
// 게시글 수정
@RequestMapping("/update") public ModelAndView update(
@RequestParam("seq") String seq,
@RequestParam("name") String name,
@RequestParam("passwd") String passwd,
@RequestParam("title") String title,
@RequestParam("content") String content ) {
@RequestMapping("/update") public ModelAndView update(
@RequestParam("seq") String seq,
@RequestParam("name") String name,
@RequestParam("passwd") String passwd,
@RequestParam("title") String title,
@RequestParam("content") String content ) {
BoardDTO board = new BoardDTO(name, passwd, title, content, "");
board.setSeq(Integer.parseInt(seq));
board.setSeq(Integer.parseInt(seq));
boardService.updateBoard(board);
return new ModelAndView("redirect:/read.html?seq=" + seq);
}
}
// 게시글 삭제
@RequestMapping("/delete") public ModelAndView delete(
@RequestParam("seq") String seq,
@RequestParam("passwd") String passwd, HttpServletResponse res
) throws Exception{
@RequestMapping("/delete") public ModelAndView delete(
@RequestParam("seq") String seq,
@RequestParam("passwd") String passwd, HttpServletResponse res
) throws Exception{
int result = boardService.deleteBoard(seq, passwd);
if (result != 1) {
PrintWriter out = res.getWriter();
out.println("<script>alert('password not correct');</script>");
out.println("<script>history.go(-1);</script>");
return null;
} else {
return new ModelAndView("redirect:/list.html");
}
}
PrintWriter out = res.getWriter();
out.println("<script>alert('password not correct');</script>");
out.println("<script>history.go(-1);</script>");
return null;
} else {
return new ModelAndView("redirect:/list.html");
}
}
// 게시물상세보기에서 답변 클릭시 호출되어 답변달 reply.jsp로 연결
@RequestMapping("/reply") public ModelAndView reply(@RequestParam("seq") String seq) {
@RequestMapping("/reply") public ModelAndView reply(@RequestParam("seq") String seq) {
// 답변달 게시물 내용을 reply.jsp 넘긴다.
ModelAndView mav = new ModelAndView("reply", //view이름
"reply", //readContent가 넘기는 boardDTO의 이름, reply.jsp에서 사용
boardService.readContent(seq));
return mav;
}
ModelAndView mav = new ModelAndView("reply", //view이름
"reply", //readContent가 넘기는 boardDTO의 이름, reply.jsp에서 사용
boardService.readContent(seq));
return mav;
}
// 답글 저장
@RequestMapping("/replyok") public ModelAndView replyok(
@RequestParam("seq") String seq,
@RequestParam("name") String name,
@RequestParam("passwd") String passwd,
@RequestParam("title") String title,
@RequestParam("content") String content,
@RequestParam("reply") String reply,
@RequestParam("reply_step") String reply_step,
@RequestParam("reply_level") String reply_level ) {
@RequestMapping("/replyok") public ModelAndView replyok(
@RequestParam("seq") String seq,
@RequestParam("name") String name,
@RequestParam("passwd") String passwd,
@RequestParam("title") String title,
@RequestParam("content") String content,
@RequestParam("reply") String reply,
@RequestParam("reply_step") String reply_step,
@RequestParam("reply_level") String reply_level ) {
BoardDTO boardDTO = new BoardDTO(name, passwd, title, content, "");
boardDTO.setSeq(Integer.parseInt(seq));
boardDTO.setReply(Integer.parseInt(reply));
boardDTO.setReply_level(Integer.parseInt(reply_level));
boardDTO.setReply_step(Integer.parseInt(reply_step));
boardDTO.setReply(Integer.parseInt(reply));
boardDTO.setReply_level(Integer.parseInt(reply_level));
boardDTO.setReply_step(Integer.parseInt(reply_step));
boardService.replyBoard(boardDTO);
return new ModelAndView("redirect:/list.html");
}
}
}
3. 기존 action-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@127.0.0.1:1521:onj</value>
</property>
<property name="username">
<value>scott</value>
</property>
<property name="password">
<value>tiger</value>
</property>
</bean>
destroy-method="close">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@127.0.0.1:1521:onj</value>
</property>
<property name="username">
<value>scott</value>
</property>
<property name="password">
<value>tiger</value>
</property>
</bean>
<!-- 넘어오는 URL에 따라 컨트롤러에서 실행될 메소드 매핑 -->
<!-- PropertiesMethodNameResolver는 prop key로 넘어오는 url에 대해 실행할 컨트롤러의 메소드
정의 -->
<bean id="userControllerMethodNameResolver"
class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
<property name="mappings">
<props>
<!-- list.html 요청이 오면 컨트롤러의 list 메소드 실행 -->
<prop key="/list.html">list</prop>
<!-- read.html 요청이 오면 컨트롤러의 read 메소드 실행 -->
<prop key="/read.html">read</prop>
<!-- comment.html 요청이 오면 컨트롤러의 comment 메소드 실행 -->
<prop key="/comment.html">comment</prop>
<!-- write.html 요청이 오면 컨트롤러의 write 메소드 실행 -->
<prop key="/write.html">write</prop>
<!-- update.html 요청이 오면 컨트롤러의 update 메소드 실행 -->
<prop key="/update.html">update</prop>
<!-- delete.html 요청이 오면 컨트롤러의 delete 메소드 실행 -->
<prop key="/delete.html">delete</prop>
<!-- reply.html 요청이 오면 컨트롤러의 reply 메소드 실행 -->
<prop key="/reply.html">reply</prop>
<!-- replyok.html 요청이 오면 컨트롤러의 replyok 메소드 실행 -->
<prop key="/replyok.html">replyok</prop>
</props>
</property>
</bean>
<!-- PropertiesMethodNameResolver는 prop key로 넘어오는 url에 대해 실행할 컨트롤러의 메소드
정의 -->
<bean id="userControllerMethodNameResolver"
class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
<property name="mappings">
<props>
<!-- list.html 요청이 오면 컨트롤러의 list 메소드 실행 -->
<prop key="/list.html">list</prop>
<!-- read.html 요청이 오면 컨트롤러의 read 메소드 실행 -->
<prop key="/read.html">read</prop>
<!-- comment.html 요청이 오면 컨트롤러의 comment 메소드 실행 -->
<prop key="/comment.html">comment</prop>
<!-- write.html 요청이 오면 컨트롤러의 write 메소드 실행 -->
<prop key="/write.html">write</prop>
<!-- update.html 요청이 오면 컨트롤러의 update 메소드 실행 -->
<prop key="/update.html">update</prop>
<!-- delete.html 요청이 오면 컨트롤러의 delete 메소드 실행 -->
<prop key="/delete.html">delete</prop>
<!-- reply.html 요청이 오면 컨트롤러의 reply 메소드 실행 -->
<prop key="/reply.html">reply</prop>
<!-- replyok.html 요청이 오면 컨트롤러의 replyok 메소드 실행 -->
<prop key="/replyok.html">replyok</prop>
</props>
</property>
</bean>
<!-- 뷰 리졸버 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<!-- 컨트롤러 매핑 -->
<bean name="/list.html /read.html /comment.html /write.html
/update.html /delete.html /reply.html /replyok.html"
class="onj.board.controller.BoardMultiController">
<property name="methodNameResolver">
<ref local="userControllerMethodNameResolver" />
</property>
<property name="boardService">
<ref bean="boardService" />
</property>
</bean>
</beans>
<bean name="/list.html /read.html /comment.html /write.html
/update.html /delete.html /reply.html /replyok.html"
class="onj.board.controller.BoardMultiController">
<property name="methodNameResolver">
<ref local="userControllerMethodNameResolver" />
</property>
<property name="boardService">
<ref bean="boardService" />
</property>
</bean>
</beans>
4. 새로 작성할 action-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="onj.board.controller"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@192.168.0.7:1521:orcl</value>
</property>
<property name="username">
<value>scott</value>
</property>
<property name="password">
<value>tiger</value>
</property>
</bean>
destroy-method="close">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<property name="url">
<value>jdbc:oracle:thin:@192.168.0.7:1521:orcl</value>
</property>
<property name="username">
<value>scott</value>
</property>
<property name="password">
<value>tiger</value>
</property>
</bean>
<!-- 뷰 리졸버 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
</beans>
[개강확정강좌]오라클자바커뮤니티에서 운영하는 개발자 전문교육 ,개인80%환급(www.onjprogramming.co.kr)
[주말]
[10/26]C#,ASP.NET마스터
[11/2]Spring3.X, MyBatis, Hibernate실무과정
[11/2]JAVA&WEB프레임워크실무과정
[평일야간]
[10/29]C#,ASP.NET마스터
[10/31]JAVA&WEB프레임워크실무과정
[11/1]Spring3.X, MyBatis, Hibernate실무과정
[주간]
[11/4]Spring3.X, MyBatis, Hibernate실무과정
[주말]
[10/26]C#,ASP.NET마스터
[11/2]Spring3.X, MyBatis, Hibernate실무과정
[11/2]JAVA&WEB프레임워크실무과정
[평일야간]
[10/29]C#,ASP.NET마스터
[10/31]JAVA&WEB프레임워크실무과정
[11/1]Spring3.X, MyBatis, Hibernate실무과정
[주간]
[11/4]Spring3.X, MyBatis, Hibernate실무과정
[기타 다른 강좌는 아래 해당 카테고리를 클릭해주세요]
댓글 없음:
댓글 쓰기