BACKEND/스프링 Spring

[spring3.0] 스프링3.0 과 마이바티스를 이용하여 게시판 만들기

꾸준히개발하자 2022. 3. 29. 22:57

 

Spring MVC Project 를 생성해서 MyBatis를 활용한 게시판을 만들어보았다

 

게시판 기능

1. 등록

2. 삭제

3. 검색

4. 수정 

5. 페이징 처리 

 

 

SpringWebMybatis 프로젝트 생성

 

resource - css,js파일

src/main/java - DAO , DTO , boardMapper.xml , BoardController , MyUtil , MyBatis-config.xml

web-inf -  article.jsp ,  created.jsp , list.jsp  ,  updated.jsp 가 있다.

 

메이븐 으로 라이브러리 설치

 

 

pom.xml

		<!--  메이븐의 환경 세팅  -->
		<!-- commons-dbcp : JDBC 를 사용하기 위해서 DBCP1.4 메이븐으로 가져옴  -->
		<!-- commons-dbcp -->
        
        
		<dependency>
		    <groupId>commons-dbcp</groupId>
		    <artifactId>commons-dbcp</artifactId>
		    <version>1.4</version>
		</dependency>
		
		<!-- commons-pool : DBCP를 쓰기위한 툴  -->
		<!-- commons-pool/commons-pool -->
			
            <dependency>
			    <groupId>commons-pool</groupId>
			    <artifactId>commons-pool</artifactId>
			    <version>1.6</version>
			</dependency>

		<!-- ojdbc -->
		<dependency>
		    <groupId>com.oracle.database.jdbc</groupId>
		    <artifactId>ojdbc6</artifactId>
		    <version>11.2.0.4</version>
		</dependency>
		
		<!-- spring-jdbc -->
		<dependency>
		    <groupId>org.springframework</groupId>
		    <artifactId>spring-jdbc</artifactId>
		    <version>${org.springframework-version}</version>
		</dependency>
		
		<!-- mybatis -->
		<dependency>
		    <groupId>org.mybatis</groupId>
		    <artifactId>mybatis</artifactId>
		    <version>3.5.9</version>
		</dependency>
		
     	<!-- mybatis-spring -->
		<dependency>
		    <groupId>org.mybatis</groupId>
		    <artifactId>mybatis-spring</artifactId>
		    <version>1.3.3</version>
		</dependency>

 

라이브러리 mybatis , mybatis-spring 를 추가한다.

 

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">

<!-- mapper 에는 insert,delete의 쿼리들이 들어가있다. -->
<!-- 이클립스에서 sql문 모아놓은거랑 같은 기능 -->
<!-- 마이바티스 특징은  SqlSessionTemplate 은 CommDAO를 구현한 impl 두개없어도됨 없애고 마이바티스에 내장시킴-->

<configuration>
	<mappers>
		<mapper resource="com/jdbc/mybatis/boardMapper.xml"/>
	</mappers>
</configuration>

 

src - main - webapp - WEB-INF - spring - appServlet - servlet-context.xml

 

 

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>
	
	<!-- 컨트롤러 주소  -->
	<context:component-scan base-package="com.jdbc.springweb" />

	<!-- db연결 콘솔은 bean , 웹은 beans-->
	<!-- boardDAO객체생성 - 의존성주입 에 제어의 역전 -->
	<beans:bean id="boardDAO2" class="com.jdbc.dao.BoardDAO2">
		<beans:property name="sessionTemplate" ref="sessionTemplate"/>
	</beans:bean>
	
	<beans:bean id="sessionTemplate"
	class="org.mybatis.spring.SqlSessionTemplate">
		<beans:constructor-arg ref="sessionFactory"/>
	</beans:bean>
	
	<!-- 패키지안에 안만들었으므로 파일이름만 적으면됨 -->
	<beans:bean id="sessionFactory"
	class="org.mybatis.spring.SqlSessionFactoryBean">
		<beans:property name="configLocation"
		value="classpath:/mybatis-config.xml"/> 
		<beans:property name="dataSource" ref="dataSource"/>
	</beans:bean>
		
	<beans:bean id="dataSource"
	class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<beans:property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
		<beans:property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
		<beans:property name="username" value="suzi"/>
		<beans:property name="password" value="a123"/>
	</beans:bean>
	
	<beans:bean id="myUtil" class="com.jdbc.util.MyUtil"/> <!-- myutil객체생성 -->
</beans:beans>

 

 

BoardDTO.java

package com.jdbc.dto;

public class BoardDTO {
	
	private int num;
	private String name;
	private String pwd;
	private String email;
	private String subject;
	private String content;
	
	
	private String ipAddr;
	private String created;
	private int hitCount;
	
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getSubject() {
		return subject;
	}
	public void setSubject(String subject) {
		this.subject = subject;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public String getIpAddr() {
		return ipAddr;
	}
	public void setIpAddr(String ipAddr) {
		this.ipAddr = ipAddr;
	}
	public String getCreated() {
		return created;
	}
	public void setCreated(String created) {
		this.created = created;
	}
	public int getHitCount() {
		return hitCount;
	}
	public void setHitCount(int hitCount) {
		this.hitCount = hitCount;
	}
	
	
	
}

 

 

MyUtil 페이징처리 

package com.jdbc.util;

public class MyUtil {

	//전체페이지
	public int getPageCount(int numPerPage, int dataCount) {
		
		int pageCount = 0;
		
		pageCount = dataCount / numPerPage;
		
		if(dataCount % numPerPage !=0) {
			pageCount++;
			
		}
		return pageCount;
	}
	
	//페이지 처리 메소드
	public String pageIndexList(int currentPage, int totalPage, String listUrl) {
		
		int numPerBlock = 5; //◀이전 6 7 8 9 10 다음▶ 이전과 다음 사이의 페이지 표시 수.
		int currentPageSetup; //◀에 들어있는 값.
		int page;	//6 7 8 9 10 페이지값. int i와 비슷하다.
		
		StringBuffer sb = new StringBuffer(); //String을 도와주는 보조 스트링버퍼와 스트링빌더가 있다.
		
		if(currentPage==0 || totalPage==0) {
			return "";
		}
		
		//list.jsp?pageNum=2 Url이 두개가 올 수 있다. 페이징작업.
		//list.jsp?searchKey=subject&searchValue=a
		if(listUrl.indexOf("?")!=-1	) { //listUrl의 인덱스값중에 ? 가 들어있나 확인.
			listUrl = listUrl + "&"; //만약 있다면 url에 &를 더해라
		}else {
			listUrl = listUrl + "?"; //없다면 Url에 ?를 더해라
		}
		
		 // 1 2 3 4 5 다음▶
		 //◀이전 6 7 8 9 10 다음▶
		 //◀이전 11 12 13 14 15 다음▶
		//◀ 만들기
		currentPageSetup = (currentPage/numPerBlock)*numPerBlock; //6 / 5 는 1에 나머지 1 에다 numPerblock값 5를 더하면  5

		if(currentPage % numPerBlock == 0) { //커런트페이지를 나눈값이 0으로 딱 떨어지면 셋업-넘퍼블록.
			currentPageSetup = currentPageSetup - numPerBlock; //이전페이지를 구하는 공식
		}
	
		//◀이전 <만들기
		if(totalPage > numPerBlock && currentPageSetup > 0) { //토탈페이지보다 크고 넘퍼블록이나 커런트페이지셋업이 0보다 크면 만들고 작으면 안만듬
			//
			sb.append("<a href=\"" + listUrl + "pageNum=" + 
			currentPageSetup + "\">◀이전</a>&nbsp;"); // \" 역슬래시따옴표는 닫는 따옴표로 인식하지않는다.
			
			//<a href="list.jsp?pageNum=5>◀이전</a>
		}
		
		//바로가기페이지 6 7 8 9 10
		
		page = currentPageSetup + 1;
		
		while(page <= totalPage && page <= (currentPageSetup + numPerBlock)) {
			//페이지가 토탈페이지보다 작거나 같고 && 페이지가 커런트페이지셋업 + 넘퍼블록보다 작거나 같은게 참이면
			
			if(page == currentPage) {
				sb.append("<font color=\"Fuchsia\">" + page + "</font>&nbsp;");
				//<font color = "Fuchsia">9</font> 현재 보고있는 페이지에 색상을 준것.
				
			}else {
				
				sb.append("<a href=\"" + listUrl + "pageNum=" + page + "\">" + page + "</a>&nbsp;");
				
				//<a href="list.jsp?pageNum=7">7</a>&nbsp; 위와 동일. 현재보고있는 페이지가 아닌 다른페이지에 링크를준것.
			}
			
			page++; //++해주어야 와일문이 하나찍고 더하고 찍고 더하고 반복.
			
		}
		
		//다음▶
		//◀이전 6 7 8 9 10 다음▶
		//◀이전 11 12 13 14 15 다음▶
		if(totalPage - currentPageSetup > numPerBlock) {
			
			sb.append("<a href=\"" + listUrl + "pageNum=" + page + "\">다음▶</a>&nbsp;");
			//<a href="list.jsp?pageNum=11">다음▶</a>&nbsp; 위와 동일.
		}
		
		return sb.toString();
	}
	
	
}

 

 

BoardDAO2.java 

package com.jdbc.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;



import org.mybatis.spring.SqlSessionTemplate;

import com.jdbc.dto.BoardDTO;


public class BoardDAO2 {

	private SqlSessionTemplate sessionTemplate;
	
	// 객체 생성 동시에 초기화 = 의존성 주입 
	// dataSource받아서 초기화
	public void setSessionTemplate(SqlSessionTemplate sessionTemplate) throws Exception {
		this.sessionTemplate = sessionTemplate; 
	}
	
	// num의 최대값
	public int getMaxNum() {
		
		int maxNum = 0;
		
		maxNum = sessionTemplate.selectOne("com.boardMapper.maxNum");
		
		return maxNum;
	}
	
	// 입력
	public void insertData(BoardDTO dto) {	
		
		sessionTemplate.insert("com.boardMapper.insertData",dto);
		
	}
	
	// 전체 데이터 갯수
	public int getDataCount(String searchKey,String searchValue) {
		
		HashMap<String, Object> params = new HashMap<String,Object>();
		params.put("searchKey", searchKey);
		params.put("searchValue", searchValue);
		
		int totalCount = sessionTemplate.selectOne("com.boardMapper.getDataCount", params);	
	
		return totalCount;		
	}
	
	// 전체데이터 4개의 매개변수
	// Board dto 가 들어가있는 list
	public List<BoardDTO> getLists(int start,int end ,
			String searchKey,String searchValue) {	
		HashMap<String, Object> params = new HashMap<String,Object>();
		
		//4개의 매개변수
		params.put("start", start);
		params.put("end", end);
		params.put("searchKey", searchKey);
		params.put("searchValue", searchValue);
		
		List<BoardDTO> lists =
				sessionTemplate.selectList("com.boardMapper.getLists",params);
		
		return lists;
	}
	
	// num으로 조회한 한개의 데이터 ( article , update 할때 쓰일것임 ) 
		// Board dto 가 들어가있는 list	
	public BoardDTO getReadData(int num) { 
			BoardDTO dto = 
					sessionTemplate.selectOne("com.boardMapper.getReadData",num);
			return dto;
		}
		// 조회수 증가(update 업데이트)
		// num이라는 값의 조회수를 증가시킬것이다.
		public void updateHitCount(int num) {
			
			sessionTemplate.update("com.boardMapper.updateHitCount",num);
		}
		//수정
		public void updateData(BoardDTO dto) {
			int result = 0;
			sessionTemplate.update("com.boardMapper.updateData",dto);
		}
		
		// 삭제
		public void deleteData(int num) {
			sessionTemplate.delete("com.boardMapper.deleteData",num);
			
		}
	}

 

 

boardMapper.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="com.boardMapper">
	
<select id="maxNum" resultType="int">
	select nvl(max(num),0) from board
</select>	

<insert id="insertData" parameterType="com.jdbc.dto.BoardDTO">
	insert into board(num,name,pwd,email,subject,content,ipAddr,
	hitCount,created) values(#{num},#{name},#{pwd},#{email},#{subject}
	,#{content},#{ipAddr},0,sysdate)
</insert>

<select id="getDataCount" parameterType="hashMap" resultType="int">
	select nvl(count(*),0) from board
	where ${searchKey} like '%' || #{searchValue} || '%'
</select>
	
<select id="getLists" parameterType="map" resultType="com.jdbc.dto.BoardDTO">
	select * from (
	select rownum rnum, data.* from (
	select num,name,subject,hitCount,
	to_char(created,'YYYY-MM-DD') created
	from board where ${searchKey} like '%' || #{searchValue} || '%'
	order by num desc) data)
<![CDATA[
	where rnum>=#{start} and rnum<=#{end}
]]>
</select>

<update id="updateHitCount" parameterType="int">
	update board set hitCount=hitCount+1 where num=#{num}
</update>

<select id="getReadData" parameterType="int" resultType="com.jdbc.dto.BoardDTO">
	select num,name,pwd,email,subject,content,IpAddr,
	hitCount,created from board where num=#{num}
</select>
	
<update id="updateData" parameterType="com.jdbc.dto.BoardDTO">
	update board set name=#{name},pwd=#{pwd},email=#{email},subject=#{subject},
	content=#{content} where num=#{num}
</update>	

<delete id="deleteData" parameterType="int">
	delete board where num=#{num}
</delete>

</mapper>

 

 

BoardController.java

package com.jdbc.springweb;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.jdbc.dao.BoardDAO2;
import com.jdbc.dto.BoardDTO;
import com.jdbc.util.MyUtil;

//Controller 객체 생성 및  Controller 자동 상속 
@Controller
public class BoardController {
	
	/* servlet jdbc 
	@Autowired
	@Qualifier("boardDAO")
	BoardDAO dao; 
	*/
	
	// spring jdbc 
	@Autowired
	@Qualifier("boardDAO2")
	BoardDAO2 dao; // 의존성 주입

	@Autowired
	MyUtil myUtil; // 의존성주입해서 자동으로 가져옴
	
	@RequestMapping(value="/",method=RequestMethod.GET)
	public String home() {
		
		return "index";	
	}
	
	// get방식으로 왔을때
	/*
	@RequestMapping(value="/created.action",
			method= {RequestMethod.GET,RequestMethod.POST})
	public String created(HttpServletRequest request,HttpServletResponse response) throws Exception {
		return "bbs/created";
	}
	*/
	
	// Spring 고유의 ModelAndView
	// method 안쓰면 기본이 get방식으로 간다
	@RequestMapping(value="/created.action")
	public ModelAndView created() {		
		ModelAndView mav = new ModelAndView();
		mav.setViewName("bbs/created");	
		return mav;
	}
	
	// created.jsp 에서 글쓰기완료를 누르면 created_ok.action으로 이동
	@RequestMapping(value="/created_ok.action",
			method= {RequestMethod.GET,RequestMethod.POST})
	public String created_ok(BoardDTO dto , HttpServletRequest request,HttpServletResponse response) throws Exception {

		int maxNum = dao.getMaxNum();
		
		dto.setNum(maxNum + 1);
		dto.setIpAddr(request.getRemoteAddr());
		dao.insertData(dto);
		
		return "redirect:/list.action";
	}
	/*
	@RequestMapping(value = "/list.action",
			method = {RequestMethod.GET,RequestMethod.POST})
	public String list(BoardDTO dto,HttpServletRequest request, HttpServletResponse response) throws Exception{
	*/
	
	// ModelAndView로 
	
	@RequestMapping(value = "/list.action",
			method = {RequestMethod.GET,RequestMethod.POST})
	public ModelAndView list(BoardDTO dto,HttpServletRequest request, HttpServletResponse response) throws Exception{
	
		String cp = request.getContextPath();
		
		String pageNum = request.getParameter("pageNum");
		
		int currentPage = 1;
		
		if(pageNum!=null)
			currentPage = Integer.parseInt(pageNum);
		
		String searchKey = request.getParameter("searchKey");
		String searchValue = request.getParameter("searchValue");
		
		if(searchValue==null) {
			searchKey = "subject";
			searchValue = "";
		
		}else {
			if(request.getMethod().equalsIgnoreCase("GET")) {
				searchValue = URLDecoder.decode(searchValue, "UTF-8");
			}
		}
		
		int dataCount = dao.getDataCount(searchKey, searchValue);
		
		int numPerPage = 5;
		int totalPage = myUtil.getPageCount(numPerPage, dataCount);
		
		if(currentPage>totalPage)
			currentPage = totalPage;
		
		int start = (currentPage-1)*numPerPage+1; // 1 6 11 16
		int end = currentPage*numPerPage;
		
		List<BoardDTO> lists = dao.getLists(start, end, searchKey, searchValue);
		
		String param = "";
		
		if(searchValue!=null&&!searchValue.equals("")) { //널을 찾아내지 못하는경우가 있기때문에 양쪽에 부정문을 써준다.
			param = "searchKey=" + searchKey;
			param+= "&searchValue=" + URLEncoder.encode(searchValue, "UTF-8");
		}
		
		String listUrl = cp + "/list.action";
		
		if(!param.equals("")) {
			listUrl += "?" + param;
		}

		String pageIndexList = myUtil.pageIndexList(currentPage, totalPage, listUrl);
		
		String articleUrl = cp + "/article.action?pageNum=" + currentPage;
		
		if(!param.equals("")) {
			articleUrl += "&" + param;
		}
		
		/*
		request.setAttribute("lists", lists);
		request.setAttribute("articleUrl", articleUrl);
		request.setAttribute("pageIndexList", pageIndexList);
		request.setAttribute("dataCount", dataCount);
		return "bbs/list";
		*/
		
		// ModelAndView로 데이터 넘기기
		ModelAndView mav = new ModelAndView();
		
		// 객체추가
		mav.addObject("lists",lists); // 데이터 넘기기
		mav.addObject("articleUrl",articleUrl); // 데이터 넘기기
		mav.addObject("pageIndexList",pageIndexList); // 데이터 넘기기
		mav.addObject("dataCount",dataCount); // 데이터 넘기기
		
		// VIEW이름설정 
		mav.setViewName("bbs/list"); // 어디로?	
		return mav;
	}
	
	@RequestMapping(value = "/article.action",
			method = {RequestMethod.GET,RequestMethod.POST})
	public String article(BoardDTO dto,HttpServletRequest request, HttpServletResponse response) throws Exception{
	
		String cp = request.getContextPath();
		
		String pageNum = request.getParameter("pageNum"); //  
		int num = Integer.parseInt(request.getParameter("num")); // 게시물번호 
		String searchKey = request.getParameter("searchKey"); // 검색 키
		String searchValue = request.getParameter("searchValue"); // 검색 값
		
		// 값이 있으면
		if(searchValue!=null) {
			searchValue = URLDecoder.decode(searchValue,"UTF-8");
		}
		
		//게시물번호(프라이머리키) 조회수 증가
		dao.updateHitCount(num);
		
		// 하나의 데이터 읽어온다
		// setAttribute("dto",dto);
		dto = dao.getReadData(num);		
		
		if(dto==null) {
			// modeleAndView 일때는 "redirect:/list.action"; 못씀
			return "redirect:/list.action";
		}
		
		// 라인수 
		// setAttribute("line",lineSu);
		int lineSu = dto.getContent().split("\n").length;
		
		dto.setContent(dto.getContent().replaceAll("\n", "<br/>"));
		
		// setAttribute("params",param);
		
		// 밑에 몇번째 게시물인지 
		String param = "pageNum="+pageNum;
		
		if(searchValue!=null&&!searchValue.equals("")) {
			//검색을 했다는거
			param += "&searchKey="+searchKey;
			// 인코더 시켜서 보낸다
			param += "&searchValue="+URLEncoder.encode(searchValue,"UTF-8");
		}
		
		// 게시물 누르면 데이터가 보여지게 위해서 데이터를 넘김(setAttribute)
		request.setAttribute("dto", dto);
		
		// 사진8번
		// 값을 가지고 넘어가는 변수는 param을 쓸수없다
		// param은 이미 내부에 변수를 쓰고있다.
		request.setAttribute("params", param); // 키와 벨류 
		request.setAttribute("lineSu", lineSu);
		request.setAttribute("pageNum", pageNum);
		
		return "bbs/article";
	}
	
	@RequestMapping(value = "/updated.action",
			method = {RequestMethod.GET,RequestMethod.POST})
	public String updated(HttpServletRequest request, HttpServletResponse response) throws Exception{
		
		String cp = request.getContextPath();
		
		// 수정버튼 눌렀을때 주소창으로 넘어가는 데이터 
			int num = Integer.parseInt(request.getParameter("num"));
			String pageNum = request.getParameter("pageNum");
			String searchKey = request.getParameter("searchKey");
			String searchValue = request.getParameter("searchValue");
			
			if(searchValue!=null) {
				searchValue = URLDecoder.decode(searchValue,"UTF-8");		
			}
			// 특정 데이터 (한개의 데이터) num으로 클릭하고 들어갔으므로 
			
			// http://localhost:8080/study/sboard/updated.do?num=39&pageNum=1
			
			BoardDTO dto = dao.getReadData(num);

			if(dto==null) {
				return "redirect:/list.action";
			}
			
			// 데이터 넘기기 위한 param
			String param = "pageNum=" + pageNum;
			
			if(searchValue!=null&&!searchValue.equals("")) {
				param += "&searchKey=" + searchKey;
				param += "&searchValue=" + URLEncoder.encode(searchValue,"UTF-8");
			}
			
			// 수정했을때 페이지에 기존 데이터들을 불러와야되므로 넘김 
			
			// 사진10번 변수를 쓰는건 상관없는데 
			request.setAttribute("dto", dto);
			request.setAttribute("pageNum", pageNum);
			request.setAttribute("params", param);
			request.setAttribute("searchKey", searchKey);
			request.setAttribute("searchValue", searchValue);
			return "bbs/updated";
	}
	@RequestMapping(value = "/updated_ok.action",
			method = {RequestMethod.GET,RequestMethod.POST})
	public String updated_ok(BoardDTO dto, HttpServletRequest request, HttpServletResponse response) throws Exception{
	
		// getparameter 요청 = 나 이거 줘 ! 
					String pageNum = request.getParameter("pageNum");	
					String searchKey = request.getParameter("searchKey");
					String searchValue = request.getParameter("searchValue");
					
					// dto가 매개변수로 넘어온다.
					// 왜 폼양식으로 ? created.jsp에서 hidden으로 넘겨와서 자동으로 dto에 들어감
					dao.updateData(dto);
					
					String param = "pageNum="+pageNum;
					
					if(searchValue!=null&&!searchValue.equals("")) {
						param += "&searchKey=" + searchKey;
						param += "&searchValue=" + URLEncoder.encode(searchValue,"UTF-8");
						
					}
					// 가상주소로 이동시킨다.
					// req.setAttribute("params", param);
					// 위에 para자체는 못넘김 왜 ? 이미 쓰이고있는 변수이니까
					
					// 여기서 param는 안에 들어가있는 경로가 들어가있다. 써도된다.
					
					// 사진12
					
					
					// 작업을 끝내서 list.do로 이동 ( sendRedirect )
					
					// 넘어가는 데이터가없으므로 modelandview 쓸필요가 없다
					// modelandview는 데이터와 경로를 넘겨주기때문에
					// 리다이렉트로 넘겨주면됨 
					return "redirect:/list.action?"+param;
		
	}
	
	@RequestMapping(value = "/deleted_ok.action",
			method = {RequestMethod.GET,RequestMethod.POST})
	public String deleted_ok(HttpServletRequest request, HttpServletResponse response) throws Exception{

		// pagenum , 설치키 , 설치 벨류 가져와 
					int num = Integer.parseInt(request.getParameter("num"));	
					String pageNum = request.getParameter("pageNum");
					String searchKey = request.getParameter("searchKey");
					String searchValue = request.getParameter("searchValue");
					
					dao.deleteData(num);
					
					// 돌아갈곳
					String param = "pageNum="+pageNum;
					if(searchValue!=null&&!searchValue.equals("")) {
						param += "&searchKey=" + searchKey;
						param += "&searchValue=" + 
						URLEncoder.encode(searchValue,"UTF-8");
					}
					
					
			return "redirect:/list.action?" + param;
					
		}
	}

 

 

list.jsp  게시판의 리스트를 보여줌 

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
	
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>게 시 판</title>

<link rel="stylesheet" type="text/css" href="/springwebmybatis/resources/css/style.css"/>
<link rel="stylesheet" type="text/css" href="/springwebmybatis/resources/css/list.css"/>

<script type="text/javascript">

	function sendIt() {
		
		var f = document.searchForm;
		f.action = "<%=cp%>/list.action";   /* 자기자신호출하면서 검색된결과가 보여짐 */
		f.submit();
	}

</script>

</head>
<body>

<div id="bbsList">

	<div id="bbsList_title">
		게 시 판 
	</div>
	<div id="bbsList_header">
		<div id="leftHeader">
		<form action="" method="post" name="searchForm">
			<select name="searchKey" class="selectField">
				<option value="subject">제목</option>
				<option value="name">작성자</option>
				<option value="content">내용</option>
			</select>
			<input type="text" name="searchValue" class="textField"/>
			<input type="button" value=" 검 색 " class="btn2" onclick="sendIt()"/>		
		</form>				
		</div>
		<div id="rightHeader">
			<input type="button" value=" 글올리기 " class="btn2" onclick="javascript:location.href='<%=cp %>/created.action';"/>			
		</div>	
	</div>
	<div id="bbsList_list">
		<div id="title">
			<dl>
				<dt class="num">번호</dt>
				<dt class="subject">제목</dt>
				<dt class="name">작성자</dt>
				<dt class="created">작성일</dt>
				<dt class="hitCount">조회수</dt>
			</dl>
		</div>
		<div id="lists">
		<!-- 자기만의 태그를 만들어서 공통적인 표준을 만든게 jstl  -->
		<!--  jstl를 쓸수있게 위에 taglib ~ 선언한다.
		  -->
		  <!-- jstl 확장for문 사용  3번사진을 대신해서 사용하는것  -->
		  
		  <!-- lists에 하나꺼내서 출력 -->
		  <!-- el은 dto에 만들어진 변수명 그대로 받을수있다. -->
		  <!-- 그렇다고 getter setter를 지우면 안된다. -->
		  <c:forEach var="dto" items="${lists }">
			<dl>
				<dd class="num">${dto.num }</dd>
				<dd class="subject">
				<a href="${articleUrl}&num=${dto.num}">${dto.subject }</a></dd>
				<dd class="name">${dto.name }</dd>
				<dd class="created">${dto.created }</dd>
				<dd class="hitCount">${dto.hitCount }</dd>
			</dl>
		 </c:forEach>	
		 
		</div>
		<div id="footer">
		<!-- 사진 4번 5번 -->
			<c:if test="${dataCount!=0 }">
			  ${pageIndexList } 
			 </c:if>
			 <c:if test="${dataCount==0 }">
				등록된 게시물이 없습니다.
			 </c:if>
		</div>
		
	</div>
	
</div>

</body>
</html>

 

created.jsp - 글쓰기 페이지 

<%@ page contentType="text/html; charset=UTF-8"%>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath(); 
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>게 시 판</title>

<!--  cp 못적음 외부사람은 못들어옴 그래서 /springweb 자기스프링을 적어줌 -->
<link rel="stylesheet" type="text/css" href="/springwebmybatis/resources/css/style.css"/>  
<link rel="stylesheet" type="text/css" href="/springwebmybatis/resources/css/created.css"/>

<script type="text/javascript" src="/springwebmybatis/resources/js/util.js"></script>
<script type="text/javascript">

	function sendIt(){
		
		var f = document.myForm;
		
		str = f.subject.value;
		str = str.trim();
		if(!str){
			alert("\n제목을 입력하세요.");
			f.subject.focus();
			return;
		}
		f.subject.value = str;
		str = f.name.value;
		str = str.trim();
		if(!str){
			alert("\n이름을 입력하세요.");
			f.name.focus();
			return;
		}		
		
		// 한글을 입력해야하기때문에 주석처리함 
		/* if(!isValidKorean(str)){
			alert("\n이름을 정확히 입력하세요.");
			f.name.focus()
			return;
		}*/
		f.name.value = str;
		if(f.email.value){
			if(!isValidEmail(f.email.value)){
				alert("\n정상적인 E-Mail을 입력하세요.");
				f.email.focus();
				return;
			}
		}

		str = f.content.value;
		str = str.trim();
		if(!str){
			alert("\n내용을 입력하세요.");
			f.content.focus();
			return;
		}
		f.content.value = str;
		
		str = f.pwd.value;
		str = str.trim();
		if(!str){
			alert("\n패스워드를 입력하세요.");
			f.pwd.focus();
			return;
		}
		f.pwd.value = str;
		
	
		//등록하기하면 created_ok 로 넘어가게 한다.
		// 포워딩할때만 진짜주소 
		// 나머지는 가상주소
		
		// sboard/* -> BoardServlet 으로 간다
		f.action = "<%=cp%>/created_ok.action";
		f.submit();
	}
</script>
</head>
<body>

<div id="bbs">
	<div id="bbs_title">
		게 시 판 (Servlet)
	</div>
	
	<form action="" method="post" name="myForm">
	<div id="bbsCreated">
		
		<div class="bbsCreated_bottomLine">
			<dl>
				<dt>제&nbsp;&nbsp;&nbsp;&nbsp;목</dt>
				<dd>
				<input type="text" name="subject" size="60" 
				maxlength="100" class="boxTF"/>
				</dd>
			</dl>		
		</div>
		
		
		
		<!-- 작성자 ------------로그인햇으면 세션스코프 정보 불러오기  -->
		
		<div class="bbsCreated_bottomLine">
			<dl>
				<dt>작성자</dt>
				<dd>
				<input type="text" name="name" size="35" 
				maxlength="20" class="boxTF"/>
				</dd>
			</dl>		
		</div>
		
		<!-----------------------------------------------------------  -->
		
		<div class="bbsCreated_bottomLine">
			<dl>
				<dt>E-Mail</dt>
				<dd>
				<input type="text" name="email" size="35" 
				maxlength="50" class="boxTF"/>
				</dd>
			</dl>		
		</div>
		
		<div id="bbsCreated_content">
			<dl>
				<dt>내&nbsp;&nbsp;&nbsp;&nbsp;용</dt>
				<dd>
				<textarea rows="12" cols="63" name="content"
				class="boxTA"></textarea>
				</dd>
			</dl>
		</div>
		
		<div class="bbsCreated_noLine">
			<dl>
				<dt>패스워드</dt>
				<dd>
				<input type="password" name="pwd" size="35" 
				maxlength="7" class="boxTF"/>
				&nbsp;(게시물 수정 및 삭제시 필요!!)
				</dd>
			</dl>		
		</div>	
	</div>
	<div id="bbsCreated_footer">
		<input type="button" value=" 등록하기 " class="btn2" onclick="sendIt();"/>
		<input type="reset" value=" 다시입력 " class="btn2" 
		onclick="document.myForm.subject.focus();"/>
		<input type="button" value=" 작성취소 " class="btn2" onclick="javascript:location.href='<%=cp %>/list.action';"/> <!-- 루트경로가져올시 안에 작은따옴표; 에 큰따옴표로 묶어줌 -->
	</div>
	</form>
</div>
</body>
</html>

 

article.jsp - 글 상세 페이지 

<%@ page contentType="text/html; charset=UTF-8"%>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>게 시 판</title>

<link rel="stylesheet" type="text/css" href="/springwebmybatis/resources/css/style.css"/>
<link rel="stylesheet" type="text/css" href="/springwebmybatis/resources/css/article.css"/>

</head>
<body>
<!-- 서블릿으로 넘어온건 다이렉트로 dto.변수명으로 받는다 -->
<div id="bbs">
	
	<div id="bbs_title">
		게 시 판 
	</div>
	<div id="bbsArticle">	
		<div id="bbsArticle_header">
			${dto.subject }
		</div>
		
		<div class="bbsArticle_bottomLine">
			<dl>
				<dt>작성자</dt>
				<dd>${dto.name }</dd>
				<dt>${lineSu }</dt>
				<dd>15</dd>
			</dl>		
		</div>
		
		<div class="bbsArticle_bottomLine">
			<dl>
				<dt>등록일</dt>
				<dd>${dto.created }</dd>
				<dt>조회수</dt>
				<dd>${dto.hitCount }</dd>
			</dl>		
		</div>
		
		<div id="bbsArticle_content">
			<table width="600" border="0">
			<tr>
				<td style="padding-left: 20px 80px 20px 62px;" 
				valign="top" height="200">
				${dto.content }
				</td>
			</tr>			
			</table>
		</div>
	</div>
	<div class="bbsArticle_noLine" style="text-align: right">
	From : ${dto.ipAddr }
	</div>
	
	<div id="bbsArticle_footer">
		<div id="leftFooter">
			<!-- 특정 num값을 가지고 들어가면서 설치키도,설치벨류 가지고 들어감  -->
			<input type="button" value=" 수정 " class="btn2" 
			onclick="javascript:location.href='<%=cp%>/updated.action?num=${dto.num }&${params }'"/>
			<input type="button" value=" 삭제 " class="btn2" 
			onclick="javascript:location.href='<%=cp%>/deleted_ok.action?num=${dto.num }&${params }'"/>
		</div>
		<div id="rightFooter">
			<input type="button" value=" 리스트 " class="btn2" 
			onclick="javascript:location.href='<%=cp%>/list.action?${params }';"/>
			<!-- 검색했다면 설치키,설치벨류도 가지고 나감 -->
			<!-- 설치키 설치벨류는 param 이 가지고 있다. -->
		</div>	
	</div>
</div>
</body>
</html>

 

updated.jsp  - 수정 페이지 

 

<%@ page contentType="text/html; charset=UTF-8"%>
<%
	request.setCharacterEncoding("UTF-8");
	String cp = request.getContextPath();
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>게 시 판</title>

<link rel="stylesheet" type="text/css" href="/springwebmybatis/resources/css/style.css"/>
<link rel="stylesheet" type="text/css" href="/springwebmybatis/resources/css/created.css"/>

<script type="text/javascript" src="/springwebmybatis/resources/js/util.js"></script>
<script type="text/javascript">

	function sendIt(){
		
		var f = document.myForm;
		
		str = f.subject.value;
		str = str.trim();
		if(!str){
			alert("\n제목을 입력하세요.");
			f.subject.focus();
			return;
		}
		f.subject.value = str;
		str = f.name.value;
		str = str.trim();
		if(!str){
			alert("\n이름을 입력하세요.");
			f.name.focus();
			return;
		}		
		
		// 한글을 입력해야하기때문에 주석처리함 
		/* if(!isValidKorean(str)){
			alert("\n이름을 정확히 입력하세요.");
			f.name.focus()
			return;
		}*/
		f.name.value = str;
		if(f.email.value){
			if(!isValidEmail(f.email.value)){
				alert("\n정상적인 E-Mail을 입력하세요.");
				f.email.focus();
				return;
			}
		}

		str = f.content.value;
		str = str.trim();
		if(!str){
			alert("\n내용을 입력하세요.");
			f.content.focus();
			return;
		}
		f.content.value = str;
		
		str = f.pwd.value;
		str = str.trim();
		if(!str){
			alert("\n패스워드를 입력하세요.");
			f.pwd.focus();
			return;
		}
		f.pwd.value = str;
		
	
		//등록하기하면 created_ok 로 넘어가게 한다.
		// 포워딩할때만 진짜주소 
		// 나머지는 가상주소
		f.action = "<%=cp%>/updated_ok.action";
		f.submit();
	}
</script>
</head>
<body>

<div id="bbs">
	<div id="bbs_title">
		게 시 판
	</div>
	
	<form action="" method="post" name="myForm">
	<div id="bbsCreated">
		
		<div class="bbsCreated_bottomLine">
			<dl>
				<dt>제&nbsp;&nbsp;&nbsp;&nbsp;목</dt>
				<dd>
				<input type="text" name="subject" value="${dto.subject}"
				 size="60" 
				maxlength="100" class="boxTF"/>
				</dd>
			</dl>		
		</div>
		
		<div class="bbsCreated_bottomLine">
			<dl>
				<dt>작성자</dt>
				<dd>
				<input type="text" name="name" value="${dto.name }" size="35" 
				maxlength="20" class="boxTF"/>
				</dd>
			</dl>		
		</div>
		
		<div class="bbsCreated_bottomLine">
			<dl>
				<dt>E-Mail</dt>
				<dd>
				<input type="text" name="email" value="${dto.email }" size="35"  
				maxlength="50" class="boxTF"/>
				</dd>
			</dl>		
		</div>
		<div id="bbsCreated_content">
			<dl>
				<dt>내&nbsp;&nbsp;&nbsp;&nbsp;용</dt>
				<dd>
				<textarea rows="12" cols="63" name="content" 
				class="boxTA">${dto.content }</textarea>
				</dd>
			</dl>
		</div>
		
		<div class="bbsCreated_noLine">
			<dl>
				<dt>패스워드</dt>
				<dd>
				<input type="password" name="pwd" value="${dto.pwd }" size="35" 
				maxlength="7" class="boxTF"/>
				&nbsp;(게시물 수정 및 삭제시 필요!!)
				</dd>
			</dl>		
		</div>	
	
	</div>
	
	<div id="bbsCreated_footer">



		<!-- 수정하기를 하면 히든을 통해 값을 넘겨줘야 한다.  -->
		<!-- 사진10, 사진11 , 사진12  -->
		<!-- 폼안에서 넘기는건 post방식이므로 주소값에 안보인다. -->
		
		
		<!-- 자동으로 num 이 히든으로 넘어온다. -->
		<input type="hidden" name="num" value="${dto.num }"/>
		<input type="hidden" name="pageNum" value="${pageNum }"/>
		<input type="hidden" name="searchKey" value="${searchKey }"/>
		<input type="hidden" name="searchValue" value="${searchValue }"/>

		<input type="button" value=" 수정하기 " class="btn2" onclick="sendIt();"/>
		<input type="button" value=" 수정취소 " class="btn2" onclick="javascript:location.href='<%=cp %>/list.action?${params }';"/> <!-- 검색을안했으면 pageNum만 검색했으면 pagenum,설치키,설치벨류 넘어간다 --> 
	</div>
	</form>
</div>
</body>
</html>