본문 바로가기

bitcamp/면접족보

면접족보 21/02/10_RESTful, Intercptor

1. RESTful을 적용하여 답변 구현을 완성하시오. (URL 설계 포함, Reply)

<RestBoardController.java>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 @Log4j 
 @AllArgsConstructor
 @RestController
 @RequestMapping("/restful/*")
 public class RestBoardController {
    private BoardService boardService;
 
    @GetMapping("/board")
    public ModelAndView list(ModelAndView mav) {
        mav.setViewName("rest_list"); // rest_list.jsp로 보내줌
        mav.addObject("list", boardService.getList());
 
        return mav;
    }
        
    @GetMapping("/board/reply_view/{bId}")
    public ModelAndView rest_reply_view(BoardVO boardVO, ModelAndView mav) {
        log.info("rest_content_view");
        
        mav.setViewName("rest_reply_view");
        mav.addObject("reply_view", boardService.replyview(boardVO.getbId()));
 
        return mav;
    }
    
    @PostMapping("/board/{bId}")
    public ResponseEntity<String> rest_reply(@RequestBody BoardVO boardVO, ModelAndView mav) {
        ResponseEntity<String> entity = null;
        log.info("rest_reply");
        try {
            boardService.reply(boardVO);
            entity = new ResponseEntity<String>("SUCCESS", HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            entity = new ResponseEntity<String>(e.getMessage(), HttpStatus.BAD_REQUEST);
    }
    return entity;
    }
 }
cs

 

<content_view.jsp>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<body>
 <form id="form" action="${pageContext.request.contextPath}/restful/board/${content_view.bId}" method="post">
    <input type="hidden" name="bId" value="${content_view.bId}">
    <table width="500" cellpadding="0" cellspacing="0" border="1">
        <tr>
            <td>번호</td>
            <td><input type="text" id="bId" value="${content_view.bId}"></td>
        </tr>
        <tr>
            <td>히트</td>
            <td><input type="text" id="bHit" value="${content_view.bHit}"></td>
        </tr>
        <tr>
            <td>이름</td>
            <td><input type="text" id="bName" value="${content_view.bName}"></td>
        </tr>
        <tr>
            <td>제목</td>
            <td><input type="text" id="bTitle" value="${content_view.bTitle}"></td>
        </tr>
        <tr>
            <td>내용</td>
            <td><textarea rows="10" id="bContent">${content_view.bContent}</textarea></td>
        </tr>        
        <tr>
            <td colspan="5"><input type="submit" value="수정"> 
            &nbsp;&nbsp; <a href="${pageContext.request.contextPath}/restful/board">목록보기</a>
            &nbsp;&nbsp; <a href="${pageContext.request.contextPath}/restful/board/reply_view/${content_view.bId}">답변</a>
            </td>
        </tr>
    </table>
    </form>
 </body>
cs

 

<reply_view.jsp>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 <title>Insert title here</title>
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
 <script type="text/javascript">
    $(document).ready(function(){
        $("#form").submit(function(event){
            event.preventDefault(); 
    
            var bId = $("#bId").val();
            var bName = $("#bName").val();
            var bTitle = $("#bTitle").val();
            var bContent = $("#bContent").val();
            var bGroup = $("#bGroup").val();
            var bStep = $("#bStep").val();
            var bIndent = $("#bIndent").val();
                
            var form = {
                    bId: bId,
                    bName: bName,
                    bTitle: bTitle,
                    bContent: bContent,
                    bGroup: bGroup,
                    bStep: bStep,
                    bIndent: bIndent
            };
            
            $.ajax({
                    type : "POST",
                    url: $(this).attr("action"),
                    contentType: 'application/json; charset=utf-8',
                    data: JSON.stringify(form),
                    success: function (result) {       
                    if(result == "SUCCESS"){
                        console.log(result); 
                        $(location).attr('href''${pageContext.request.contextPath}/restful/board');
                    }
             },
             error: function (e) {
                console.log(e);
             }
        })
    });
 });        
 </script>
 </head>
 <body>
    <form id="form" action="${pageContext.request.contextPath}/restful/board/${reply_view.bId}" method="post">
        <input type="hidden" id="bId" value="${reply_view.bId}">
        <input type="hidden" id="bGroup" value="${reply_view.bGroup}">
        <input type="hidden" id="bStep" value="${reply_view.bStep}">
        <input type="hidden" id="bIndent" value="${reply_view.bIndent}">
        <table width="500" cellpadding="0" cellspacing="0" border="1">
            <tr>
                <td>번호</td>
                <td><input type="text" name="bId" value="${reply_view.bId}"></td>
            </tr>
            <tr>
                <td>히트</td>
                <td><input type="text" name="bHit" value="${reply_view.bHit}"></td>
            </tr>
            <tr>
                <td>이름</td>
                <td><input type="text" id="bName" value="${reply_view.bName}"></td>
            </tr>
            <tr>
                <td>제목</td>
                <td><input type="text" id="bTitle" value="${reply_view.bTitle}"></td>
            </tr>
            <tr>
                <td>내용</td>
                <td><textarea rows="10" id="bContent">${reply_view.bContent}</textarea></td>
            </tr>
            <tr>
                <td colspan="5"><input type="submit" value="답변"> &nbsp;&nbsp; <a href="${pageContext.request.contextPath}/restful/board">목록보기</a></td>
            </tr>
        </table>
    </form>
 </body>
 </html>
cs

 

<구현 화면>

 

2. 부트스트랩으로 로그인 화면 구현 후, 로그인한 유저에게만 게시판이 보이도록 하시오.

 단, img는 정적리소스, 로그인은 interceptor를 적용시킬 것!

 

<UserVO.java>

1
2
3
4
5
6
7
8
9
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class UserVO {
    String username;
    String password;
    char enabled;
}
cs

 

<BoardIntercepton.java>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 @Log4j
 public class BoardInterceptor extends HandlerInterceptorAdapter {
    //기본적으로 두 개의 메소드를 구현할 수 있다, preHandle() : 컨트롤러보다 먼저 수행되는 메서드
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    //Interceptor에서는 request, response객체가 Controller로 넘어가기 전에 중간에서 컨트롤한다.
        System.out.println("preHandle 실행");
        //session 객체를 가져옴
        HttpSession session = request.getSession();
 
        //사용자 정보를 담고 있는 객체를 가져옴
        UserVO user = (UserVO) session.getAttribute("user");
 
        if (user == null) {
            log.info("user가 null");
            //user가 null이라면, LoginController에 설정한 "/"로 유입되면서 로그인 폼으로 돌려보냄(redirect)
            response.sendRedirect(request.getContextPath());
 
            return false// 더 이상 컨트롤러 요청으로 가지 않도록 false로 반환
        }
        // preHandle의 return은 컨트롤러 요청 uri로 가도 되냐 안되냐를 허가하는 의미임
        // 따라서 true로하면 컨트롤러 uri로 가게 됨.
        return true;
    }
 
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
 
        super.postHandle(request, response, handler, modelAndView);
        System.out.println("postHandle 실행");
   }
 }
cs

 

<LoginController.java>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
@Log4j
@AllArgsConstructor
@Controller
public class LoginController {
    private LoginService loginService;
 
    @GetMapping("/")
    public String home() {
        log.info("home");
 
        return "logintest";
    }
 
    @PostMapping("/login")
    public String login(HttpServletRequest req, RedirectAttributes rttr) {
        log.info("login");
        String id = req.getParameter("id");
        String pw = req.getParameter("pw");
        HttpSession session = req.getSession();
        // Session 처리를 위한 Session 객체 HttpServletRequest 안에 있음
        // user한테 30분의 session 번호를 제공
 
        UserVO user = loginService.loginUser(id, pw);
 
        if (user == null) {
            session.setAttribute("user"null);
            rttr.addFlashAttribute("msg"false);
            //일회성으로 로그인 잘못했을때 멘트 보임과 동시에 새로고침하면 다시 로그인 창으로 변환
        } else {
            session.setAttribute("user", user);
        }
        return "redirect:/";
    }
 
    // 로그아웃
    @RequestMapping(value = "/logout")
    public String logout(HttpSession session) throws Exception {
        log.info("/member/logout");
 
        session.invalidate(); //로그아웃하면 정보 삭제
 
        return "redirect:/";
    }
}
 
cs

 

<LoginService.java>

1
2
3
4
5
6
7
8
9
 @Service
 @AllArgsConstructor
 public class LoginService {
    LogInMapper logInMapper;
    
    public UserVO loginUser(String id, String pw) {
        return logInMapper.logInUser(id, pw);
    }
 }
cs

 

<LoginMapper.java>

1
2
3
4
5
6
7
 @Mapper
 public interface LogInMapper {
   
   @Select("select * from users where username = #{username} and password = #{password}")
   public UserVO logInUser(@Param("username") String username,@Param("password") String password);
    //파라미터가 두개일때는 변수명도 두번 적어줘야함.
 }
cs

<logintest.jsp>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
 
 <html>
 <head>   
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
 <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
 <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
 <title></title>
 <style type="text/css">
    body{
        text-align: center;
        background-color: #F5F5F5;    
        padding: 150px;
    }
    div{
         display: inline-block;
         text-align: center;               
    }      
 </style>
 </head>
 <body>
    <div class="container p-3 my-center ">
        <img class="rounded mb-4" width="70" height="70" src="${pageContext.request.contextPath}/resources/img/photo.JPG" > 
        <h3>Please sign in</h3>
 
        <c:if test="${user == null}">
            <form action="${pageContext.request.contextPath}/login" method="post">    
        
                <input class="form-control" id="userId" type="text" placeholder="Id" name="id" />
                <input class="form-control" id="userPass" type="password" placeholder="Password" name="pw" />
               
                <div class="form-check mb-3">             
                    <input type="checkbox" class="form-check-input" id="check">Remember me       
                </div>
           
                <button type="submit" class="btn btn-lg btn-primary">Sign in</button>
            </form>
        </c:if>
    
        <c:if test="${msg == false}">
            <p style="color:#f00;">로그인에 실패했습니다. 아이디 또는 패스워드를 다시 입력해주십시오.</p>
        </c:if>
    
        <c:if test="${user != null}">
            <p>${user.username}님 환영합니다.</p>
            <a href="${pageContext.request.contextPath}/restful/board">게시판 리스트</a><br>
            <a href="${pageContext.request.contextPath}/logout">로그아웃</a> 
        </c:if>
    </div>
 </body>
 </html>
cs

 

<login.jsp>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 <head>
 <title>로그인</title>
 </head>
 <body>
    <%
       String path = request.getContextPath();
    %>
    <%=path%>
 
    <c:if test="${user == null}">
    <!-- user는 session에서 가져옴 -->
    <form role="form" method="post" autocomplete="off" action="${pageContext.request.contextPath}/login">
        <p>
            <label for="userId">아이디</label>
            <input type="text" id="userId" name="id" />
       </p>
       <p>
           <label for="userPass">패스워드</label>
           <input type="password" id="userPass" name="pw" />
        </p>
        <p><button type="submit">로그인</button></p>
    </form>
    </c:if>
 
    <c:if test="${msg == false}">
        <p style="color:#f00;">로그인에 실패했습니다. 아이디 또는 패스워드를 다시 입력해주십시오.</p>
    </c:if>
 
    <c:if test="${user != null}">
        <p>${user.username}님 환영합니다.</p>
        <a href="<%=path%>/restful/board">게시판 리스트</a><br>
        <a href="<%=path%>/logout">로그아웃</a>   
    </c:if>
 </body>
cs

 

<구현 화면>

 

3. Intercptor의 개념에 대하여 설명하시오.

· Interceptor 객체는 DispatcherServlet과 Controller사이에 위치하여 사용자의 요청과 서버의 응답을 가로채는 역할을 한다.

· DispatcherServlet과 Interceptor사이에는 preHandle과 postHandle 객체가 주고 받으며, 두 개의 객체는 스프링에서 실행한다.

· ex) 인터셉터는 로그인 상태에 따라 페이지 출력 여부를 구분하는 역할을 한다. 

       로그인 상태라면 클라이언트의 요청 페이지를 나타내며, 비회원의 경우 해당 url에 접근 할 수 없도록 처리한다. 

 

· Interceptor 객체를 사용하기 위해서는 아래와 같이 설정하도록 한다.

 (Controller 이전에 해당되는 부분이기 때문에 servlet-context.xml에 내용 추가)

 

4. 부트스트랩이란?

· 부트스트랩은 각종 레이아웃, 버튼, 입력창 등의 디자인을 HTML, CSS, JavaScript를 기반으로하여 만들어진 프레임워크이다.
· 여러 개발자들의 공동작업이 이루어질때, 디자인 불일치, 방대한 코드량, 관리 어려움 등의 일관성을 유지하기가

  힘든 문제점을 개선하기 위해 개발되었다.

· 부트스트랩 기존의 태그도 새로 설정하였기 때문에 기존의 태그와 화면 상에서 차이가 존재한다. 
· <html>에서 개발자가 class를 정의하여 css를 적용하는데, 설정하지 않은 함수가 인식되는 이유는

  부트스트랩에서 정의 된 class를 사용하기 때문이다.

 

 



 

 

 

'bitcamp > 면접족보' 카테고리의 다른 글

면접족보 21/02/16_스프링시큐리티  (0) 2021.02.17
면접족보 21/02/15_ AOP  (0) 2021.02.17
면접족보 21/02/09_트랜잭션  (0) 2021.02.17
면접족보 21/02/08_RESTful  (0) 2021.02.16
면접족보 21/02/05_비동기ajax  (0) 2021.02.15