@RequestMapping("detail")
  public String detail(int no, Model model) throws Exception {

    Project project = projectDao.selectOne(no);
    model.addAttribute("project", project);

    return "project/ProjectDetail";
  }
  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    try {
      int pageNo = 1;
      int pageSize = 10;
      if (request.getParameter("pageNo") != null) {
        pageNo = Integer.parseInt(request.getParameter("pageNo"));
      }
      if (request.getParameter("pageSize") != null) {
        pageSize = Integer.parseInt(request.getParameter("pageSize"));
      }

      String keyword = "no";
      String align = "desc";
      if (request.getParameter("keyword") != null) {
        keyword = request.getParameter("keyword");
      }
      if (request.getParameter("align") != null) {
        align = request.getParameter("align");
      }
      response.setContentType("text/plain;charset=UTF-8");
      PrintWriter out = response.getWriter();
      out.printf("%-3s %-20s %-10s %-10s %-40s\n", "No", "Title", "Start", "End", "Members");
      ApplicationContext iocContext =
          (ApplicationContext) this.getServletContext().getAttribute("iocContainer");
      ProjectDao projectDao = iocContext.getBean(ProjectDao.class);
      for (Project project : projectDao.selectList(pageNo, pageSize, keyword, align)) {
        out.printf(
            "% 3d %-20s %3$tY-%3$tm-%3$td %4$s %5$-40s\n",
            project.getNo(),
            project.getTitle(),
            project.getStartDate(),
            project.getEndDate(),
            project.getMember());
      }
      RequestDispatcher rd = request.getRequestDispatcher("/copyright");
      rd.include(request, response);
    } catch (Exception e) {
      RequestDispatcher rd = request.getRequestDispatcher("/error");
      rd.forward(request, response);
    }
  }
  @RequestMapping("delete")
  public String delete(int no, Model model) throws Exception {

    if (projectDao.delete(no) <= 0) {
      model.addAttribute("errorCode", "401");
      return "/project/ProjectAuthError.jsp";
    }

    return "redirect:list.do";
  }
  @RequestMapping(value = "add", method = RequestMethod.POST)
  public String add(String title, String startDate, String endDate, String member)
      throws Exception {

    Project project = new Project();
    project.setTitle(title);
    project.setStartDate(Date.valueOf(startDate));
    project.setEndDate(Date.valueOf(endDate));
    project.setMember(member);

    projectDao.insert(project);

    return "redirect:list.do";
  }
  @RequestMapping("update")
  public String update(
      int no, String title, String startDate, String endDate, String member, Model model)
      throws Exception {
    Project project = new Project();
    project.setTitle(title);
    project.setStartDate(Date.valueOf(startDate));
    project.setEndDate(Date.valueOf(endDate));
    project.setMember(member);
    project.setNo(no);

    if (projectDao.update(project) <= 0) {
      model.addAttribute("errorCode", "401");
      return "project/ProjectAuthError";
    }

    return "redirect:list.do";
  }
  @RequestMapping("list")
  public String list(
      @RequestParam(defaultValue = "1") int pageNo,
      @RequestParam(defaultValue = "10") int pageSize,
      @RequestParam(defaultValue = "no") String keyword,
      @RequestParam(defaultValue = "desc") String align,
      Model model)
      throws Exception {

    HashMap<String, Object> paramMap = new HashMap<>();
    paramMap.put("startIndex", (pageNo - 1) * pageSize);
    paramMap.put("length", pageSize);
    paramMap.put("keyword", keyword);
    paramMap.put("align", align);

    List<Project> projects = projectDao.selectList(paramMap);

    model.addAttribute("projects", projects);

    return "project/ProjectList";
  }
  @Override
  public void service(HashMap<String, Object> params) {
    int pageNo = 1;
    int pageSize = 10;

    if (params.get("pageNo") != null) {
      pageNo = Integer.parseInt((String) params.get("pageNo"));
    }

    if (params.get("pageSize") != null) {
      pageSize = Integer.parseInt((String) params.get("pageSize"));
    }

    // 정렬 처리
    String keyword = "no";
    String align = "desc";

    if (params.get("keyword") != null) {
      keyword = (String) params.get("keyword");
    }

    if (params.get("align") != null) {
      align = (String) params.get("align");
    }

    PrintStream out = (PrintStream) params.get("out");
    out.printf("%-3s %-20s %-10s %-10s %-40s\n", "No", "Title", "Start", "End", "Members");

    for (Project project : projectDao.selectList(pageNo, pageSize, keyword, align)) {
      out.printf(
          "% 3d %-20s %3$tY-%3$tm-%3$td %4$s %5$-40s\n",
          project.getNo(),
          project.getTitle(),
          project.getStartDate(),
          project.getEndDate(),
          project.getMember());
    }
  }