인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

학운학운님의 프로필 이미지
학운학운

작성한 질문수

스프링 프레임워크는 내 손에 [스프1탄]

'2022.12.23 오후 5:22에 질문드린 추가질문드립니다 글'에 대한 선생님 답변에 대한 질문입니다.

작성

·

310

0

안녕하세요 선생님.

 

먼저 BoardController입니다.

 

 

@Controller

public class BoardController {

@Autowired

private BoardMapper boardmapper;

// HandlerMapping

@GetMapping("/")

public String root() {

return "redirect:/main";

}

@GetMapping("/main")

public String main(Model model) {

List<Board> list = boardmapper.getLists();

model.addAttribute("list", list);

return "main"; // /WEB-INF/views/main.jsp -> forward

}

@GetMapping("/boardWriteForm")

public String boardWriteForm() {

return "boardWriteForm";

}

@PostMapping("/boardWrite")

public String boardWrite(Board vo) {

boardmapper.write(vo);

return "redirect:/main";

}

@GetMapping("/boardMore")

public String boardMore(@RequestParam("idx") int idx, Model model) {

//public String boardMore(int idx, Model model) {

boardmapper.boardCount(idx);

Board vo = boardmapper.boardMore(idx);

model.addAttribute("vo", vo);

return "boardMore";

}

@GetMapping("/boardDelete/{idx}")

public String boardDelete(@PathVariable("idx") int idx) {

boardmapper.boardDelete(idx);

return "redirect:/main";

}

@GetMapping("/boardUpdate/{idx}")

public String boardUpdateForm(@PathVariable("idx") int idx, Model model) {

Board vo = boardmapper.boardMore(idx);

model.addAttribute("vo", vo);

return "boardUpdateForm";

}

@PostMapping("/boardUpdate")

public String boardUpdate(Board vo) {

boardmapper.boardUpdate(vo);

return "redirect:/boardMore";

}

}

 

두번째로 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"%>

<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>

<!DOCTYPE html>

<html lang="en">

<head>

<title>Bootstrap Example</title>

<meta charset="utf-8" />

<meta name="viewport" content="width=device-width, initial-scale=1" />

<link rel="stylesheet"

href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" />

<script

src="https://cdn.jsdelivr.net/npm/jquery@3.6.1/dist/jquery.slim.min.js"></script>

<script

src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>

<script

src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>

</head>

<body>

<jsp:include page="header.jsp" />

<div class="container">

<h2>게시판</h2>

<table class="table table-bordered">

<thead>

<tr>

<th>번호</th>

<th>제목</th>

<th>작성자</th>

<th>작성일</th>

<th>조회수</th>

</tr>

</thead>

<tbody>

<c:forEach var="vo" items="${list}">

<tr>

<td>${vo.idx}</td>

<td><a href="boardMore?idx=${vo.idx}">${vo.title}</a></td>

<td>${vo.writer}</td>

<td>${fn:split(vo.indate, " ")[0]}</td>

<td>${vo.count}</td>

</tr>

</c:forEach>

<tr>

<td colspan="5" align="right"><a href="boardWriteForm"

class="btn btn-primary">게시글 작성</a></td>

</tr>

</tbody>

</table>

</div>

</body>

</html>

 

세번째로 boardMore.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="fn" uri="http://java.sun.com/jsp/jstl/functions"%>

<%

pageContext.setAttribute("newLineChar", "\n");

%>

<!DOCTYPE html>

<html lang="en">

<head>

<title>Bootstrap Example</title>

<meta charset="utf-8" />

<meta name="viewport" content="width=device-width, initial-scale=1" />

<link rel="stylesheet"

href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" />

<script

src="https://cdn.jsdelivr.net/npm/jquery@3.6.1/dist/jquery.slim.min.js"></script>

<script

src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>

<script

src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>

</head>

<body>

<jsp:include page="header.jsp" />

<div class="container">

<h2>게시글 상세</h2>

<table class="table table-bordered">

<tbody>

<tr>

<td style="max-width: 50px">제목</td>

<td>${vo.title}</td>

</tr>

<tr>

<td style="max-width: 50px">내용</td>

<td>${fn:replace(vo.content, newLineChar, "<br/>")}</td>

</tr>

<tr>

<td style="max-width: 50px">작성자</td>

<td>${vo.writer}</td>

</tr>

<tr>

<td style="max-width: 50px">작성일</td>

<td>${fn:split(vo.indate, " ")[0]}</td>

</tr>

<tr>

<td style="max-width: 50px">조회수</td>

<td>${vo.count}</td>

</tr>

<tr>

<td colspan="2" align="right"><a

href="boardUpdate/${vo.idx}"

class="btn btn-primary">수정</a> <a

href="boardDelete/${vo.idx}" class="btn btn-danger">삭제</a>

<a href="main" class="btn btn-success">목록</a></td>

</tr>

</tbody>

</table>

</div>

</body>

</html>

 

네번째로 boardUpdateForm.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="fn" uri="http://java.sun.com/jsp/jstl/functions"%>

<!DOCTYPE html>

<html lang="en">

<head>

<title>Bootstrap Example</title>

<meta charset="utf-8" />

<meta name="viewport" content="width=device-width, initial-scale=1" />

<link rel="stylesheet"

href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" />

<script

src="https://cdn.jsdelivr.net/npm/jquery@3.6.1/dist/jquery.slim.min.js"></script>

<script

src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>

<script

src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>

</head>

<body>

<!-- <nav class="navbar navbar-expand-md bg-dark navbar-dark">

<a class="navbar-brand" href="../main"><img style="max-width: 80px"

src="../resources/images/logo.png" /></a>

<ul class="nav navbar-nav navbar-right">

<li class="nav-item"><a class="nav-link" href="#">김명수님,

안녕하세요</a></li>

<li class="nav-item"><a class="nav-link" href="#">회원정보수정</a></li>

<li class="nav-item"><a class="nav-link" href="#">로그아웃</a></li>

</ul>

</nav> -->

<br>

<div class="container">

<h2>게시글 수정</h2>

<form action="../boardUpdate" method="post">

<input type="hidden" name="idx" value="${vo.idx}" />

<table class="table table-bordered">

<tr>

<td style="min-width: 100px;">제목</td>

<td><input type="text" name="title" class="form-control"

value="${vo.title}" required></td>

</tr>

<tr>

<td>내용</td>

<td><textarea name="content" class="form-control" rows="10"

required>${vo.content}</textarea></td>

</tr>

<tr>

<!-- 추후 세션으로 처리 -->

<td>작성자</td>

<td><input type="text" name="writer" class="form-control"

value="${vo.writer}" readonly></td>

</tr>

<tr>

<td colspan="2" align="right">

<button type="button" class="btn btn-danger"

onclick="location.href='../boardMore'">취소</button>

<button type="submit" class="btn btn-primary">수정완료</button>

</td>

</tr>

</table>

</form>

</div>

</body>

</html>

 

마지막으로 header.jsp입니다.

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<nav class="navbar navbar-expand-md bg-dark navbar-dark">

<a class="navbar-brand" href="main"><img

style="max-width: 80px" src="resources/images/logo.png" /></a>

<ul class="nav navbar-nav navbar-right">

<li class="nav-item"><a class="nav-link" href="#">김명수님, 안녕하세요</a>

</li>

<li class="nav-item"><a class="nav-link" href="#">회원정보수정</a></li>

<li class="nav-item"><a class="nav-link" href="#">로그아웃</a></li>

</ul>

</nav>

<br>

 

header.jsp를 공통적으로 적용하면 다 잘 되는데 updateForm에서는 logo를 인식하지 못합니다. logo의 주소가 No mapping found for HTTP request with URI [/m01/boardUpdate/resources/images/logo.png] 이런식으로 나오게 됩니다.

지금 올린 코드에서는 주석처리한 부분이 공통적으로 한 것이 아니고 그 페이지에만 해당하는 방식으로 했습니다. 공통적으로 처리하는 방법 없을까요?

<!-- <nav class="navbar navbar-expand-md bg-dark navbar-dark">

<a class="navbar-brand" href="../main"><img style="max-width: 80px"

src="../resources/images/logo.png" /></a>

<ul class="nav navbar-nav navbar-right">

<li class="nav-item"><a class="nav-link" href="#">김명수님,

안녕하세요</a></li>

<li class="nav-item"><a class="nav-link" href="#">회원정보수정</a></li>

<li class="nav-item"><a class="nav-link" href="#">로그아웃</a></li>

</ul>

</nav> -->

 

그리고 updateForm에서 취소버튼을 누르나 제출버튼을 누르나

HTTP 상태 400 – 잘못된 요청


타입 상태 보고

메시지 Required int parameter 'idx' is not present

설명 클라이언트 오류로서 인지된 어떤 문제로 인하여, 서버가 해당 요청을 처리할 수 없거나, 처리하지 않을 것입니다. (예: 잘못된 요청 문법, 유효하지 않은 요청 메시지 framing, 또는 신뢰할 수 없는 요청 라우팅).

이렇게 나오는 것도 왜 그런지 모르겠습니다...

public String boardMore(@RequestParam("idx") int idx, Model model) {

//public String boardMore(int idx, Model model) {

컨트롤러에서 이 부분은 int idx가 한개이므로 위나 아래나 다 가능한 것 아닌가요? 아래것으로 하면 오류가 java.lang.IllegalStateException: Optional int parameter 'idx' is not present but cannot be translated into a null value due to being declared as a primitive type. Consider declaring it as object wrapper for the corresponding primitive type.

이런 오류가 납니다.

그런데 오류가 나고 나서 다시 목록으로 가 보면 수정은 완료되어 있습니다. DB에 반영은 됩니다.

 

오류를 고치고자 선생님 올려주신 github 보고 계속 해봐도 도저히 안 됩니다. 어떻게 고쳐야 할까요??

답변 2

1

박매일님의 프로필 이미지
박매일
지식공유자

취소버튼을 누르면 다시 리스트로 가야되는데 boardMore로 가고있습니다 그리고 boardMore로 가면 idx를 가지고 가야되는데 넘어가지도 않구요

<button type="button" class="btn btn-danger"

onclick="location.href='../boardMore'">취소</button>

아래를 보시면 컨트롤러에서 idx를 받아야되는데 위 취소를 누르면 idx가 넘어오지 않기 때문에 에러가 날것입니다.

public String boardMore(@RequestParam("idx") int idx, Model model) {

//public String boardMore(int idx, Model model) {

이렇게 해보세요

<button type="button" class="btn btn-danger"

onclick="location.href='../boardMore?idx=${vo.idx}'">취소</button>

학운학운님의 프로필 이미지
학운학운
질문자

선생님 안녕하세요

선생님 답변 덕분에 많이 해결되고 있습니다 감사합니다.

 

@RequestMapping("/boardUpdate")

public String boardUpdate(Board vo) {

boardmapper.boardUpdate(vo);

return "redirect:/boardMore/{idx}";

}

 

이런식으로 업데이트 후에 게시글 상세 페이지인 /boardMore/{idx}로 가고 싶은데

Request processing failed; nested exception is java.lang.IllegalArgumentException: Model has no value for key 'idx'

라는 오류가 납니다. 오류가 나는 이유와 해결방법 알 수 있을까요?

 

boardMore/{idx]에 대한 컨트롤러는

 

@RequestMapping("/boardMore/{idx}")

public String boardMore(@PathVariable("idx") int idx, Model model) {

boardmapper.boardCount(idx);

Board vo = boardmapper.boardMore(idx);

model.addAttribute("vo", vo);

return "boardMore";

}

 

이렇게 작성했구요.

 

boardUpdateForm은 아래와 같이 해서 PathVariable으로 처리하게 해서 취소와 로고는 처리했습니다.

 

<%@ 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="fn" uri="http://java.sun.com/jsp/jstl/functions"%>

<!DOCTYPE html>

<html lang="en">

<head>

<title>Bootstrap Example</title>

<meta charset="utf-8" />

<meta name="viewport" content="width=device-width, initial-scale=1" />

<link rel="stylesheet"

href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" />

<script

src="https://cdn.jsdelivr.net/npm/jquery@3.6.1/dist/jquery.slim.min.js"></script>

<script

src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>

<script

src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>

</head>

<body>

<!-- <nav class="navbar navbar-expand-md bg-dark navbar-dark">

<a class="navbar-brand" href="../main"><img style="max-width: 80px"

src="../resources/images/logo.png" /></a>

<ul class="nav navbar-nav navbar-right">

<li class="nav-item"><a class="nav-link" href="#">김명수님,

안녕하세요</a></li>

<li class="nav-item"><a class="nav-link" href="#">회원정보수정</a></li>

<li class="nav-item"><a class="nav-link" href="#">로그아웃</a></li>

</ul>

</nav>

<br> -->

<jsp:include page="header.jsp" />

<div class="container">

<h2>게시글 수정</h2>

<form action="../boardUpdate" method="post">

<input type="hidden" name="idx" value="${vo.idx}" />

<table class="table table-bordered">

<tr>

<td style="min-width: 100px;">제목</td>

<td><input type="text" name="title" class="form-control"

value="${vo.title}" required></td>

</tr>

<tr>

<td>내용</td>

<td><textarea name="content" class="form-control" rows="10"

required>${vo.content}</textarea></td>

</tr>

<tr>

<!-- 추후 세션으로 처리 -->

<td>작성자</td>

<td><input type="text" name="writer" class="form-control"

value="${vo.writer}" readonly></td>

</tr>

<tr>

<td colspan="2" align="right">

<button type="button" class="btn btn-danger"

onclick="location.href='../boardMore/${vo.idx}'">취소</button>

<button type="submit" class="btn btn-primary">수정완료</button>

</td>

</tr>

</table>

</form>

</div>

</body>

</html>

박매일님의 프로필 이미지
박매일
지식공유자

업데이트 후에 idx를 다시 가지고 갈려면 아래처럼 값을 쿼리스트링 형태로 넘겨야될듯합니다.

@RequestMapping("/boardUpdate")

public String boardUpdate(Board vo) {

boardmapper.boardUpdate(vo);

return "redirect:/boardMore/"+vo.getIdx();

}

학운학운님의 프로필 이미지
학운학운
질문자

감사합니다!! 잘 작동합니다

학운학운님의 프로필 이미지
학운학운
질문자

강의중에서 배운 내용인데 확실히 만들어보면서 복습하니 제 것으로 되는 것이 느껴지네요. 감사합니다.

박매일님의 프로필 이미지
박매일
지식공유자

네 코드를 직접 수정을 못해주니 저도 답답했는데 가이드를 잘 보시면서 잘 하시고 계시군요 ㅎ 자기것으로 만들어보는것도 중요합니다.

마무리까지 잘 하시구요^^

1

박매일님의 프로필 이미지
박매일
지식공유자

이미지 경로는

<a class="navbar-brand" href="../main"><img style="max-width: 80px"

src="${cpath}/resources/images/logo.png" /></a>

또는

<a class="navbar-brand" href="../main"><img style="max-width: 80px"

src="/m01/resources/images/logo.png" /></a>

이런식으로 해야 이미지 경로가 잘 인식 될겁니다.

학운학운님의 프로필 이미지
학운학운
질문자

감사합니다!!

Required int parameter 'idx' is not present

이 오류는 어떻게 고쳐야 할까요?

박매일님의 프로필 이미지
박매일
지식공유자

아래 답글을 참고하세요^^

학운학운님의 프로필 이미지
학운학운

작성한 질문수

질문하기