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="수정">
<a href="${pageContext.request.contextPath}/restful/board">목록보기</a>
<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="답변"> <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 |