✏ 이제 작성된 글을 수정해봅시다!
JSON 형식을 사용해 전송해야 하므로 다음 라이브러리를 추가합니다.
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.2</version>
</dependency>
우선 요청을 보낼 때 id를 함께 보내기 위해 아래 태그를 <c:when test="${post!=null}"> 태그에 있는 form안에 추가합니다. hidden속성을 주어서 보이지 않도록 합니다.
<input type="number" name="id" value="${post.id}" hidden>
수정 역시 이전에 사용했던 post.jsp를 수정해서 사용하도록 하겠습니다.아래 태그를 <c:when test="${post!=null}"> 태그에 있는 form안에 추가합니다. 만약 모델의 isModify가 false일 경우 Modify버튼이 나오게하고 아니라면 Submit버튼이 나오게 해 제출을 할 수 있도록 합니다. 그리고 Modify가 true일 때, 즉 수정 화면일 때 아래 jquery가 실행되도록 합니다.
<c:choose>
<c:when test="${!isModify}">
<a id="modify" href="/post/${post.id}?isModify=true" class="btn btn-primary btn-user btn-block">
Modify
</a>
</c:when>
<c:otherwise>
<a id="modifySubmit" class="btn btn-primary btn-user btn-block">
Submit
</a>
</c:otherwise>
</c:choose>
<c:if test="${isModify}">
<script>
$("input").removeAttr("readonly")
$("textarea").removeAttr("readonly")
$("#modifySubmit").click(function (){
var postVO =new Object()
postVO.id = $("[name='id']").val()
postVO.title = $("[name='title']").val()
postVO.content= $("[name='content']").val()
postVO.name = $("[name='name']").val()
$.ajax({
type:"PUT",
url:"/post",
contentType:"application/json; charset=utf-8",
data:JSON.stringify(postVO),
success:function (data) {
if(data)
location.href="/post/"+postVO.id
}
})
})
</script>
</c:if>
이 스크립트는 수정 화면일 때 input, textarea의 readonly 속성을 제거하여 수정을 할 수 있게 해주고, modifySubmit라는 id를 가진 태그가 눌리면 postVO라는 객체를 만들어 정보를 담아 JSON형태로 /post로 PUT요청을 보냅니다. 요청이 성공적으로 끝나고 반환된 data가 true일 시 수정한 post로 다시 redirect됩니다.
<script src="/vendor/jquery/jquery.min.js"></script>
스크립트는 이 코드 밑에 적어야 합니다.
jquery?
JS를 사용하기 쉽게 만들어 놓은 라이브러리입니다.
ajax란?
자바스크립트의 라이브러리 중 하나이며 비동기식 통신을 하기 위한 라이브러리 입니다. 아래는 기본 형식입니다.
$.ajax({ type:, //http 메소드 url:, //요청 보낼 주소 data:, //요청 보낼 때 보낼 데이터(body 부분) contentType:, success:function(){}//요청이 성공적으로 끝났을 시 });
JSON?
JavaScript Object Notation의 약자로 {태그:데이터}의 형식입니다.
EX) {id:1, title: "json"...}
우리는 DB접근시간을 최소화하기 위해 멀티쿼리를 사용해서 UPDATE후 바로 SELECT로 해당 글을 반환하도록 할 것입니다. 그러기 위해서는 JDBC URL을 아래와 같이 수정해주어야 합니다.
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/spring?allowMultiQueries=true");
그 후 인터페이스와 xml에 update를 추가해줍니다.
public PostVO update(PostVO postVO);
<mapper namespace="ac.kr.smu.mapper.PostMapper">
<insert id="save">
INSERT INTO post(title,content,created_date,name)
VALUES(#{title},#{content},#{created_date},#{name})
</insert>
<select id="findAll" resultType="PostVO">
SELECT * FROM post
</select>
<select id="findById" resultType="PostVO">
SELECT * FROM post WHERE id=#{id}
</select>
<select id="update" resultType="PostVO">
UPDATE post SET title=#{title}, content=#{content},name=#{name} WHERE id=#{id};
SELECT * FROM post WHERE id=#{id}
</select>
</mapper>
멀티쿼리를 사용하면 마지막 SQL문을 제외하고 ;를 붙여야합니다.
마찬가지로 update를 추가해줍니다.
public interface PostService {
public void save(PostVO postVO);
public List<PostVO> findAll();
public PostVO findById(int id);
public PostVO update(PostVO postVO);
}
@Service
public class PostServiceImpl implements PostService {
@Autowired
private PostMapper postMapper;
public void save(PostVO postVO){
postMapper.save(postVO);
}
@Override
public List<PostVO> findAll() {
return postMapper.findAll();
}
@Override
public PostVO findById(int id) {
return postMapper.findById(id);
}
@Override
public PostVO update(PostVO postVO) {
return postMapper.update(postVO);
}
}
우선 getPost를 수정합니다. 앞에서 post.jsp를 수정할 때 Modify버튼의 요청 주소가 /post/${post.id}?isModify=true였습니다. 이를 받아서 @RequestParam isModify변수에 저장합니다. 따라서 만약 수정 요청을 보내면 수정화면을 출력할 수 있도록 모델에 isModify속성을 추가하고 true를 넣습니다. 아니라면 false를 넣습니다. 또한 PUT요청을 처리할 메소드를 만듭니다.
@Controller
@RequestMapping("/post")
public class PostController {
@Autowired
private PostService postService;
@GetMapping({"/{postId}", ""})
public String getPost(@PathVariable(value = "postId", required = false) Integer postId,
@RequestParam(value = "isModify", required = false) boolean isModify, Model model) {
if (postId != null)
model.addAttribute("post", postService.findById(postId));
if (isModify)
model.addAttribute("isModify", true);
else
model.addAttribute("isModify", false);
return "post";
}
@PostMapping
public String postPost(PostVO postVO) {
postService.save(postVO);
return "board";
}
@PutMapping
public @ResponseBody boolean putPost(@RequestBody PostVO postVO, Model model) {
model.addAttribute("post", postService.update(postVO));
model.addAttribute("isModify", false);
return true;
}
}
PUT요청을 처리하는 부분에서는 수정된 post를 업데이트하고 다시 그 글을 모델에 넣어서 반환해줍니다. 반환해주는 화면은 수정 화면이 아니므로 isModify를 false로 해줍니다.
URL로 파라미터를 넘기는 법은 두가지가 있습니다. 하나는 앞에서 보았던 방법이고 다른 하나는 URL에 ?와 &를 사용해서 보내는 방법입니다. 그리고 Spring에서는 이를 @RequestParm을 사용하여 변수에 저장할 수 있습니다.
EX) /post?id=1&title=hello
@ResponseBody는 Controller가 객체를 반환할 수 있도록 해줍니다.
@RequestBody는 Request의 body를 받아옵니다. 이 예제에서는 요청에서 body에 {id:1,title:"title",...} 이런 식으로 요청이 전송되고 이를 받아서 postVO에 저장합니다.