728x90

wirte.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:set var="root" value="${pageContext.request.contextPath }/"/>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>우리반 화이팅</title>
    <!-- Bootstrap CDN -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
</head>
<body>
<c:import url="/WEB-INF/views/include/top_menu.jsp"/>

<div class="container" style="margin-top: 100px">
    <div class="card shadow">
        <div class="card-body">
            <form:form action="${root }board/wrtie_pro" method="post" modelAttribute="writeBean">
             <form:hidden path="contest_board_idx"/>
                <div class="form-group">
                    <form:label for="content_subject">제목</form:label>
                    <form:input path="content_subject" class="form-control"/>
                    <form:errors path="content_subject" style='color:red'/>

                </div>

                <div class="form-group">
                    <form:label for="content_text">내용</form:label>
                    <form:textarea class="form-control" path="content_text"
                                   rows="10" style="resize:none"/>
                    <form:errors path="content_text" style='color:red'/>
                </div>

                <div class="form-group">
                    <div class="text-right">
                        <form:button class="btn btn-primary">작성하기</form:button>
                    </div>
                </div>
            </form:form>
        </div>
    </div>
</div>

<c:import url="/WEB-INF/views/include/bottom_menu.jsp"/>


</body>
</html>

 

BoardController

package kr.bit.controller;

import kr.bit.beans.Content;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
@RequestMapping("/board")
public class BoardController {

    @GetMapping("/main")
    public String main(@RequestParam("board_info_idx") int board_info_idx,
                   Model model) {
       model.addAttribute("board_info_idx", board_info_idx);
       return "board/main";
    }
    
    @GetMapping("/read")
    public String read() {
       return "board/read";
    }
    
    @GetMapping("/write")
    public String write(@ModelAttribute("writeBean") Content writeBean,
                   @RequestParam("board_info_idx") int board_info_idx) {
       
       return "board/write";
    }
    
    @GetMapping("/modify")
    public String modify() {
       return "board/modify";
    }
    
    @GetMapping("/delete")
    public String delete() {
       return "board/delete";
    }
}

main.jsp

아래와 같이 코드 변경

<div class="text-right">
    <a href="${root }board/write?board_info_idx=${board_info_idx}" class="btn btn-primary">글쓰기</a>
</div>  

 

2팀을 누르고 글쓰기하는경우 board_info_idx=[값]이 잘 적용된 모습


Content

@NotBlank 추가해서 유효성검사 추가!(붙여서 위아래 놔도 구분되어 들어감)

package kr.bit.beans;

import javax.validation.constraints.NotBlank;

public class Content {
    
    @NotBlank
    private int content_idx;

    @NotBlank
    private String content_subject;
    
    private String content_text;
    private int content_writer_idx;
    private int content_board_idx;
    private String content_date;
    
    public int getContent_idx() {
       return content_idx;
    }
    public void setContent_idx(int content_idx) {
       this.content_idx = content_idx;
    }
    public String getContent_subject() {
       return content_subject;
    }
    public void setContent_subject(String content_subject) {
       this.content_subject = content_subject;
    }
    public String getContent_text() {
       return content_text;
    }
    public void setContent_text(String content_text) {
       this.content_text = content_text;
    }
    public int getContent_writer_idx() {
       return content_writer_idx;
    }
    public void setContent_writer_idx(int content_writer_idx) {
       this.content_writer_idx = content_writer_idx;
    }
    public int getContent_board_idx() {
       return content_board_idx;
    }
    public void setContent_board_idx(int content_board_idx) {
       this.content_board_idx = content_board_idx;
    }
    public String getContent_date() {
       return content_date;
    }
    public void setContent_date(String content_date) {
       this.content_date = content_date;
    }
    
    
    

}

 

BoardController

write 부분 변경 및 추가

@GetMapping("/write")
public String write(@ModelAttribute("writeBean") Content writeBean,
                    @RequestParam("board_info_idx") int board_info_idx) {

    return "board/write";
}

@PostMapping("/write_pro")
public String write_pro(@Valid @ModelAttribute("writeBean") Content writeBean,
                      BindingResult result) {
    if (result.hasErrors()) {
        return "board/write";
    }
    return "board/write_success";
}

 

 

전체코드

 

package kr.bit.controller;

import kr.bit.beans.Content;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@Controller
@RequestMapping("/board")
public class BoardController {

    @GetMapping("/main")
    public String main(@RequestParam("board_info_idx") int board_info_idx,
                       Model model) {
        model.addAttribute("board_info_idx", board_info_idx);
        return "board/main";
    }

    @GetMapping("/read")
    public String read() {
        return "board/read";
    }

    @GetMapping("/write")
    public String write(@ModelAttribute("writeBean") Content writeBean,
                        @RequestParam("board_info_idx") int board_info_idx) { // 글쓰기 할 팀 세팅

        return "board/write";
    }

    @PostMapping("/write_pro")
    public String write_pro(@Valid @ModelAttribute("writeBean") Content writeBean,
                          BindingResult result) {
        if (result.hasErrors()) {
            return "board/write";
        }
        return "board/write_success";
    }


    @GetMapping("/modify")
    public String modify() {
        return "board/modify";
    }

    @GetMapping("/delete")
    public String delete() {
        return "board/delete";
    }
}

BoardMapper

package kr.bit.mapper;

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Options;

public interface BoardMapper {

    //mysql에서 sql 매퍼에 추가되는 옵션설정할 때 사용하는 애노테이션
    // useGeneratedKeys = true : 자동으로 생성하는 키 값을 mybatis가 사용할 수 있도록 허용
    @Options(useGeneratedKeys = true, keyProperty = "content_idx")

    @Insert("INSERT INTO content_table(content_subject, content_text, content_writer_idx, content_board_idx, content_date) " +

            "VALUES (#{content_subject}, #{content_text}, #{content_writer_idx}, #{content_board_idx}, CURRENT_DATE())")
    void addContent(Content writeContentBean);

}

 

BoardDao

package kr.bit.dao;

import kr.bit.beans.Content;
import kr.bit.mapper.BoardMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class BoardDao {

    @Autowired
    private BoardMapper boardMapper;

    public void addContent(Content writeContntBean) {
        boardMapper.addContent(writeContntBean);

    }

}

 

BoardService

package kr.bit.service;

import javax.annotation.Resource;

import kr.bit.beans.Content;
import kr.bit.beans.User;
import kr.bit.dao.BoardDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class BoardService {

    @Autowired
    private BoardDao boardDao;

    @Resource(name="loginBean")
    private User loginBean;

    public void addContent(Content writeContentBean) {
        // 제목 내용 저장하는

        // 로그인 한 사람의 idx값을 가져와 글작성자 idx값 세팅
        writeContentBean.setContent_writer_idx(loginBean.getUser_idx());
        boardDao.addContent(writeContentBean);


    }



}

 

BoardController

추가

@Controller
@RequestMapping("/board")
public class BoardController {

    @Autowired
    private BoardService boardService;

 

 

write_success 생성

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<c:set var="root" value="${pageContext.request.contextPath }/"/>

<script>
    alert('저장되었습니다.')
    location.href = "${root}board/read?board_info_idx=${writeBean.content_board_idx}&content_idx=${writeBean.content_idx}"
</script>

BoardMapper

package kr.bit.mapper;

import kr.bit.beans.Content;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Select;

public interface BoardMapper {

    //mysql에서 sql 매퍼에 추가되는 옵션설정할 때 사용하는 애노테이션
    // useGeneratedKeys = true : 자동으로 생성하는 키 값을 mybatis가 사용할 수 있도록 허용
    @Options(useGeneratedKeys = true, keyProperty = "content_idx")
    @Insert("INSERT INTO content_table(content_subject, content_text, content_writer_idx, content_board_idx, content_date) " +

            "VALUES (#{content_subject}, #{content_text}, #{content_writer_idx}, #{content_board_idx}, CURRENT_DATE())")
    void addContent(Content writeContentBean);

    @Select("select board_info_name from board_infor_table where board_info_idx=#{board_info_idx}")
    String getBoardName(int board_info_idx);
}

BoardDao

package kr.bit.dao;

import kr.bit.beans.Content;
import kr.bit.mapper.BoardMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class BoardDao {

    @Autowired
    private BoardMapper boardMapper;

    public void addContent(Content writeContntBean) {
        boardMapper.addContent(writeContntBean);

    }

    public String getBoardName(int board_info_idx) {
        return boardMapper.getBoardName(board_info_idx);
    }

}

BoardService

package kr.bit.service;

import javax.annotation.Resource;

import kr.bit.beans.Content;
import kr.bit.beans.User;
import kr.bit.dao.BoardDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class BoardService {

    @Autowired
    private BoardDao boardDao;

    @Resource(name = "loginBean")
    private User loginBean;

    public void addContent(Content writeContentBean) {
        // 제목 내용 저장하는

        // 로그인 한 사람의 idx값을 가져와 글작성자 idx값 세팅
        writeContentBean.setContent_writer_idx(loginBean.getUser_idx());
        boardDao.addContent(writeContentBean);

    }

    public String getBoardName(int board_info_idx) {
        return boardDao.getBoardName(board_info_idx);
    }


}

 

BoardController

코드 추가

public class BoardController {

    @Autowired
    private BoardService boardService;

    @GetMapping("/main")
    public String main(@RequestParam("board_info_idx") int board_info_idx,
                       Model model) {
        model.addAttribute("board_info_idx", board_info_idx);

        String boardName=boardService.getBoardName(board_info_idx);
        model.addAttribute("boardName", boardName);

        return "board/main";
    }

 

Board/Main.jsp

이름 변경되면 받아올 수 있도록 코드 변경

<div class="container" style="margin-top: 100px">
    <div class="card shadow">
       <div class="card-body">
          <h3 class="card-title">${boardName }</h3>
          <table class="table table-hover" id="board_list">
             <thead>
             <tr>

페이지 작업

Content

@Getter, @Setter

private String content_writer_name;

 

BoardDao(RowBound)

package kr.bit.dao;

import kr.bit.beans.Content;
import kr.bit.mapper.BoardMapper;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public class BoardDao {

    @Autowired
    private BoardMapper boardMapper;

    public void addContent(Content writeContntBean) {
        boardMapper.addContent(writeContntBean);

    }

    public String getBoardName(int board_info_idx) {
        return boardMapper.getBoardName(board_info_idx);
    }

    public List<Content> getContent(int board_info_idx, RowBounds rowBounds){
        return boardMapper.getContent(board_info_idx, rowBounds.getOffset(), rowBounds.getLimit());
    }

}

 

option.properties

추가

page.listcount=10
page.pa=10

 

BoardService

프로퍼티 소스 추가

밸류 추가

페이징 작업 소스 추가

@Service
@PropertySource("/WEB-INF/properties/option.properties")
public class BoardService {

    @Value("${page.listcount")
    private int page_listcount;

    @Value("${page.pa}")
    private int page_pa;

    public List<Content> getContent(int board_info_idx, int page){
        int start=(page-1)*page_listcount;

        RowBounds rowBounds = new RowBounds(start, page_listcount);

        return boardDao.getContent(board_info_idx, rowBounds);
//        return boardDao.getContent(board_info_idx, offset, pageSize);
    }


}

 

전체 코드

package kr.bit.service;

import javax.annotation.Resource;

import kr.bit.beans.Content;
import kr.bit.beans.User;
import kr.bit.dao.BoardDao;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;

import java.util.List;


@Service
@PropertySource("/WEB-INF/properties/option.properties")
public class BoardService {

    @Value("${page.listcount")
    private int page_listcount;

    @Value("${page.pa}")
    private int page_pa;

    @Autowired
    private BoardDao boardDao;

    @Resource(name = "loginBean")
    private User loginBean;

    public void addContent(Content writeContentBean) {
        // 제목 내용 저장하는

        // 로그인 한 사람의 idx값을 가져와 글작성자 idx값 세팅
        writeContentBean.setContent_writer_idx(loginBean.getUser_idx());
        boardDao.addContent(writeContentBean);

    }

    public String getBoardName(int board_info_idx) { // 팀 이름 추출
        return boardDao.getBoardName(board_info_idx);
    }

    public List<Content> getContent(int board_info_idx, int page){
        int start=(page-1)*page_listcount;

        RowBounds rowBounds = new RowBounds(start, page_listcount);

        return boardDao.getContent(board_info_idx, rowBounds);
//        return boardDao.getContent(board_info_idx, offset, pageSize);
    }


}

 

BoardController

코드추가

@GetMapping("/main")
public String main(@RequestParam("board_info_idx") int board_info_idx,
                   @RequestParam(value="page", defaultValue = "1") int page,
                   Model model) {
    model.addAttribute("board_info_idx", board_info_idx);

    String boardName=boardService.getBoardName(board_info_idx); // 팀명 추출 메소드
    model.addAttribute("boardName", boardName);

    List<Content> contentLi = boardService.getContent(board_info_idx, page);
    model.addAttribute("contentLi", contentLi); 게시글 목록

    return "board/main";
}

 

/Board/Main

<%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="root" value="${pageContext.request.contextPath }/"/>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Fighting, Our Class</title>
    <!-- Bootstrap CDN -->
    <link rel="stylesheet"
         href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
    <script
          src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script
          src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
    <script
          src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
</head>
<body>

<c:import url="/WEB-INF/views/include/top_menu.jsp"/>

<div class="container" style="margin-top: 100px">
    <div class="card shadow">
       <div class="card-body">
          <h3 class="card-title">${boardName }</h3>
          <table class="table table-hover" id="board_list">
             <thead>
             <tr>
                <th class="text-center d-none d-md-table-cell">Post Number</th>
                <th class="w-50">Title</th>
                <th class="text-center d-none d-md-table-cell">Writer</th>
                <th class="text-center d-none d-md-table-cell">Date</th>
             </tr>
             </thead>

             <tbody>
             <c:forEach var="obj" items="${contentLi}">
                <tr>
                   <td class="text-center d-none d-md-table-cell">${obj.content_idx}
                      </td>
                   <td class="w-50">${obj.content_subject }<
                      </td>
                   <td class="text-center d-none d-md-table-cell">${obj.content_writer_name }
                      </td>
                   <td class="text-center d-none d-md-table-cell">${obj.content_date}
                      </td>
                </tr>
             </c:forEach>

             </tbody>
          </table>

          <div class="d-none d-md-block">
             <ul class="pagination justify-content-center">
                <li class="page-item"><a class="page-link" href="#">Previous</a></li>
                <li class="page-item"><a class="page-link" href="#">1</a></li>
                <li class="page-item"><a class="page-link" href="#">2</a></li>
                <li class="page-item"><a class="page-link" href="#">3</a></li>
                <li class="page-item"><a class="page-link" href="#">4</a></li>
                <li class="page-item"><a class="page-link" href="#">5</a></li>
                <li class="page-item"><a class="page-link" href="#">6</a></li>
                <li class="page-item"><a class="page-link" href="#">7</a></li>
                <li class="page-item"><a class="page-link" href="#">8</a></li>
                <li class="page-item"><a class="page-link" href="#">9</a></li>
                <li class="page-item"><a class="page-link" href="#">10</a></li>
                <li class="page-item"><a class="page-link" href="#">Next</a></li>
             </ul>
          </div>


          <div class="d-block d-md-none">
             <ul class="pagination justify-content-center">
                <li class="page-item"><a class="page-link" href="#">Previous</a></li>
                <li class="page-item"><a class="page-link" href="#">Next</a></li>
             </ul>
          </div>

          <div class="text-right">
             <a href="${root }board/write?board_info_idx=${board_info_idx}" class="btn btn-primary">Write Post</a>
          </div>
       </div>
    </div>
    <c:import url="/WEB-INF/views/include/bottom_menu.jsp"/>
</body>
</html>
728x90
728x90

로그인 유무에 따라 상단탭 다르게 설정하기

 

ServletAppContext

    @Autowired
    private TopMenuService topMenuService; //@service

    @Resource(name="loginBean")
    private User loginBean; //로그인 여부에 따라 상단메뉴바가 다르게 보이도록 하기 위해 주입받음
//인터셉터 -> 등록
public void addInterceptors(InterceptorRegistry re) {
    WebMvcConfigurer.super.addInterceptors(re);

    TopMenuInterceptor top=new TopMenuInterceptor(topMenuService, loginBean);

    InterceptorRegistration re1=re.addInterceptor(top);//TopMenuInterceptor등록
    re1.addPathPatterns("/**"); //모든경로로 매핑해도 다 뜨도록..컨트롤러 전에 preHandle
}

위와 같이 코드 추가

아래는 전체코

package kr.bit.config;

import kr.bit.beans.User;
import kr.bit.interceptor.TopMenuInterceptor;
import kr.bit.mapper.BoardMapper;
import kr.bit.mapper.TopMenuMapper;
import kr.bit.mapper.UserMapper;
import kr.bit.service.TopMenuService;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.web.servlet.config.annotation.*;

@Configuration
@EnableWebMvc
@ComponentScan("kr.bit.controller")
@ComponentScan("kr.bit.dao")
@ComponentScan("kr.bit.service")
@PropertySource("/WEB-INF/properties/db.properties")
public class ServletAppContext implements WebMvcConfigurer {

    @Value("${db.classname}")
    private String db_classname;

    @Value("${db.url}")
    private String db_url;

    @Value("${db.username}")
    private String db_username;

    @Value("${db.password}")
    private String db_password;

    @Autowired
    private TopMenuService topMenuService; //@service

    @Resource(name="loginBean")
    private User loginBean; //로그인 여부에 따라 상단메뉴바가 다르게 보이도록 하기 위해 주입받음

    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        WebMvcConfigurer.super.configureViewResolvers(registry);
        registry.jsp("/WEB-INF/views/", ".jsp");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        WebMvcConfigurer.super.addResourceHandlers(registry);
        registry.addResourceHandler("/**").addResourceLocations("/resources/");
    }

    @Bean
    public BasicDataSource dataSource() {
        BasicDataSource source= new BasicDataSource();
        source.setDriverClassName(db_classname);
        source.setUrl(db_url);
        source.setUsername(db_username);
        source.setPassword(db_password);

        return source;
    }

    @Bean
    public SqlSessionFactory factory(BasicDataSource source) throws Exception{

        SqlSessionFactoryBean fac=new SqlSessionFactoryBean();
        fac.setDataSource(source);
        SqlSessionFactory factory=fac.getObject();
        return factory;
    }

    @Bean
    public MapperFactoryBean<BoardMapper> board_mapper(SqlSessionFactory factory) throws Exception{

        MapperFactoryBean<BoardMapper> fac =
                new MapperFactoryBean<BoardMapper>(BoardMapper.class);

        fac.setSqlSessionFactory(factory);
        return fac;

    }
    @Bean
    public MapperFactoryBean<TopMenuMapper> top_mapper(SqlSessionFactory factory) throws Exception{

        MapperFactoryBean<TopMenuMapper> fac =
                new MapperFactoryBean<TopMenuMapper>(TopMenuMapper.class);

        fac.setSqlSessionFactory(factory);
        return fac;

    }
    @Bean
    public MapperFactoryBean<UserMapper> user_mapper(SqlSessionFactory factory) throws Exception{

        MapperFactoryBean<UserMapper> fac =
                new MapperFactoryBean<UserMapper>(UserMapper.class);

        fac.setSqlSessionFactory(factory);
        return fac;

    }
    //인터셉터 -> 등록
    public void addInterceptors(InterceptorRegistry re) {
        WebMvcConfigurer.super.addInterceptors(re);

        TopMenuInterceptor top=new TopMenuInterceptor(topMenuService, loginBean);

        InterceptorRegistration re1=re.addInterceptor(top);//TopMenuInterceptor등록
        re1.addPathPatterns("/**"); //모든경로로 매핑해도 다 뜨도록..컨트롤러 전에 preHandle
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean
    public ReloadableResourceBundleMessageSource messageSource() {
        ReloadableResourceBundleMessageSource res=
                new ReloadableResourceBundleMessageSource();

        res.setBasename("/WEB-INF/properties/error");
        return res;
    }
}

 

TopMenuInterceptor

loginBean과 관련된 부분 주석처리해제 및 추가

 

package kr.bit.interceptor;

import kr.bit.beans.BoardInfo;
import kr.bit.beans.User;
import kr.bit.service.TopMenuService;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

public class TopMenuInterceptor implements HandlerInterceptor {

    private TopMenuService topMenuService;

    @Resource(name = "loginBean")   //
    private User loginBean;			// 주석처리 해제

    public TopMenuInterceptor(TopMenuService topMenuService) {
        this.topMenuService = topMenuService;
        this.loginBean = loginBean; //추가
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        List<BoardInfo> team = topMenuService.getTopMenuList(); //select .. 1,2,1팀,2팀
        request.setAttribute("team", team);
        request.setAttribute("loginBean",loginBean); // 추가
        return true;
    }
}

 

 

top_menu.jsp

절대값주소 변경 및 c:chosse, c:when 추가

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="root" value="${pageContext.request.contextPath }/"/>

<nav class="navbar navbar-expand-md bg-dark text-white fixed-up shadow-lg">
    <a class=navbar-brand" href="${root }main">Board Project</a>
    <div class="container-fluid">
        <button class="navbar-toggler" type="button" data-toggle="collapse"
                data-target="#navbarNav">
            <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarNav">
            <ul class="navbar-nav">
                <c:forEach var="obj" items="${team }">
                    <li class="nav-item">
                        <a href="${root }board/main?board_info_idx=${obj.board_info_idx}"
                           class="nav-link">${obj.board_info_name}</a>
                    </li>
                </c:forEach>
            </ul>

            <ul class="navbar-nav ml-auto">
                <c:choose>
                    <c:when test="${loginBean.userLogin==true}">
                        <li class="nav-item">
                            <a class="nav-link" href="${root }user/modify">Modify</a>
                        </li>

                        <li class="nav-item">
                            <a class="nav-link" href="${root }user/logout">Log Out</a>
                        </li>
                    </c:when>
                    <c:otherwise>
                        <li class="nav-item">
                            <a class="nav-link" href="${root }user/login">Log In</a>
                        </li>

                        <li class="nav-item">
                            <a class="nav-link" href="${root }user/join">Join Us</a>
                        </li>
                    </c:otherwise>
                </c:choose>
            </ul>
        </div>
    </div>
</nav>

UserContrlloer

코드 추가

@GetMapping("/logout")
public String logout() {
    loginBean.setUserLogin(false);
    return "user/logout";
}

 

logout.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<c:set var="root" value="${pageContext.request.contextPath }/" />

<script>
    alert("LogOut!");
    location.href="${root }main";
</script>

 

로그인 되어 변경된 상단바 메뉴

 

LoginInterceptor

package kr.bit.interceptor;

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

import org.springframework.web.servlet.HandlerInterceptor;

import kr.bit.beans.User;

public class LoginInterceptor implements HandlerInterceptor{
    
    private User loginBean;
    
    public LoginInterceptor(User loginBean) {
       this.loginBean=loginBean;
    }
    //로그인 안되어있으면 주소를 입력해도 못들어가도록 막아죠~~
    
    @Override
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
             throws Exception {

          if(loginBean.isUserLogin()==false) {
             String str=request.getContextPath();
             
             response.sendRedirect(str+"/user/not_login");
             return false;
          }
          return true;
       }

}

 

ServletAppContext

인터셉트 추가

  public void addInterceptors(InterceptorRegistry re) {
      WebMvcConfigurer.super.addInterceptors(re);

      TopMenuInterceptor top = new TopMenuInterceptor(topMenuService, loginBean);

      InterceptorRegistration re1 = re.addInterceptor(top);//TopMenuInterceptor등록
      re1.addPathPatterns("/**"); //모든경로로 매핑해도 다 뜨도록..컨트롤러 전에 preHandle

      LoginInterceptor login = new LoginInterceptor(loginBean);
InterceptorRegistration re2= re.addInterceptor(login);

re2.addPathPatterns("/user/modify", "user/logout","/board/*");
re2.excludePathPatterns("/board/main");

  }

 

not_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"%>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<c:set var="root" value="${pageContext.request.contextPath }/" />

<script>

	alert('You have to Login')
	location.href="${root}user/login"

</script>


정보수정

modify.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<c:set var="root" value="${pageContext.request.contextPath }/" />
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>우리반 화이팅</title>
    <!-- Bootstrap CDN -->
    <link rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
    <script
            src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script
            src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
    <script
            src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
<body>
<c:import url="/WEB-INF/views/include/top_menu.jsp" />
<div class="container" style="margin-top: 100px">
    <div class="row">
        <div class="col-sm-3"></div>
        <div class="col-sm-6">
            <div class="card shadow">
                <div class="card-body">
                    <form:form action="${root}user/modify_pro" method="post" modelAttribute="modifyBean">
                        <form:hidden path="existId"/>
                        <div class="form-group">
                            <form:label path="user_name">이름</form:label>
                            <form:input type="text" path="user_name" class="form-control" readonly="true"/>
                            <form:errors path="user_name" style='color:red'/>
                        </div>

                        <div class="form-group">
                            <form:label path="user_id">아이디</form:label>
                            <div class="input-group">
                                <form:input class="form-control" path="user_id" readonly="true"/>
                                </div>
                            </div>
                        <div class="form-group">
                            <form:label path="user_pw">비밀번호</form:label>
                            <form:password path="user_pw" class="form-control"/>
                            <form:errors path="user_pw" style='color:red'/>
                        </div>


                        <div class="form-group">
                            <form:label path="user_pw2">비밀번호 확인</form:label>
                            <form:password path="user_pw2" class="form-control"/>
                            <form:errors path="user_pw2" style='color:red'/>
                        </div>

                        <div class="form-group">
                            <div class="text-right">
                                <button type="submit" class="btn btn-primary">정보수정</button>
                            </div>

                        </div>
                    </form:form>
                </div>
            </div>
        </div>
    </div>
    <c:import url="/WEB-INF/views/include/bottom_menu.jsp" />
</body>
</html>

UserController

아래 코드 추가

@GetMapping("/modify")
public String modify(@ModelAttribute("modifyBean") User modifyBean) {

    return "user/modify";
}

@PostMapping("/modify_pro")
public String modify_pro(@ModelAttribute("modifyBean") User modifyBean,
                    BindingResult result) {
    if (result.hasErrors()) {
       return "user/modify";
    }
    return "user/modify_success";
}

 

전체코드

package kr.bit.controller;

import javax.annotation.Resource;
import javax.validation.Valid;

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.WebDataBinder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import kr.bit.beans.User;
import kr.bit.service.UserService;
import kr.bit.validator.UserValidator;

@Controller
@RequestMapping("/user")
public class UserController {
    
    @Autowired
    private UserService userService;  //컨트롤러 전후 단계 - 비즈니스로직 (service)
    
    @Resource(name="loginBean")
    private User loginBean;  // 로그인 여부확인으로 세션영역에 담아 놓은거 자동주입받음

    @GetMapping("/modify")
    public String modify(@ModelAttribute("modifyBean") User modifyBean) {

       return "user/modify";
    }

    @PostMapping("/modify_pro")
    public String modify_pro(@ModelAttribute("modifyBean") User modifyBean,
                       BindingResult result) {
       if (result.hasErrors()) {
          return "user/modify";
       }
       return "user/modify_success";
    }

    
    @GetMapping("/modify")
    public String modify() {
       return "user/modify";
    }
    
    @GetMapping("/logout")
    public String logout() {
       loginBean.setUserLogin(false);  //로그인 되어있는 상태 아님
       return "user/logout";
    }
    
    @GetMapping("/login")
    public String login(@ModelAttribute("loginProBean") User loginProBean, @RequestParam(value="fail", defaultValue = "false") boolean fail, Model model) {
       
       model.addAttribute("fail", fail);
       return "user/login";
    }
    
    @PostMapping("/login_pro")
    public String login(@Valid @ModelAttribute("loginProBean") User loginProBean, BindingResult result) {
       if(result.hasErrors()) {
             return "user/login";
          }
       
       userService.getLoginUser(loginProBean);  // 로그인 성공하면 user_idx, user_name 추출
       
       if(loginBean.isUserLogin()==true) {
           return "user/login_success";
       }
       else {
          return "user/login_fail";
       }
         
       }
    
    @GetMapping("/join")
    public String join(@ModelAttribute("joinBean") User joinBean) {  //상단메뉴 - 회원가입
       return "user/join";
    }
    
    @PostMapping("/join_pro")  //join
    public String join_pro(@Valid @ModelAttribute("joinBean") User joinBean, 
                           BindingResult result) {
       
       if(result.hasErrors()) {
          return "user/join";
       } //에러있음 원래 회원가입 폼
       
       userService.addUser(joinBean); //db에 삽입 (insert)
       
       return "user/join_success";
    }

    @GetMapping("/not_login")
    public String not_login() {
       return "user/not_login";
    }
    
    
    @InitBinder
    public void initBinder(WebDataBinder binder) {
       
       UserValidator v1=new UserValidator();
       binder.addValidators(v1);  
    }
}






 

UserMapper

modify 추가

package kr.bit.mapper;

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;

import kr.bit.beans.User;
import org.apache.ibatis.annotations.Update;

public interface UserMapper {
    
    @Select("select user_name from user_table where user_id=#{user_id}")
    String existId(String user_id);
    
    
    @Insert("insert into user_table(user_name, user_id, user_pw) values(#{user_name}, #{user_id}, #{user_pw})")
    void addUser(User joinBean);
    
    //아이디랑 비번 검사해서 user_idx, user_name추출
    @Select("select user_idx, user_name from user_table where user_id=#{user_id} and user_pw=#{user_pw}")
    User getLoginUser(User loginProBean);
    
    @Select("select user_id, user_name from user_table where user_idx=#{user_idx}")
    User getModifyUser(int user_idx);
    
    @Update("update user_table set user_pw=#{user_pw} where user_idx=#{user_idx}")
    void modifyUser(User modifyBean);
}

 

UserDao

modify코드 추가

package kr.bit.dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import kr.bit.beans.User;
import kr.bit.mapper.UserMapper;

@Repository
public class UserDao {

    @Autowired
    private UserMapper userMapper;

    public String existId(String user_id) {
        return userMapper.existId(user_id);
    }

    public void addUser(User joinBean) {
        userMapper.addUser(joinBean);
    }

    public User getLoginUser(User loginProBean) {
        return userMapper.getLoginUser(loginProBean);

    }

    public User getModifyUser(int user_idx) {
        return userMapper.getModifyUser(user_idx);
    }

	public void modifyUser(User modifyBean) {
        userMapper.modifyUser(modifyBean);
    }

}

 

UserService

package kr.bit.service;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import kr.bit.beans.User;
import kr.bit.dao.UserDao;

@Service
public class UserService {

    @Autowired
    private UserDao userDao;
    
    @Resource(name="loginBean")  //RootAppContext 세션영역에 설정한 빈 이름과 같기 때문에 주소값 자동주입
    private User loginBean;
    
    public boolean existId(String user_id) {
       
       String user_name=userDao.existId(user_id);
       if(user_name==null) {
          return true; //  사용할 수 있는 아이디면
       }
       return false; 
    }
    
    public void addUser(User joinBean) {
       userDao.addUser(joinBean);
    }
    
    public void getLoginUser(User loginProBean) {
       User loginProBean2 = userDao.getLoginUser(loginProBean);
       if(loginProBean2 != null) {
          loginBean.setUser_idx(loginProBean2.getUser_idx());  
          //로그인 되어있는 사람의 idx값 가져와서 User의 클래스 필드(user_id)에 세팅
          loginBean.setUser_name(loginProBean2.getUser_name());
          loginBean.setUserLogin(true);  //로그인이 되어있는 상태이므로 true
          
          
          
          // 비번, 아이디가 일치하면 -> 로그인이 된 상태라면
          // 세션영역에 담은 loginBean객체로부터 idx, name, 로그인 여부확인을 설정할거임
       }
    }

    public void getModifyUser(User modifyBean) {
       User user = userDao.getModifyUser(loginBean.getUser_idx()); //로그인한 사람의 idx 기준으로 name, id 추출

       modifyBean.setUser_id(user.getUser_id());
       modifyBean.setUser_name(user.getUser_name());
       modifyBean.setUser_idx(user.getUser_idx());

    }

    public void modifyUser(User modifyBean) {

       modifyBean.setUser_idx(loginBean.getUser_idx());
       userDao.modifyUser(modifyBean); // update
    }
}

 

UserController

modify 부분 추가

package kr.bit.controller;

import javax.annotation.Resource;
import javax.validation.Valid;

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.WebDataBinder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import kr.bit.beans.User;
import kr.bit.service.UserService;
import kr.bit.validator.UserValidator;

@Controller
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;  //컨트롤러 전후 단계 - 비즈니스로직 (service)

    @Resource(name = "loginBean")
    private User loginBean;  // 로그인 여부확인으로 세션영역에 담아 놓은거 자동주입받음

    @GetMapping("/modify")
    public String modify(@ModelAttribute("modifyBean") User modifyBean) {

        return "user/modify";
    }

    @PostMapping("/modify_pro")
    public String modify_pro(@ModelAttribute("modifyBean") User modifyBean,
                             BindingResult result) {
        if (result.hasErrors()) {
            return "user/modify";
        }
        userService.modifyUser(modifyBean);
        return "user/modify_success";
    }

    @GetMapping("/modify")
    public String modify() {
        return "user/modify";
    }

    @GetMapping("/logout")
    public String logout() {
        loginBean.setUserLogin(false);  //로그인 되어있는 상태 아님
        return "user/logout";
    }

    @GetMapping("/login")
    public String login(@ModelAttribute("loginProBean") User loginProBean, @RequestParam(value = "fail", defaultValue = "false") boolean fail, Model model) {

        model.addAttribute("fail", fail);
        return "user/login";
    }

    @PostMapping("/login_pro")
    public String login(@Valid @ModelAttribute("loginProBean") User loginProBean, BindingResult result) {
        if (result.hasErrors()) {
            return "user/login";
        }

        userService.getLoginUser(loginProBean);  // 로그인 성공하면 user_idx, user_name 추출

        if (loginBean.isUserLogin() == true) {
            return "user/login_success";
        } else {
            return "user/login_fail";
        }

    }

    @GetMapping("/join")
    public String join(@ModelAttribute("joinBean") User joinBean) {  //상단메뉴 - 회원가입
        return "user/join";
    }

    @PostMapping("/join_pro")  //join
    public String join_pro(@Valid @ModelAttribute("joinBean") User joinBean,
                           BindingResult result) {

        if (result.hasErrors()) {
            return "user/join";
        } //에러있음 원래 회원가입 폼

        userService.addUser(joinBean); //db에 삽입 (insert)

        return "user/join_success";
    }

    @GetMapping("/not_login")
    public String not_login() {
        return "user/not_login";
    }


    @InitBinder
    public void initBinder(WebDataBinder binder) {

        UserValidator v1 = new UserValidator();
        binder.addValidators(v1);
    }
}






 

UserValidator

가입때 뿐만 아니라 정보수정시에도 비밀번호 확인할 수 있도록 추가변경

@Override
public void validate(Object target, Errors errors) {
    
    User user=(User)target;
    String beanName=errors.getObjectName();
    
    //join.jsp에서 폼에다 데이터 입력 
    //-> modelAttribute로 User클래스의 필드에 데이터 값이 저장되어 있는 상태(값 주입한 상태)
    
    if(beanName.equals("joinBean") || beanName.equals("modifyBean")) {
       
       if(user.getUser_pw().equals(user.getUser_pw2())==false) {
          errors.rejectValue("user_pw", "NotEqual");
          errors.rejectValue("user_pw2", "NotEqual");
       }
       
       //비밀번호와 비밀번호확인이 같아야됨.. 유효성검사하는 어노테이션이 따로 없음 -> 개발자가 정의해야함(커스터마이징)
       
    }

 

db.properties 추가

Size.modifyBean.user_pw=4글자 이상, 10글자 미만으로 작성해주세요
Pattern.modifyBean.user_pw=영문으로만 작성해주세요

Size.modifyBean.user_pw2=4글자 이상, 10글자 미만으로 작성해주세요
Pattern.modifyBean.user_pw2=영문으로만 작성해주세요

NotEqual.modifyBean.user_pw=비밀번호가 일치하지 않습니다
NotEqual.modifyBean.user_pw2=비밀번호가 일치하지 않습니다

 

modify_success.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<c:set var="root" value="${pageContext.request.contextPath }/" />

<script>

    alert('수정되었습니다')
    location.href="${root}user/modify"

</script>

 

728x90
728x90

유효성 검사

join.jsp

form taglib 추가

 

 

form 태그 작업

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <!-- URI 수정 -->
<c:set var="root" value="${pageContext.request.contextPath}"/>

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>우리반 화이팅~~! 아쟉!♥</title>
    <link rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
</head>
<body>
<c:import url="/WEB-INF/views/include/top_menu.jsp"/>
<div class="container" style="margin-top: 100px">
    <div class="row">
        <div class="col-sm-3"></div>
        <!-- 부트스트랩 그리드 옵션 -->
        <div class="col-sm-6">
            <div class="card shadow">
                <div class="card-body">
                    <form:form action="${root}/user/join_pro" method="post" modelAttribute="joinBean">
                        <form:hidden path="existId"/>
                        <div class="form-group">
                            <form:label path="user_name">Name</form:label>
                            <form:input type="text" class="form-control" path="user_name"/>
                            <form:errors path="user_name" style="color:red"/>
                        </div>

                        <div class="form-group">
                            <form:label path="user_id">ID</form:label>
                            <div class="input-group">
                                <form:input class="form-control" path="user_id" onkeypress="resetUser()"/>
                                <div class="input-group-append">
                                    <button type="button" class="btn btn-dark" onclick="chexistId()">
                                        Duplicate Check
                                    </button>
                                </div>
                            </div>
                            <form:errors path="user_id" style="color:red"/>
                        </div> <!-- form-group 닫기 -->

                        <div class="form-group">
                            <form:label path="user_pw">Password</form:label>
                            <form:password path="user_pw" class="form-control"/>
                            <form:errors path="user_pw" style="color:red"/>
                        </div>

                        <div class="form-group">
                            <form:label path="user_pw2">Password Check</form:label>
                            <form:password path="user_pw2" class="form-control"/>
                            <form:errors path="user_pw2" style="color:red"/>
                        </div>

                        <div class="form-group">
                            <div class="text-right">
                                <button type="submit" class="btn btn-dark">Join</button>
                            </div>
                        </div>
                    </form:form>
                </div>
            </div>
        </div>
    </div>
</div>

<c:import url="/WEB-INF/views/include/bottom_menu.jsp"/>
</body>
</html>

 

User

에 유효성 검사 추가

package kr.bit.beans;

import lombok.Getter;
import lombok.Setter;

import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

@Getter
@Setter
public class User {

    private int user_idx;

    @Size(min=2, max=4)
    @Pattern(regexp = "[가-힣]*")
    private String user_name;

    @Size(min=4, max=10)
    @Pattern(regexp = "[a-zA-Z0-9]*")
    private String user_id;

    @Size(min=4, max=10)
    @Pattern(regexp = "[a-zA-Z0-9]*")
    private String user_pw;

    @Size(min=4, max=10)
    @Pattern(regexp = "[a-zA-Z0-9]*")
    private String user_pw2;

    private boolean existId;
}

UserController (비즈니스 로직)

package kr.bit.controller;

import kr.bit.beans.User;
import kr.bit.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@Controller
@RequestMapping("/user")
public class UserController {

//    @Autowired
//    private UserService userService; //컨트롤러 전후 단계 = 비즈니스 로직(Service)


    @GetMapping("/modify")
    public String modify() {
        return "user/modify";
    }

    @GetMapping("/logout")
    public String logout() {
        return "user/logout";
    }

	@GetMapping("/login")
	public String loginGet() {

		return "user/login";
	}

    @PostMapping("/login")
    public String loginPost() {
        return "user/login";
    }


    @GetMapping("/join")
    public String join(@ModelAttribute("joinBean") User joinBean) {  //상단메뉴 - 회원가입
        return "user/join";
    }
    @PostMapping("/join_pro")
    public String join_pro(@Valid @ModelAttribute("joinBean") User joinBean, BindingResult result) {
        if(result.hasErrors()){
            return "user/join";
        } // 에러있음 - 원래 회원 가입 폼

//        userService.addUser(joinBean);


        return "user/join_success";
    }
}

 

유효성검사 실행 화면

error.properties

# user_name errors
Size.joinBean.user_name=Please enter between 2 and 4 characters.
Pattern.joinBean.user_name=Please use only Korean characters.

# user_id errors
Size.joinBean.user_id=Please enter between 4 and 10 characters.
Pattern.joinBean.user_id=Please use only alphanumeric characters.

# user_pw errors
Size.joinBean.user_pw=Please enter between 4 and 10 characters.
Pattern.joinBean.user_pw=Please use only alphanumeric characters.

# user_pw2 errors
Size.joinBean.user_pw2=Please enter between 4 and 10 characters.
Pattern.joinBean.user_pw2=Please use only alphanumeric characters.

 

ServletAppcontext

추가한 프로퍼티를 불러올 수 있도록 아래 코드 추가

@Bean
public ReloadableResourceBundleMessageSource messageSource() {
    ReloadableResourceBundleMessageSource res =
            new ReloadableResourceBundleMessageSource();
    res.setBasename("/WEB-INF/properties/error");
    return res;
}

error.properties가 적용된 모습

UserValidator

비밀번호 유효성 검사

package kr.bit.validator;

import kr.bit.beans.User;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

public class UserValidator implements Validator {

    @Override
    public boolean supports(Class<?> clazz) {
        return User.class.isAssignableFrom(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {

        User user=(User)target;
    String beanName=errors.getObjectName();

    //join.jsp에서 폼에 데이터 입력 -> modelAttribute로 User클래스의 필드에 데이터 값이 저장되어 있는 상태

    if(beanName.equals("joinBean")) {

        if(user.getUser_pw().equals(user.getUser_pw2())==false) {
            errors.rejectValue("user_pw", "NotEqual");
            errors.rejectValue("user_pw2", "NotEqual");
        }

        //비밀번호와 비밀번호확인이 같아야된다. 유효성 검사하는 애노테이션이 따로 없음 -> 개발자가 정의해야함(커스터마이징)

    }

}
}

 

error.properties

비밀번호 유효성 에러 메세지 추가

# Password matching errors
NotEqual.joinBean.user_pw=Password and password confirmation do not match.
NotEqual.joinBean.user_pw2=Password confirmation and password do not match.

 

 

UserController

에 아래코드 추가

@InitBinder
public void initBinder(WebDataBinder binder) {
    
    UserValidator v1 = new UserValidator();
    binder.addValidators(v1);
}

 

@InitBinder

@InitBinder 애너테이션은 특정 컨트롤러 클래스의 메서드에 적용되어, 해당 컨트롤러에서 사용하는 바인더를 초기화할 때 사용된다.
주로 요청 파라미터를 특정 객체에 바인딩할 때, 바인딩 방식이나 유효성 검사기를 설정하는 데 사용된다.

 

 

아이디 유효성 검사

UserDao

package kr.bit.dao;

import kr.bit.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class UserDao {

    @Autowired
    private UserMapper userMapper;

    public String existId(String user_id) {
        return userMapper.existId(user_id);
    }

}

UserService

package kr.bit.service;

import kr.bit.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    public boolean existId(String user_id) {

        String user_name=userDao.existId(user_id);
        if(user_name==null) {
            return true; // 사용할 수 있는 아이디면
        }
        return false;
    }
}

컨트롤러에 RestTestController 추가

 

RestTestController

package kr.bit.controller;

import kr.bit.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

//restAPI는 보통주소로 보냄
@RestController
public class RestTestController {

    @Autowired
    private UserService userService;

    @GetMapping("/user/chexistId/{user_id}")
    public String existId(@PathVariable String user_id) {

       boolean chk=userService.existId(user_id);
       return chk+"";

    }
}

Spring MVC에서 RESTful 웹 서비스를 구현한 예시이다.

RestTestController 클래스는 REST API 엔드포인트를 정의하고, 주어진 user_id가 존재하는지 확인하는 기능을 제공한다

실제로 aaaa를 만든적이 없지만 위와같이 확인하면 ID값이 확인이 가능하다

 

아이디 중복확인

ajax를 사용해서 아이디 중복사용 체크

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <!-- URI 수정 -->
<c:set var="root" value="${pageContext.request.contextPath}"/>

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>우리반 화이팅~~! 아쟉!♥</title>
    <link rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
    <script> function chexistId(){
        let user_id =$("#user_id").val()

        if(user_id.length==0){
            alert("Please enter your ID")
            return
        }
        $.ajax({
            url:'${root}/user/chexistId/'+user_id,
            type:'get',
            dataType:'text',
            success:function(result){
                if(result.trim()=='true'){
                    alert('You can use this ID')
                    $('#existId').val('true')
                }
                else{
                    alert('You can not use this ID')
                    $('#existId').val('false')
                }
            }
        })
    }
    </script>
</head>
<body>
...

<c:import url="/WEB-INF/views/include/bottom_menu.jsp"/>
</body>
</html>

중복확인 알림창 출력

User에 아래 코드 추가

    public User() {
        this.existId = false; // 중복검사 미실시 한것으로 초기화 해줌
    }
}

 

UserValidator 에 아래 코드 추가

   }
    if(beanName.equals("joinBean")){
        if(user.isExistId()==false){
            errors.rejectValue("user_id", "NotCheck");
        }
    }
}
}

 

error.properties 에 에러메세지 추가

NotCheck.joinBean.user_id=Please check for duplicate ID.

 

아이디 중복확인을 위한 function 추가

join.jsp

<script> function chexistId(){
    let user_id =$("#user_id").val() //입력한 아이디 가져옴

    if(user_id.length==0){
        alert("Please enter your ID")
        return
    }
    $.ajax({
        url:'${root}/user/chexistId/'+user_id,
        type:'get',
        dataType:'text',
        success:function(result){
            if(result.trim()=='true'){
                alert('You can use this ID')
                $('#existId').val('true')
            }
            else{
                alert('You can not use this ID')
                $('#existId').val('false')
            }
        }
    })
    
    function resetUser(){
        $('#existId').val('false')
    }
}
</script>

 


DB에 data 저장하기

UserMapper

package kr.bit.mapper;

import kr.bit.beans.User;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;

public interface UserMapper {

    @Select("select user_name from user_table where user_id=#{user_id}")
    String existId(String user_id);

    //db에 삽입
    @Insert("insert into user_table(user_name, user_id, user_pw) values(#{user_name}, #{user_id}, #{user_pw})")
    void addUser(User joinBean);

}

UserDao

맨 밑 코드 추가

package kr.bit.service;

import kr.bit.beans.User;
import kr.bit.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    public boolean existId(String user_id) {

        String user_name=userDao.existId(user_id);
        if(user_name==null) {
            return true; // 사용할 수 있는 아이디면
        }
        return false;
    }

    public void addUser(User joinBean) {
        userDao.addUser(joinBean);
    }

}

 

 

UserController 에 주석처리 되어있던것들을 다시 활성화

package kr.bit.controller;

import kr.bit.beans.User;
import kr.bit.service.UserService;
import kr.bit.validator.UserValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@Controller
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService; //컨트롤러 전후 단계 = 비즈니스 로직(Service)


    @GetMapping("/modify")
    public String modify() {
        return "user/modify";
    }

    @GetMapping("/logout")
    public String logout() {
        return "user/logout";
    }

    @GetMapping("/login")
    public String loginGet() {

       return "user/login";
    }

    @PostMapping("/login")
    public String loginPost() {
        return "user/login";
    }


    @GetMapping("/join")
    public String join(@ModelAttribute("joinBean") User joinBean) {  //상단메뉴 - 회원가입
        return "user/join";
    }
    @PostMapping("/join_pro")
    public String join_pro(@Valid @ModelAttribute("joinBean") User joinBean, BindingResult result) {
        if(result.hasErrors()){
            return "user/join";
        } // 에러있음 - 원래 회원 가입 폼

        userService.addUser(joinBean); //db에 삽입 (insert)
        return "user/join_success";
    }
    @InitBinder
    public void initBinder(WebDataBinder binder) {

        UserValidator v1 = new UserValidator();
        binder.addValidators(v1);
    }

}

join_success

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <!-- URI 수정 -->
<c:set var="root" value="${pageContext.request.contextPath}"/>

<script>
    alert("Success Join");
    location.href="${root }user/login";
</script>

 

728x90
728x90

Mapper

Mapper에서

BoardMapper, TopMenuMapper, UserMapper를 생성 후

 

 

MyBatis Mapper 인터페이스를 스프링 애플리케이션 컨텍스트에 빈으로 등록하여, 나중에 스프링의 의존성 주입을 통해 해당 Mapper 인터페이스를 사용할 수 있도록 하는 것이다.

이를 통해 SQL 쿼리를 Java 메서드로 쉽게 매핑하고, 데이터베이스와 상호작용하는 코드를 간결하게 작성할 수 있다.

 

ServletAppContext

    @Bean
    public MapperFactoryBean<BoardMapper> board_mapper(SqlSessionFactory factory) throws Exception {

       MapperFactoryBean<BoardMapper> fac =
             new MapperFactoryBean<BoardMapper>(BoardMapper.class);

       fac.setSqlSessionFactory(factory);
       return fac;
    }

    @Bean
    public MapperFactoryBean<TopMenuMapper> top_Mapper(SqlSessionFactory factory) throws Exception {

        MapperFactoryBean<TopMenuMapper> fac =
                new MapperFactoryBean<TopMenuMapper>(TopMenuMapper.class);

        fac.setSqlSessionFactory(factory);
        return fac;
    }

    @Bean
    public MapperFactoryBean<UserMapper> user_mapper(SqlSessionFactory factory) throws Exception {

        MapperFactoryBean<UserMapper> fac =
                new MapperFactoryBean<UserMapper>(UserMapper.class);

        fac.setSqlSessionFactory(factory);
        return fac;
    }


}

해당 과정과 같이 DB에 Data가 들어갈 수 있게 단계를 적용하기 위해서

 

굳이 Model(Service or DAO)를 거쳐서 매핑작업을 하는가? 하면 유지보수를 원활히 하게 하기 위함이있다. "약한 결속력"에 의함!

 

아래와 같이 패키지와 클래스, 인터페이스를 준비한다.

TopMenuMapper

package kr.bit.mapper;

import kr.bit.beans.BoardInfo;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface TopMenuMapper {

    @Select("select board_info_idx, board_info_name from board_info_table order by board_info_idx;")
    List<BoardInfo> getTopMenuList();
    // 함수 호출시 위 쿼리문이 실행됨 -> 쿼리문 결과값들이 /List에 저장됨
}

 

TopMenuDao

에서 TopMenuMapper를 @Autowired를 통해 주입받는다.

package kr.bit.dao;

import kr.bit.beans.BoardInfo;
import kr.bit.mapper.TopMenuMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public class TopMenuDao {

    @Autowired
    private TopMenuMapper topMenuMapper;

    public List<BoardInfo> getTopMenuList() {
        List<BoardInfo> topMenuList = topMenuMapper.getTopMenuList();
        return topMenuList;
                // 1,2,3,4, 1팀,2팀,3팀,4팀

    }
}

 

Service 패키지 생성

 

 

 

ServletAppcontext에서 @ComponentScan에 등록해준다

@ComponentScan은 Spring 프레임워크에서 사용되는 애너테이션으로, 주로 스프링 컨텍스트가 빈(bean)으로 등록할 컴포넌트들을 검색하고 자동으로 인식하기 위해 사용된다.

 

 

TopMenuService

package kr.bit.service;

import kr.bit.beans.BoardInfo;
import kr.bit.dao.TopMenuDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class TopMenuService {
    
    @Autowired
    private TopMenuDao topMenuDao; 
    
    public List<BoardInfo> getTopMenuList(){
        List<BoardInfo> topMenuList = topMenuDao.getTopMenuList();
        return topMenuList; 
    }
}

// 상단에 팀명을 띄우고 싶을 때( 상단메뉴는 어떤 주소를 눌러도 다 동작이 되야한다 -> 무엇을 요청하던 Interceptor를 거쳐야함)
// 뭘 요청하던 topmenu를 통과해야함

/java/kr.bit/

interceptor 패키지 추가

 

TopInterceptor

package kr.bit.interceptor;

import kr.bit.beans.BoardInfo;
import kr.bit.beans.User;
import kr.bit.service.TopMenuService;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

public class TopInterceptor implements HandlerInterceptor {

    private TopMenuService topMenuService;

//    @Resource(name = "loginBean")
//    private User loginBean;

    public TopInterceptor(TopMenuService topMenuService) {
        this.topMenuService = topMenuService;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        List<BoardInfo> team = topMenuService.getTopMenuList(); //select .. 1,2,1팀,2팀
        request.setAttribute("team", team);

        return true;
    }
}

 

 

ServletAppContext에 아래 코드 추가

public void addInterceptors(InterceptorRegistry re) {
    WebMvcConfigurer.super.addInterceptors(re);

    TopMenuInterceptor top = new TopMenuInterceptor(topMenuService);
    
    InterceptorRegistration re1 = re.addInterceptor(top); // TopMenuInterceptor등록
    re1.addPathPatterns("/**"); // 모든 경로로 매핑해도 다 뜨도록, 컨트롤러 전에 preHandle
}

 


상단에 팀명 띄우기

1팀 버튼을 눌렀을 때, 주소창과 화면

top_menu.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:url value='/' var="root"/>

<nav class="navbar navbar-expand-md bg-dark text-white fixed-up shadow-lg">
	<a class=navbar-brand" href="${root }main">Board Project</a>
	<div class="container-fluid">
		<button class="navbar-toggler" type="button" data-toggle="collapse"
			data-target="#navbarNav">
			<span class="navbar-toggler-icon"></span>
		</button>
		<div class="collapse navbar-collapse" id="navbarNav">
			<ul class="navbar-nav">
			<c:forEach var="obj" items="${team }">
				<li class="nav-item">
					<a href="${root }board/main?board_info_idx=${obj.board_info_idx}"
					   class="nav-link">${obj.board_info_name}</a>
				</li>
			</c:forEach>
			</ul>

			<ul class="navbar-nav ml-auto">
			
				<li class="nav-item">
				<a class="nav-link" href="${root }user/modify">Modify</a>
				</li>
				
				<li class="nav-item">
				<a class="nav-link" href="${root }user/logout">Log Out</a>
				</li>
				
				<li class="nav-item">
				<a class="nav-link" href="${root }user/login">Log In</a>
				</li>
				
				<li class="nav-item">
				<a class="nav-link" href="${root }user/join">Join Us</a>
				</li>
				
			</ul>
		</div>
	</div>
</nav>
728x90
728x90

CRUD 구성


 

RootAppContext

package kr.bit.config;

import org.springframework.context.annotation.Configuration;


@Configuration
public class RootAppContext {  //root-context.xml


}

ServletAppContext

package kr.bit.config;

import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@EnableWebMvc
@ComponentScan("kr.bit.controller")
@PropertySource("/WEB-INF/views/properties/db.properties")
public class ServletAppContext implements WebMvcConfigurer {

    @Value("${db.classname}")
    private String db_classname;

    @Value("${db.url}")
    private String db_url;

    @Value("${db.username}")
    private String db_username;

    @Value("${db.password}")
    private String db_password;


    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        WebMvcConfigurer.super.configureViewResolvers(registry);
        registry.jsp("/WEB-INF/views/", ".jsp");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        WebMvcConfigurer.super.addResourceHandlers(registry);
        registry.addResourceHandler("/**").addResourceLocations("/resources/");
    }

}

SpringConfigClass

package kr.bit.config;

import javax.servlet.Filter;

import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class SpringConfigClass extends AbstractAnnotationConfigDispatcherServletInitializer {
    
    //DispatcherServlet에 매핑할 요청주소를 세팅
    @Override
    protected String[] getServletMappings() {
       // TODO Auto-generated method stub
       return new String[] {"/"};
    }
    
    //MVC 설정을 위한 클래스 지정
    @Override
    protected Class<?>[] getServletConfigClasses() {
       // TODO Auto-generated method stub
       return new Class[] {ServletAppContext.class};
    }
    
    //웹에서 사용한 Bean들을 정의하기 위한 클래스 지정
    @Override
    protected Class<?>[] getRootConfigClasses() {
       // TODO Auto-generated method stub
       return new Class[] {RootAppContext.class};
    }
    
    
    @Override
    protected Filter[] getServletFilters() {
       // TODO Auto-generated method stub
       CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
       encodingFilter.setEncoding("UTF-8");
       return new Filter[] {encodingFilter};
    }
    

}

HomeController

package kr.bit.controller;

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

@Controller  
public class HomeController {
    
    @RequestMapping(value="/", method=RequestMethod.GET)
    public String home() {
          return "main";  //main.jsp를 첫화면으로
    }

}

MainController

package kr.bit.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class MainController {

    @GetMapping("/main")
    public String main() {
       return "main";
    }
}

Main.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:set var="root" value="${pageContext.request.contextPath }/"/>

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <!-- Bootstrap CDN-->
    <link rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
    <script
            src="https://ajax.googleapis.com/ajax/libs/jquery-3.3.1/jquery.min.js"></script>
    <script
            src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
    <script
            src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
</head>
<body>
<c:import url="/WEB-INF/views/include/top_menu.jsp"/>
<div class="container" style="margin-top: 100px">
    <div class="card shadow">
        <div class="card-body">
            <h3 class="card-title">Post Title</h3>
            <table class="table table-hover" id="board_list">
                <thead>
                <tr>
                    <th class="text-center d-none d-md-table-cell">Post No.</th>
                    <th class="w-50">Post Subject.</th>
                    <th class="text-center d-none d-md-table-cell">Post Writer.</th>
                    <th class="text-center d-none d-md-table-cell">Post Date.</th>
                </tr>
                </thead>

                <tbody>
                <tr>
                    <td class="text-center d-none d-md-table-cell">10</td>
                    <td class="w-50">Subject</td>
                    <td class="text-center d-none d-md-table-cell">Gildong. Hong</td>
                    <td class="text-center d-none d-md-table-cell">2024-05-14</td>
                </tr>

                <tr>
                    <td class="text-center d-none d-md-table-cell">11</td>
                    <td class="w-50">Subject</td>
                    <td class="text-center d-none d-md-table-cell">ZzangGu. Shin</td>
                    <td class="text-center d-none d-md-table-cell">2024-05-15</td>
                </tr>

                <tr>
                    <td class="text-center d-none d-md-table-cell">12</td>
                    <td class="w-50">Subject</td>
                    <td class="text-center d-none d-md-table-cell">Zzang A. Shin</td>
                    <td class="text-center d-none d-md-table-cell">2024-05-16</td>
                </tr>

                <tr>
                    <td class="text-center d-none d-md-table-cell">13</td>
                    <td class="w-50">Subject</td>
                    <td class="text-center d-none d-md-table-cell">Melody. My</td>
                    <td class="text-center d-none d-md-table-cell">2024-05-17</td>
                </tr>

                <tr>
                    <td class="text-center d-none d-md-table-cell">14</td>
                    <td class="w-50">Subject</td>
                    <td class="text-center d-none d-md-table-cell">Gildong. Hong</td>
                    <td class="text-center d-none d-md-table-cell">2024-05-13</td>
                </tr>

                <tr>
                    <th class="text-center d-none d-md-table-cell">Post No.</th>
                    <th class="w-50">Post Subject.</th>
                    <th class="text-center d-none d-md-table-cell">Post Writer.</th>
                    <th class="text-center d-none d-md-table-cell">Post Date.</th>
                </tr>

                <tr>
                    <th class="text-center d-none d-md-table-cell">Post No.</th>
                    <th class="w-50">Post Subject.</th>
                    <th class="text-center d-none d-md-table-cell">Post Writer.</th>
                    <th class="text-center d-none d-md-table-cell">Post Date.</th>
                </tr>

                <tr>
                    <th class="text-center d-none d-md-table-cell">Post No.</th>
                    <th class="w-50">Post Subject.</th>
                    <th class="text-center d-none d-md-table-cell">Post Writer.</th>
                    <th class="text-center d-none d-md-table-cell">Post Date.</th>
                </tr>

                <tr>
                    <th class="text-center d-none d-md-table-cell">Post No.</th>
                    <th class="w-50">Post Subject.</th>
                    <th class="text-center d-none d-md-table-cell">Post Writer.</th>
                    <th class="text-center d-none d-md-table-cell">Post Date.</th>
                </tr>

                <tr>
                    <th class="text-center d-none d-md-table-cell">Post No.</th>
                    <th class="w-50">Post Subject.</th>
                    <th class="text-center d-none d-md-table-cell">Post Writer.</th>
                    <th class="text-center d-none d-md-table-cell">Post Date.</th>
                </tr>


                </tbody>
            </table>
            <div class="d-none d-md-block">
                <ul class="pagination justify-content-center">
                    <li class="page-item">
                        <a class="page-link" href="#">Previous</a>
                    </li>
                    <li class="page-item">
                        <a class="page-link" href="#">1</a>
                    </li>
                    <li class="page-item">
                        <a class="page-link" href="#">2</a>
                    </li>
                    <li class="page-item">
                        <a class="page-link" href="#">3</a>
                    </li>
                    <li class="page-item">
                        <a class="page-link" href="#">4</a>
                    </li>
                    <li class="page-item">
                        <a class="page-link" href="#">5</a>
                    </li>
                    <li class="page-item">
                        <a class="page-link" href="#">6</a>
                    </li>
                    <li class="page-item">
                        <a class="page-link" href="#">7</a>
                    </li>
                    <li class="page-item">
                        <a class="page-link" href="#">8</a>
                    </li>
                    <li class="page-item">
                        <a class="page-link" href="#">9</a>
                    </li>
                    <li class="page-item">
                        <a class="page-link" href="#">Next</a>
                    </li>
                </div>

                    <div class="d-none d-md-block">
                        <ul class="pagination justify-content-center">
                            <li class="page-item"><a class="page-link" href="#">Previous</a></li>
                            <li class="page-item"><a class="page-link" href="#">Next</a></li>
                        </ul>
                    </div>

            <div class="text-right">
                <a href="${root }board/write" class="btn btn-dark">Write</a>
            </div>
        </div>
    </div>

        <c:import url="/WEB-INF/views/include/bottom_menu.jsp"/>
</body>
</html>

 

절대경로 설정

<c:set var="root" value="${pageContext.request.contextPath }/"/>

 

머릿말 / 바닥글 설정법

머릿글

<c:import url="/WEB-INF/views/include/top_menu.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:url value='/' var="root"/>

<nav class="navbar navbar-expand-md bg-dark text-white fixed-up shadow-lg">
    <a class=navbar-brand" href="${root }main">Board Project</a>
    <div class="container-fluid">
       <button class="navbar-toggler" type="button" data-toggle="collapse"
          data-target="#navbarNav">
          <span class="navbar-toggler-icon"></span>
       </button>
       <div class="collapse navbar-collapse" id="navbarNav">
          <ul class="navbar-nav"></ul>
          
          <ul class="navbar-nav ml-auto">
          
             <li class="nav-item">
             <a class="nav-link" href="${root }user/modify">Modify</a>
             </li>
             
             <li class="nav-item">
             <a class="nav-link" href="${root }user/logout">Log Out</a>
             </li>
             
             <li class="nav-item">
             <a class="nav-link" href="${root }user/login">Log In</a>
             </li>
             
             <li class="nav-item">
             <a class="nav-link" href="${root }user/join">Join Us</a>
             </li>
             
          </ul>
       </div>
    </div>
</nav>

 

바닥글

<c:import url="/WEB-INF/views/include/bottom_menu.jsp"/>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<style>
.foot{
display: flex;
gap:15px;
}
.foot-box{
position: absolute;
top:100%;
right:18%;
transform:translate(0%,-100%);
}
</style>
<div class="container-fluid bg-white text-dark" style="margin-top: 50px; padding-top: 30px; padding-bottom: 30px">
    <div class="container foot">
       <p>미치겠다</p>
       <p>이게 뭡니까 ..?</p>
       <p>네클캠 10기 살려줘~</p>
    
    </div>


</div>

<!--  절대경로로 넣으면 새로운 요청이 발생했을 때 localhost:8080 주소만 남음 
      하위 경로(첫경로/main)가 어떻게 되어있던 상관없이 원하는 페이지를 직접 요청할 수 있다  -->

 


User

 

UserController

package kr.bit.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/user")
public class UserController {

    @GetMapping("/modify")
    public String modify() {
        return "user/modify";
    }

    @GetMapping("/logout")
    public String logout() {
        return "user/logout";
    }

//  @GetMapping("/login")
//  public String login() {
//     return "user/login";
//  }

    @PostMapping("/login")
    public String login() {
        return "user/login";
    }

    @GetMapping("/join")
    public String join() {  //상단메뉴 - 회원가입
        return "user/join";
    }
}

 

 

join.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:set var="root" value="${pageContext.request.contextPath }"/>

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>우리반 화이팅~~! 아쟉!♥</title>
    <link rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
    <script
            src="https://ajax.googleapis.com/ajax/libs/jquery-3.3.1/jquery.min.js"></script>
    <script
            src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
    <script
            src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
</head>
<body>
<c:import url="/WEB-INF/views/include/top_menu.jsp"/>
<div class="container" style="margin-top: 100px">
    <div class="row">
        <div class="col-sm-3"></div>
        <!--  부트스트랩 그리드 옵션 -->
        <div class="col-sm-6">
            <div class="card shadow">
                <div class="card-body">
                    <form action="${root}user/login" method="post">
                        <div class="form-group">
                            <label for="user_name">Name</label>
                            <input type="text"
                                   class="form-control" id="user_name"
                                   name="user_name"/>
                        </div>

                        <div class="form-group">
                            <label for="user_id">ID</label>

                            <div class="input-group">
                                <input type="text" class="form-control" id="user_id"
                                       name="user_id"/>

                                <div class="input-group-append">
                                    <button type="button" class="btn btn-dark">
                                        Duplicate Check
                                    </button>
                                </div>
                            </div>

                            <div class="form-group">
                                <label for="user_pw">Password</label>
                                <input type="password"
                                       class="form-control" id="user_pw"
                                       name="user_pw"/>
                            </div>

                            <div class="form-group">
                                <label for="user_pw2">Password Check</label>
                                <input type="text"
                                       class="form-control" id="user_pw"
                                       name="user_pw2"/>
                            </div>

                            <div class="form-group">
                                <div class="text-right">
                                    <button type="submit" class="btn btn-dark">Join</button>
                                </div>
                            </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>


<c:import url="/WEB-INF/views/include/bottom_menu.jsp"/>
</body>
</html>

 

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:set var="root" value="${pageContext.request.contextPath }"/>

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
    <script
            src="https://ajax.googleapis.com/ajax/libs/jquery-3.3.1/jquery.min.js"></script>
    <script
            src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
    <script
            src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
</head>
<body>
<c:import url="/WEB-INF/views/include/top_menu.jsp"/>
<div class="container" style="margin-top: 100px">
    <div class="row">
        <div class="col-sm-3"></div>
        <!--  부트스트랩 그리드 옵션 -->
        <div class="col-sm-6">
            <div class="card shadow">
                <div class="card-body">
                    <div class="alert alert-danger">
                        <h2>login fail</h2>
                        <p>check your ID, Password</p>
                    </div>

                    <form action="${root}user/login" method="get">
                        <div class="form-group">
                            <label for="user_id">ID</label>
                            <input type="text"
                                   class="form-control" id="user_id"
                                   name="user_id"/>
                        </div>

                            <div class="form-group">
                                <label for="user_pw">Password</label>
                                <input type="password"
                                       class="form-control" id="user_pw"
                                       name="user_pw"/>
                            </div>

                        <div class="form-group">
                            <div class="text-right">
                                <button type="submit" class="btn btn-dark">Log In</button>
                                <a href="${root }user/join" class="btn btn-dark">Join</a>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>


<c:import url="/WEB-INF/views/include/bottom_menu.jsp"/>

</body>
</html>

 

logout.jsp

modify.jsp

 


BoardController

package kr.bit.controller;

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

@Controller
@RequestMapping("/board")
public class BoardController {

    @GetMapping("/main")
    public String main() {
        return "board/main";
    }

    @GetMapping("/read")
    public String read() {
        return "board/read";
    }

    @GetMapping("/write")
    public String write() {
        return "board/write";
    }

    @GetMapping("/modify")
    public String modify() {
        return "board/modify";
    }

    @GetMapping("/delete")
    public String delete() {
        return "board/delete";
    }
}

 

main.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:set var="root" value="${pageContext.request.contextPath }/"/>

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <!-- Bootstrap CDN-->
    <link rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
    <script
            src="https://ajax.googleapis.com/ajax/libs/jquery-3.3.1/jquery.min.js"></script>
    <script
            src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
    <script
            src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
</head>
<body>
<c:import url="/WEB-INF/views/include/top_menu.jsp"/>
<div class="container" style="margin-top: 100px">
    <div class="card shadow">
        <div class="card-body">
            <h3 class="card-title">Post Title</h3>
            <table class="table table-hover" id="board_list">
                <thead>
                <tr>
                    <th class="text-center d-none d-md-table-cell">Post No.</th>
                    <th class="w-50">Post Subject.</th>
                    <th class="text-center d-none d-md-table-cell">Post Writer.</th>
                    <th class="text-center d-none d-md-table-cell">Post Date.</th>
                </tr>
                </thead>

                <tbody>
                <tr>
                    <td class="text-center d-none d-md-table-cell">10</td>
                    <td class="w-50">Subject</td>
                    <td class="text-center d-none d-md-table-cell">Gildong. Hong</td>
                    <td class="text-center d-none d-md-table-cell">2024-05-14</td>
                </tr>

                <tr>
                    <td class="text-center d-none d-md-table-cell">11</td>
                    <td class="w-50">Subject</td>
                    <td class="text-center d-none d-md-table-cell">ZzangGu. Shin</td>
                    <td class="text-center d-none d-md-table-cell">2024-05-15</td>
                </tr>

                <tr>
                    <td class="text-center d-none d-md-table-cell">12</td>
                    <td class="w-50">Subject</td>
                    <td class="text-center d-none d-md-table-cell">Zzang A. Shin</td>
                    <td class="text-center d-none d-md-table-cell">2024-05-16</td>
                </tr>

                <tr>
                    <td class="text-center d-none d-md-table-cell">13</td>
                    <td class="w-50">Subject</td>
                    <td class="text-center d-none d-md-table-cell">Melody. My</td>
                    <td class="text-center d-none d-md-table-cell">2024-05-17</td>
                </tr>

                <tr>
                    <td class="text-center d-none d-md-table-cell">14</td>
                    <td class="w-50">Subject</td>
                    <td class="text-center d-none d-md-table-cell">Gildong. Hong</td>
                    <td class="text-center d-none d-md-table-cell">2024-05-13</td>
                </tr>

                <tr>
                    <th class="text-center d-none d-md-table-cell">Post No.</th>
                    <th class="w-50">Post Subject.</th>
                    <th class="text-center d-none d-md-table-cell">Post Writer.</th>
                    <th class="text-center d-none d-md-table-cell">Post Date.</th>
                </tr>

                <tr>
                    <th class="text-center d-none d-md-table-cell">Post No.</th>
                    <th class="w-50">Post Subject.</th>
                    <th class="text-center d-none d-md-table-cell">Post Writer.</th>
                    <th class="text-center d-none d-md-table-cell">Post Date.</th>
                </tr>

                <tr>
                    <th class="text-center d-none d-md-table-cell">Post No.</th>
                    <th class="w-50">Post Subject.</th>
                    <th class="text-center d-none d-md-table-cell">Post Writer.</th>
                    <th class="text-center d-none d-md-table-cell">Post Date.</th>
                </tr>

                <tr>
                    <th class="text-center d-none d-md-table-cell">Post No.</th>
                    <th class="w-50">Post Subject.</th>
                    <th class="text-center d-none d-md-table-cell">Post Writer.</th>
                    <th class="text-center d-none d-md-table-cell">Post Date.</th>
                </tr>

                <tr>
                    <th class="text-center d-none d-md-table-cell">Post No.</th>
                    <th class="w-50">Post Subject.</th>
                    <th class="text-center d-none d-md-table-cell">Post Writer.</th>
                    <th class="text-center d-none d-md-table-cell">Post Date.</th>
                </tr>


                </tbody>
            </table>
            <div class="d-none d-md-block">
                <ul class="pagination justify-content-center">
                    <li class="page-item">
                        <a class="page-link" href="#">Previous</a>
                    </li>
                    <li class="page-item">
                        <a class="page-link" href="#">1</a>
                    </li>
                    <li class="page-item">
                        <a class="page-link" href="#">2</a>
                    </li>
                    <li class="page-item">
                        <a class="page-link" href="#">3</a>
                    </li>
                    <li class="page-item">
                        <a class="page-link" href="#">4</a>
                    </li>
                    <li class="page-item">
                        <a class="page-link" href="#">5</a>
                    </li>
                    <li class="page-item">
                        <a class="page-link" href="#">6</a>
                    </li>
                    <li class="page-item">
                        <a class="page-link" href="#">7</a>
                    </li>
                    <li class="page-item">
                        <a class="page-link" href="#">8</a>
                    </li>
                    <li class="page-item">
                        <a class="page-link" href="#">9</a>
                    </li>
                    <li class="page-item">
                        <a class="page-link" href="#">Next</a>
                    </li>
                </div>

                    <div class="d-none d-md-block">
                        <ul class="pagination justify-content-center">
                            <li class="page-item"><a class="page-link" href="#">Previous</a></li>
                            <li class="page-item"><a class="page-link" href="#">Next</a></li>
                        </ul>
                    </div>

            <div class="text-right">
                <a href="${root }board/write" class="btn btn-dark">Write</a>
            </div>
        </div>
    </div>

        <c:import url="/WEB-INF/views/include/bottom_menu.jsp"/>
</body>
</html>

 

write.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:set var="root" value="${pageContext.request.contextPath }/"/>

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <!-- Bootstrap CDN-->
    <link rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
    <script
            src="https://ajax.googleapis.com/ajax/libs/jquery-3.3.1/jquery.min.js"></script>
    <script
            src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
    <script
            src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
</head>
<body>
<c:import url="/WEB-INF/views/include/top_menu.jsp"/>
<div class="container" style="margin-top: 100px">
    <div class="card shadow">
        <div class="card-body">
            <form action="${root}board/read" method="get">
                <div class="form-group">
                    <label for="board_subject">Subject</label>
                    <input type="text"
                           class="form-control" id="board_subject" name="board_subject"/>
                </div>

                <div class="form-group">
                    <label for="board_content">Content</label>
                    <textarea class="form-control" id="board_content" name="board_content"
                              rows="10" style="resize:none"></textarea>
                </div>

                <div class="form-group">
                    <div class="text-right">
                        <button type="submit" class="btn btn-dark">Write</button>
                    </div>
                </div>
            </form>
        </div>
    </div>


    <c:import url="/WEB-INF/views/include/bottom_menu.jsp"/>
</body>
</html>

 

read.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:set var="root" value="${pageContext.request.contextPath }/"/>

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <!-- Bootstrap CDN-->
    <link rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
    <script
            src="https://ajax.googleapis.com/ajax/libs/jquery-3.3.1/jquery.min.js"></script>
    <script
            src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
    <script
            src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
</head>
<body>
<c:import url="/WEB-INF/views/include/top_menu.jsp"/>
<div class="container" style="margin-top: 100px">
    <div class="card shadow">
        <div class="card-body">
            <div class="form-group">
                <label for="board_writer_name">Writer</label>
                <input type="text" value="Gildong.Hong" disabled="disabled"
                       class="form-control" id="board_writer_name" name="board_writer_name"/>
            </div>

            <div class="form-group">
                <label for="board_date">Wrote Date</label>
                <input type="text" value="2024-05-13" disabled="disabled"
                       class="form-control" id="board_date" name="board_date"/>
            </div>

            <div class="form-group">
                <label for="board_subject">Subject</label>
                <input type="text" value="Subject" disabled="disabled"
                       class="form-control" id="board_subject" name="board_subject"/>
            </div>

            <div class="form-group">
                <label for="board_content">Content</label>
                <textarea style="resize: none" rows="10" disabled="disabled"
                          class="form-control" id="board_content" name="board_content">Content</textarea>
            </div>

            <div class="form-group">
                <div class="text-right">
                    <a href="${root }board/main" class="btn btn-dark">List</a>
                    <a href="${root }board/modify" class="btn btn-info">Modify</a>
                    <a href="${root }board/delete" class="btn btn-danger">Delete</a>

        </div>
    </div>
</div>

<c:import url="/WEB-INF/views/include/bottom_menu.jsp"/>

</body>
</html>

 

modify.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:set var="root" value="${pageContext.request.contextPath }/"/>

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <!-- Bootstrap CDN-->
    <link rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
    <script
            src="https://ajax.googleapis.com/ajax/libs/jquery-3.3.1/jquery.min.js"></script>
    <script
            src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
    <script
            src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
</head>
<body>
<c:import url="/WEB-INF/views/include/top_menu.jsp"/>
<div class="container" style="margin-top: 100px">
    <div class="card shadow">
        <div class="card-body">
            <form action="${root}board/read" method="get">
                <div class="form-group">
                    <label for="board_writer_name">Writer</label>
                    <input type="text" value="Gildong.Hong" disabled="disabled"
                           class="form-control" id="board_writer_name" name="board_writer_name"/>
                </div>

                <div class="form-group">
                    <label for="board_date">Wrote Date</label>
                    <input type="text" value="2024-05-13" disabled="disabled"
                           class="form-control" id="board_date" name="board_date"/>
                </div>

                <div class="form-group">
                    <label for="board_subject">Subject</label>
                    <input type="text"
                           class="form-control" id="board_subject" name="board_subject"/>
                </div>

                <div class="form-group">
                    <label for="board_content">Content</label>
                    <textarea class="form-control" id="board_content" name="board_content"
                              rows="10" style="resize:none"></textarea>
                </div>

                <div class="form-group">
                    <div class="text-right">
                        <button type="submit" class="btn btn-dark">Modify Done</button>
                        <a href="${root }board/read" class="btn btn-info">Cancel</a>
                    </div>
                </div>
            </form>
        </div>
    </div>


    <c:import url="/WEB-INF/views/include/bottom_menu.jsp"/>
</body>
</html>

 

delete.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:set var="root" value="${pageContext.request.contextPath }/"/>
<script>
    alert("삭제되었습니다.");
    location.href="${root }main";
</script>

My SQL Table Setting

use khw;

create table board_info_table(
board_info_idx int auto_increment primary key,
board_info_name varchar(500) not null);

insert into board_info_table values(1,'1팀');
insert into board_info_table values(2,'2팀');
insert into board_info_table values(3,'3팀');
insert into board_info_table values(4,'4팀');

create table user_table(
user_idx int auto_increment primary key,
user_name varchar(50) not null,
user_id varchar(100) not null,
user_pw varchar(100) not null);

create table content_table(
content_idx int auto_increment primary key,
content_subject varchar(500) not null,
content_text text not null,
content_writer_idx int not null,
content_board_idx int not null,
content_date date not null,
foreign key(content_writer_idx) references user_table(user_idx),
foreign key(content_board_idx) references board_info_table(board_info_idx));

desc content_table;
desc user_table;
desc board_info_table;


select *from mvc_table;

 


Getter & Setter 설정

BoardInfo.java

package kr.bit.beans;

public class Boardinfo {
    private int board_info_idx;
    private String board_info_name;

    public int getBoard_info_idx() {
        return board_info_idx;
    }

    public void setBoard_info_idx(int board_info_idx) {
        this.board_info_idx = board_info_idx;
    }

    public String getBoard_info_name() {
        return board_info_name;
    }

    public void setBoard_info_name(String board_info_name) {
        this.board_info_name = board_info_name;
    }
}

Content.java

package kr.bit.beans;


import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Content {

    private int content_idx;
    private String content_subject;
    private String content_text;
    private int content_writer_idx;
    private int content_board_idx;
    private String content_date;
}

User.java

package kr.bit.beans;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class User {

    private int user_idx;
    private String user_name;
    private String user_id;
    private String user_pw;
}

 

db.properties

db.classname=com.mysql.cj.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/스키마이름
db.username=아이디
db.password=비번

 

ServletAppContext에 propertiesSource 추가

package kr.bit.config;

import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@EnableWebMvc
@ComponentScan("kr.bit.controller")
@PropertySource("/WEB-INF/views/properties/db.properties")
public class ServletAppContext implements WebMvcConfigurer {

    @Value("${db.classname}")
    private String db_classname;

    @Value("${db.url}")
    private String db_url;

    @Value("${db.username}")
    private String db_username;

    @Value("${db.password}")
    private String db_password;


    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        WebMvcConfigurer.super.configureViewResolvers(registry);
        registry.jsp("/WEB-INF/views/", ".jsp");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        WebMvcConfigurer.super.addResourceHandlers(registry);
        registry.addResourceHandler("/**").addResourceLocations("/resources/");
    }
//mybatis setting

    @Bean
    public BasicDataSource dataSource() {
        BasicDataSource source = new BasicDataSource();
        source.setDriverClassName(db_classname);
        //주소를 직접 치지않고, 위에서 주입받은 값 그대로!
        source.setUrl(db_url);
        source.setUsername(db_username);
        source.setPassword(db_password);

        return source;
    }

    @Bean
    public SqlSessionFactory factory(BasicDataSource source) throws Exception {
        SqlSessionFactoryBean fac = new SqlSessionFactoryBean();
        fac.setDataSource(source);
        SqlSessionFactory factory = fac.getObject();

        return factory;
    }

//  @Bean
//  public MapperFactoryBean<MapperInterface> test_mapper(SqlSessionFactory factory) throws Exception {
//
//     MapperFactoryBean<MapperInterface> fac =
//           new MapperFactoryBean<MapperInterface>(MapperInterface.class);
//
//     fac.setSqlSessionFactory(factory);
//     return fac;
//  }


}
728x90
728x90

WEB-INF/config/root-context.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                          http://www.springframework.org/schema/beans/spring-beans.xsd">



</beans>

WEB-INF/config/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
                          http://www.springframework.org/schema/mvc/spring-mvc.xsd
                          http://www.springframework.org/schema/beans
                          http://www.springframework.org/schema/beans/spring-beans.xsd
                          http://www.springframework.org/schema/context
                          http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 스캔한 패키지 내부의 클래스 중 controller로 로딩하도록 한다 -->
    <annotation-driven />

    <!-- 스캔할 Bean들이 모여있는 패키지를 지정한다 -->
    <context:component-scan
            base-package="kr.bit.controller" />

    <!-- controller메서드에서 반환하는 문자열 앞 뒤에 붙힐 경로 설정 -->
    <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>

    <!-- 정적파일 세팅 -->
    <resources location="/resources/" mapping="/**"></resources>

    <!-- properties파일 내용 쓸수있도록 bean정의해야함 -->
    <beans:bean class='org.springframework.beans.factory.config.PropertyPlaceholderConfigurer'>
        <beans:property name="location">
            <beans:value>/WEB-INF/properties/db.properties</beans:value>
        </beans:property>
    </beans:bean>

    <beans:bean class='org.apache.commons.dbcp2.BasicDataSource' id='basic_data_source'>
        <beans:property name='driverClassName' value='${db.classname}' />
        <beans:property name="url" value="${db.url}" />
        <beans:property name="username" value='${db.username}' />
        <beans:property name="password" value='${db.password}' />
    </beans:bean>

    <beans:bean class='org.mybatis.spring.SqlSessionFactoryBean' id='sqlSession'>
        <beans:property name="dataSource" ref='basic_data_source' />
        <beans:property name="mapperLocations" value='/WEB-INF/mapper/*.xml' />
    </beans:bean>

    <beans:bean class='org.mybatis.spring.SqlSessionTemplate' id='sqlSessionTemplate'>
        <beans:constructor-arg index='0' ref='sqlSession' />
    </beans:bean>
</beans:beans>

WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="4.0"
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                   http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd">

    <!-- 현재 웹 애플리케이션에서 받아들이는 모든 요청에 대해 appServlet이라는 이름으로 정의되어 있는 서블릿을 사용하겠다. -->
    <servlet-mapping>
       <servlet-name>appServlet</servlet-name>
       <url-pattern>/</url-pattern>
    </servlet-mapping>
    <!-- 요청 정보를 분석해서 컨트롤러를 선택하는 서블릿을 지정한다. -->
    <servlet>
       <servlet-name>appServlet</servlet-name>
       <!-- Spring MVC에서 제공하고 있는 기본 서블릿을 지정한다. -->
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
       <!-- Spring MVC 설정을 위한 xml 파일을 지정한다. -->
       <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/config/servlet-context.xml</param-value>
       </init-param>
       <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- Bean을 정의할 xml 파일을 지정한다. -->
    <context-param>
       <param-name>contextConfigLocation</param-name>
       <param-value>/WEB-INF/config/root-context.xml</param-value>
    </context-param>

    <!-- 리스너설정 -->
    <listener>
       <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- 파라미터 인코딩 필터 설정 -->
    <filter>
       <filter-name>encodingFilter</filter-name>
       <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
       <init-param>
          <param-name>encoding</param-name>
          <param-value>UTF-8</param-value>
       </init-param>
       <init-param>
          <param-name>forceEncoding</param-name>
          <param-value>true</param-value>
       </init-param>
    </filter>

    <filter-mapping>
       <filter-name>encodingFilter</filter-name>
       <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

WEB-INF/properties

 

db.classname=com.mysql.cj.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/스키마이름
db.username=아이디
db.password=비번

 

WEB-INF/mapper/mapper.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="test">
    <insert id="insert_data" parameterType="kr.bit.beans.Data">
       <![CDATA[
        insert into mvc_table(num1,num2,num3)
        values(#{num1}, #{num2}, #{num3})
        ]]>
    </insert>

    <select id="select_data" resultType="kr.bit.beans.Data">
       <![CDATA[
        select num1,num2,num3 from mvc_table
        ]]>
    </select>
</mapper>

 

pom.xml - 의존성 추가

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.2.3.RELEASE</version>
</dependency>


<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-dbcp2</artifactId>
    <version>2.7.0</version>
</dependency>

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.4</version>
</dependency>

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.3</version>
</dependency>


SpringController( @Mapping)

package kr.bit.controller;

import java.util.List;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import kr.bit.beans.Data;

@Controller
public class SpringController {

    @Autowired
    SqlSessionTemplate sqlSessionTemplate;

    @GetMapping("/input_test")
    public String input_test() {
        return "input_test";
    }

    @PostMapping("/input_proc")
    public String input_proc(Data data) {
        //                        namespace.id값
        sqlSessionTemplate.insert("test.insert_data", data);
        return "input_proc";
    }

    @GetMapping("/read_test")
    public String read_test(Model model) {

        List<Data> li=sqlSessionTemplate.selectList("test.select_data");

        model.addAttribute("li",li);
        return "read_test";

    }
}

MySql DB 테이블 설정


index.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>
	<a href="input_test">input_test</a><br>
	<a href="read_test">read_test</a>
	
	<!--  read_test컨트롤러 짜고 mapper짜고 read_test.jsp만들어서 내가 입력한 값을 브라우저 출력-->
	
</body>
</html>

 

input_test.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>
<form action="input_proc" method="post">
    num1 : <input type="text" name="num1"><br>  <!-- num1,2,3에 입력한 값을 Data클래스 필드에 넣기 -->
    num2 : <input type="text" name="num2"><br>
    num3 : <input type="text" name="num3"><br>

    <button type="submit">확인</button>
</form>



</body>
</html>

 

<%@ 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>
저장 끝
</body>
</html>

저장이 되면 저장 끝 문자열 출력됨..

 

 

db에 입력된 화면

 

 

 

 

read_test.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>
</head>
<body>

</body>
</html>

 

DB에 잘 들어간 모습을 볼 수 있다.

728x90

'Frameworks > Spring' 카테고리의 다른 글

[Spring] Board CRUD (use Bootstrap) II  (1) 2024.05.14
[Spring] Board CRUD (use Bootstrap)  (2) 2024.05.13
[Spring] MVC (Restcontroller)  (2) 2024.05.13
[Spring] MVC (DB Setting with MyBatis)  (2) 2024.05.12
[Spring] MVC (Interceptor)  (0) 2024.05.12

+ Recent posts