2016년 10월 17일 월요일

[자바강의,스프링강의,IT실무교육_탑크리에듀]3.(스프링4 답변형게시판)[컨트롤러, AOP,미리보기서블릿]Spring JDBC]Spring4@MVC-멀티파일업로드,답변형,JSR303

첨부파일 URL참조 - http://ojc.asia/bbs/board.php?bo_table=LecSpring&wr_id=432

3.(스프링4 답변형게시판)[컨트롤러, AOP,미리보기서블릿]Spring JDBC]Spring4@MVC-멀티파일업로드,답변형,JSR303 @Valid,@Controller,@ModelAttribute,@SessionAttributes,어노테이션기반,자바교육,스프링학원

스프링프레임워크 실무교육 오라클자바커뮤니티교육센터(www.ojcedu.com)에서 받으세요~

1. 리스트보기에서 본문 미리보기용 서블릿(ajax)


package onj.board.ajaxpreview;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import onj.board.service.BoardService;
import onj.board.service.BoardServiceHelper;

//Servlet3.0이상, Tomcat7 이상에서는 애노테이션으로 서블릿 정의가 가능하다.
@WebServlet(urlPatterns = "/preView")
public class ContentPreview extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
String seq = req.getParameter("seq");
req.setCharacterEncoding("utf-8");
res.setContentType("text/html; charset=utf-8");
res.setHeader("Cache-Control",  "no-cache");
BoardService boardService = BoardServiceHelper.getBoardService(getServletContext());
PrintWriter out = res.getWriter();
out.println("<pre>" + boardService.preView(seq) + "<pre>");
}
}








2. Spring AOP용 Aspect클래스

[onj.board.aop.LoggingAspect.java]

package onj.board.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
 
@Service
@Aspect
public class LoggingAspect {

private final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);

// 사전충고
// Spring Framework의 JdbcOperations을 포인트컷으로 해서 모든 SQL에 대해 로깅 충고가 적용
@Before("execution(* org.springframework.jdbc.core.JdbcOperations.*(String, ..))")    
public void logBefore(JoinPoint joinPoint) {
logger.info("<<<<<<<<<<<<<<<<< DAO 로깅 충고 실행");

Object[] methodArgs = joinPoint.getArgs(), sqlArgs = null;
// 실행시킨 SQL 문장
String statement = methodArgs[0].toString();   // ? 가 포함된 SQL문

// find the SQL arguments (parameters)
for (int i = 1, n = methodArgs.length; i < n; i++) {
Object arg = methodArgs[i];
if (arg instanceof Object[]) {
sqlArgs = (Object[]) arg;
break;
}
}
// '?' 대신 파라미터로 대체
   String completedStatement = (sqlArgs == null ? 
    statement : fillParameters(statement, sqlArgs));
   
   logger.info(completedStatement);
}
//SQL문장의 ?를 넘겨주는 파라미터로 대체해서 최종SQL문을 리턴
private String fillParameters(String statement, Object[] sqlArgs) {
   // initialize a StringBuilder with a guesstimated final length
   StringBuilder completedSqlBuilder = new StringBuilder(Math.round(statement.length() * 1.2f));
   int index, // will hold the index of the next ?
   prevIndex = 0; // will hold the index of the previous ? + 1
 
   // loop through each SQL argument
   for (Object arg : sqlArgs) {
       index = statement.indexOf("?", prevIndex);
       if (index == -1)
           break; // bail out if there's a mismatch in # of args vs. ?'s
 
       // append the chunk of SQL coming before this ?
       completedSqlBuilder.append(statement.substring(prevIndex, index));
       // append the replacement for the ?
       if (arg == null)
           completedSqlBuilder.append("NULL");
       else
           completedSqlBuilder.append(":"+arg.toString());
 
       prevIndex = index + 1;
   }
 
   // add the rest of the SQL if any
   if (prevIndex != statement.length())
       completedSqlBuilder.append(statement.substring(prevIndex));
 
   return completedSqlBuilder.toString();
}
}


3. 컨트롤러


package onj.board.controller;

import java.io.File;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import onj.board.model.BoardDTO;
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.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author 오라클자바커뮤니티
 * Spring @MVC 게시판 컨트롤러
 * - 글입력(멀티파일업로드), 글수정, 글삭제, 글리스트보기
 * - 답변글 쓰기
 * - 커멘트 쓰기
 * - @ModelAttribute, @SessionAttributes를 사용해 전반적으로 컨트롤러가 단순해졌다.
 */
@Controller
@SessionAttributes("read")   //게시물읽기에서 읽은 게시물을 수정을 위해 세션에 보관
public class BoardMultiController {
@Autowired
private BoardService boardService;

// 게시판 리스트 보기, 페이징 기능은 구현 안함
@RequestMapping("/list")
public ModelAndView list() {
ModelAndView mv = new ModelAndView("list", "list",
boardService.boardList());

return mv;
}

// 게시글 읽기
@RequestMapping("/read")
public String read(@RequestParam("seq") String seq, Model model) {

// 게시물 한건 내용, "read"라는 이름으로 세션에 저장된다.(@SessionAttributes)
model.addAttribute("read", boardService.readContent(seq));

// comments(ArrayList에 CommentDTO가 담겨져 있다.)
model.addAttribute("comments", boardService.commentList(seq));

return "read";
}

// 커멘트쓰기
@RequestMapping("/comment")
public ModelAndView comment(@ModelAttribute CommentDTO commentDTO,
                    @ModelAttribute BoardDTO read) {
boardService.insertComment(commentDTO);
return new ModelAndView("redirect:/read.html?seq=" + read.getSeq());
}

// 게시판 글쓰기 화면
@RequestMapping(value = "/write", method = RequestMethod.GET)
public String write_view(Model model) {
if (!model.containsAttribute("uploadForm")) {
model.addAttribute("uploadForm", new BoardDTO());
}
return "write";
}

/****************************************************************
* 새글(게시글) 입력 기존 게시판과 다르게 
* Spring MVC의 MultipartFile upload 기능을 이용 다중파일업로드 구현
* @ModelAttribute적용
***************************************************************/
@RequestMapping(value = "/writeok", method = RequestMethod.POST)
public ModelAndView writeok(
@ModelAttribute("uploadForm") @Valid BoardDTO uploadForm ,
BindingResult result ) throws Exception {

if (result.hasErrors()) return new ModelAndView("write");
// 먼저 파일 업로드, 폴더는 미리 만드세요
// 스프링의 MultipartFile을 이용한 업로드
List<MultipartFile> files = uploadForm.getFiles();

if (null != files && files.size() > 0) {
int i = 0;
for (MultipartFile multipartFile : files) {
i++;
String fileName = multipartFile.getOriginalFilename();
if (!"".equals(fileName)) {
String path = "c:/java/project/spring4board/upload/"
+ fileName;

File f = new File(path);

multipartFile.transferTo(f);
if (i == 1) {
uploadForm.setFileName1(fileName);
} else if (i == 2) {
uploadForm.setFileName2(fileName);
} else if (i == 3) {
uploadForm.setFileName3(fileName);
}
}
}
}
boardService.insertBoard(uploadForm);
return new ModelAndView("redirect:/list.html");
}

// 게시글 수정, 세션에 있는 read 객체(BoardDTO, 게시물한건)가
// 사용자 파라미터 값을 받아 인자로 삽입된다.
@RequestMapping("/update")
public ModelAndView update(@ModelAttribute BoardDTO read) {
boardService.updateBoard(read);
return new ModelAndView("redirect:/read.html?seq=" + read.getSeq());
}

// 게시글 삭제
@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");
}
}

// 게시물상세보기에서 답변 클릭시 호출되어 답변달 reply.jsp로 연결
@RequestMapping("/reply")
public String reply(Model model) {
if (!model.containsAttribute("replyForm")) {
model.addAttribute("replyForm", new BoardDTO());
}
return "reply";
}

// 답글 저장
@RequestMapping("/replyok")
public ModelAndView replyok(@ModelAttribute("replyForm") @Valid BoardDTO replyForm,
                   BindingResult result) {
if (result.hasErrors()) return new ModelAndView("reply");
boardService.replyBoard(replyForm);
return new ModelAndView("redirect:/list.html");
}
}

댓글 없음:

댓글 쓰기