오늘이라도
[Spring] 19. 방명록 만들기 ⑤ : 덧글 수정, 삭제 / 공공 데이터 API 가져오기 본문
취업성공패키지 SW 개발자 교육/Spring
[Spring] 19. 방명록 만들기 ⑤ : 덧글 수정, 삭제 / 공공 데이터 API 가져오기
upcake_ 2020. 7. 27. 14:23반응형
https://github.com/upcake/Class_Examples
교육 중에 작성한 예제들은 깃허브에 올려두고 있습니다.
gif 파일은 클릭해서 보는 것이 정확합니다.
- 방명록 만들기 ⑤ : 덧글 수정, 삭제 / 공공 데이터 API 가져오기 -
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="core" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<core:forEach items="${list }" var="vo" varStatus="status">
<!-- varStatus 인덱스값 찾아갈때 사용하는 속성 -->
${status.index eq 0 ? '<hr>' : '' }
<div data-id="${vo.id }"> <!-- data-* 속성 : 특별한 조작 없이 HTML 요소에 추가 정보를 저장할 수 있게 해주는 속성 -->
${vo.name } [${vo.writedate }]
<core:if test="${login_info.id eq vo.writer }"><!-- 로그인한 사용자가 작성한 댓글 수정/삭제 기능 -->
<span style="float:right;">
<a class="btn-fill-s btn-modify-save">수정</a>
<a class="btn-fill-s btn-delete-cancel">삭제</a>
</span>
</core:if>
<div class="original">${fn:replace(fn:replace(vo.content, lf, '<br>' ), crlf, '<br>') }</div>
<div class="modify" style="display:none; margin-top:6px;"></div>
</div>
<hr>
</core:forEach>
<script>
/* closest()
현재 element 에서 탐색 출발
DOM 트리에서 selector 에 매칭되는 하나의 element 를 찾을 때까지 위로 탐색
반환된 jQuery 객체는 0개 또는 1개의 element 를 포함한다.
*/
/*
$('.original').each(function(){
$(this).text(
$(this).text().replace(/</g, '$lt;').replace(/>/g, '$gt;')
.replace(/<br>/g, '<br>')
);
});
*/
//수정 / 저장 버튼 클릭
$('.btn-modify-save').on('click', function(){
var $div = $(this).closest('div');
if( $(this).text() == '수정' ) {
//수정 텍스트 창 크기 고정
$div.children('.modify').css('height', $div.children('.original').height()-6);
//줄바꿈 태그 변환
var tag = "<textarea style='width:99%; height:90%; resize:none'>" + $div.children('.original').html().replace(/<br>/g, '\n') + "</textarea>";
$div.children('.modify').html(tag);
display($div, 'm');
} else {
var comment = {id:$div.data('id'),
content:$div.children('.modify').find('textarea').val() };
//alert(JSON.stringify(comment)); JSON형태로 잘 출력되는지 확인
$.ajax({
url: 'board/comment/update',
data: JSON.stringify(comment),
contentType: 'application/json',
type: 'post',
success: function(data) {
alert(data);
comment_list();
}, error: function(req, text) {
alert(text + ':' + req.status);
}
});
}
});
//삭제 / 취소 버튼 클릭
$('.btn-delete-cancel').on('click', function(){
var $div = $(this).closest('div');
if( $(this).text() == '취소' ) {
display($div, 'd');
} else {
if( confirm('정말 삭제하시겠습니까?') ) {
$.ajax({
url: 'board/comment/delete/' + $div.data('id'),
success: function() {
comment_list();
}, error: function(req, text) {
alert(text + ':' + req.status);
},
});
}
}
})
function display(div, mode) {
//수정 상태(m) : 저장/취소, 원글 안 보이고, 수정 글은 보이고
//보기 상태(d) : 수정/삭제, 원글 보이고, 수정 글은 안 보이고
div.find('.btn-modify-save').text(mode=='m' ? '저장' : '수정');
div.find('.btn-delete-cancel').text(mode=='m' ? '취소' : '삭제');
div.children('.original').css('display', mode=='m' ? 'none' : 'block');
div.children('.modify').css('display', mode=='m' ? 'block' : 'none');
}
</script>
▲list.jsp
package com.hanul.iot;
import java.io.File;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import board.BoardCommentVO;
import board.BoardPage;
import board.BoardServiceImpl;
import board.BoardVO;
import common.CommonService;
import member.MemberVO;
@Controller
public class BoardController {
@Autowired private BoardServiceImpl service;
@Autowired private BoardPage page;
@Autowired private CommonService common;
//방명록 목록 화면 요청================================================================
@RequestMapping("/list.bo")
public String list(HttpSession session, Model model, @RequestParam(defaultValue = "1") int curPage,
String search, String keyword, @RequestParam(defaultValue = "10") int pageList,
@RequestParam(defaultValue = "list") String viewType) {
//DB에서 방명록 정보를 조회해와 목록 화면에 출력
session.setAttribute("category", "bo");
page.setCurPage(curPage);
page.setSearch(search);
page.setKeyword(keyword);
page.setPageList(pageList);
page.setViewType(viewType);
model.addAttribute("page", service.board_list(page));
return "board/list";
} //list()
//방명록 신규 화면 요청================================================================
@RequestMapping("/new.bo")
public String board() {
//방명록 글쓰기 화면으로 연결
return "board/new";
} // board()
//신규 방명록 저장 처리 요청================================================================
@RequestMapping("/insert.bo")
public String insert(BoardVO vo, MultipartFile file, HttpSession session) {
//화면에서 입력한 정보를 DB에 저장한 후 목록 화면으로 연결
if( !file.isEmpty() ) {
vo.setFilename( file.getOriginalFilename() );
vo.setFilepath(common.upload("board", file, session));
}
vo.setWriter( ((MemberVO) session.getAttribute("login_info")).getId() );
service.board_insert(vo);
return "redirect:list.bo";
} //insert()
//방명록 상세 화면 요청====================================================================
@RequestMapping("/detail.bo")
public String detail(int id, Model model) {
//선택한 방명록 글을 DB에서 조회해와 상세 화면에 출력
service.board_read(id);
model.addAttribute("vo", service.board_detail(id));
model.addAttribute("page", page);
model.addAttribute("crlf", "\r\n");
return "board/detail";
} //detail()
//방명록 상세 화면 요청====================================================================
@ResponseBody @RequestMapping("/download.bo")
public void download(int id, HttpSession session, HttpServletResponse response) {
//해당 글의 첨부 파일 정보를 조회해와 다운로드한다.
BoardVO vo = service.board_detail(id);
common.download(vo.getFilename(), vo.getFilepath(), session, response);
} //download()
//방명록 수정 화면 요청====================================================================
@RequestMapping("/modify.bo")
public String modify(int id, Model model) {
//선택한 방명록 글의 정보를 DB에서 조회해와 수정 화면에 출력
model.addAttribute("vo", service.board_detail(id));
return "board/modify";
} //modify()
//방명록 수정 화면 요청====================================================================
@RequestMapping("/update.bo")
public String update(BoardVO vo, MultipartFile file, HttpSession session, String attach, Model model) {
//화면에서 입력한 정보를 DB에 변경, 저장한 후 상세 화면으로 연결
BoardVO board = service.board_detail(vo.getId());
String uuid = session.getServletContext().getRealPath("resources") + board.getFilepath();
//파일을 첨부한 경우 - 없었는데 새로 첨부, 있었는데 바꿔 첨부
if( !file.isEmpty() ) {
vo.setFilename(file.getOriginalFilename());
vo.setFilepath(common.upload("board", file, session));
if( board.getFilename() != null ) {
File f = new File(uuid);
if( (f.exists()) ) { f.delete(); }
}
} else {
//파일 첨부가 없는 경우 - if 없었고, else 있었는데 그대로 사용하는 경우
if( attach.isEmpty() ) {
File f = new File(uuid);
if( (f.exists()) ) { f.delete(); }
} else {
vo.setFilename(board.getFilename());
vo.setFilepath(board.getFilepath());
}
}
service.board_update(vo);
//기존 방법
//return "redirect:detail.bo?id=" + vo.getId();
//다른 방법
model.addAttribute("url", "detail.bo");
model.addAttribute("id", vo.getId());
return "board/redirect";
} //update()
//방명록 수정 화면 요청====================================================================
@RequestMapping("/delete.bo")
public String delete(int id, Model model) {
//선택한 글을 DB에서 삭제한 후 목록 화면으로 연결
service.board_delete(id);
model.addAttribute("url", "list.bo");
model.addAttribute("id", id);
model.addAttribute("page", page);
return "board/redirect";
} //delete()
//댓글 저장 처리 요청====================================================================
@ResponseBody @RequestMapping ("/board/comment/insert")
public boolean comment_insert(BoardCommentVO vo, HttpSession session) {
//화면에서 입력한 정보를 DB에 저장한다.
vo.setWriter( ((MemberVO) session.getAttribute("login_info")).getId());
return service.board_comment_insert(vo) > 0 ? true : false;
} //comment_insert()
//댓글 목록 조회 요청====================================================================
@RequestMapping("/board/comment/{pid}")
public String comment_list(@PathVariable int pid, Model model) {
//DB에서 댓글 목록을 조회해와 댓글 목록 화면에 출력
model.addAttribute("list", service.board_comment_list(pid));
model.addAttribute("crlf", "\r\n");
model.addAttribute("lf", "\n"); // lf의 형태로 라인피드가 저장될 수도 있어서 윗라인이 적용이 안될경우 이 코드도 작성한다.
return "board/comment/list";
} //comment_list()
//댓글 변경 저장 처리 요청
@ResponseBody @RequestMapping(value="/board/comment/update", produces="application/text; charset=utf-8")
public String comment_update(@RequestBody BoardCommentVO vo) {
return service.board_comment_update(vo) > 0 ? "성공" : "실패";
} //comment_update()
//댓글 삭제 처리 요청
//ResponseBody : 화면(jsp)으로 연결이 아니라 호출한쪽으로 돌아갈때 사용하는 어노테이션
@ResponseBody @RequestMapping("/board/comment/delete/{id}")
public void comment_delete(@PathVariable int id) {
service.board_comment_delete(id);
} //comment_delete()
} //class
▲BoardController.java
package board;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class BoardServiceImpl implements BoardService {
@Autowired private BoardDAO dao;
@Override
public int board_insert(BoardVO vo) {
return dao.board_insert(vo);
}
@Override
public BoardPage board_list(BoardPage page) {
return dao.board_list(page);
}
@Override
public BoardVO board_detail(int id) {
return dao.board_detail(id);
}
@Override
public void board_read(int id) {
dao.board_read(id);
}
@Override
public int board_update(BoardVO vo) {
return dao.board_update(vo);
}
@Override
public int board_delete(int id) {
return dao.board_delete(id);
}
@Override
public int board_comment_insert(BoardCommentVO vo) {
return dao.board_comment_insert(vo);
}
@Override
public List<BoardCommentVO> board_comment_list(int pid) {
return dao.board_comment_list(pid);
}
@Override
public int board_comment_update(BoardCommentVO vo) {
return dao.board_comment_update(vo);
}
@Override
public int board_comment_delete(int id) {
return dao.board_comment_delete(id);
}
}
▲BoardServiceImpl.java
package board;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class BoardDAO implements BoardService {
@Autowired private SqlSession sql;
@Override
public int board_insert(BoardVO vo) {
return sql.insert("board.mapper.insert", vo);
}
@Override
public BoardPage board_list(BoardPage page) {
page.setTotalList((Integer) sql.selectOne("board.mapper.total", page));
page.setList(sql.selectList("board.mapper.list", page));
return page;
}
@Override
public BoardVO board_detail(int id) {
return sql.selectOne("board.mapper.detail", id);
}
@Override
public void board_read(int id) {
sql.update("board.mapper.read", id);
}
@Override
public int board_update(BoardVO vo) {
return sql.update("board.mapper.update", vo);
}
@Override
public int board_delete(int id) {
return sql.delete("board.mapper.delete", id);
}
@Override
public int board_comment_insert(BoardCommentVO vo) {
return sql.insert("board.mapper.comment_insert", vo);
}
@Override
public List<BoardCommentVO> board_comment_list(int pid) {
return sql.selectList("board.mapper.comment_list", pid);
}
@Override
public int board_comment_update(BoardCommentVO vo) {
return sql.update("board.mapper.comment_update", vo);
}
@Override
public int board_comment_delete(int id) {
return sql.delete("board.mapper.comment_delete", id);
}
}
▲BoardDAO.java
<?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="board.mapper">
<select id="total" resultType="integer">
SELECT COUNT(*) FROM board <include refid="search"/>
</select>
<select id="list" resultType="board.BoardVO">
SELECT n.*, (SELECT name FROM member WHERE member.id=writer) name
FROM (SELECT b.*, ROWNUM no
FROM (SELECT * FROM board <include refid="search"/> ORDER by id) b
ORDER BY no DESC) n
WHERE no BETWEEN #{beginList } AND #{endList }
</select>
<sql id="search">
<if test="search == 'title' or search == 'content'" >
WHERE ${search } LIKE '%' || #{keyword } || '%'
</if>
<if test="search == 'writer'" >
WHERE <include refid="writer" />
</if>
<if test="search == 'all'">
WHERE TITLE LIKE '%' || #{keyword } || '%'
OR content LIKE '%' || #{keyword } || '%'
OR <include refid="writer" />
</if>
</sql>
<sql id="writer">
writer IN (SELECT id FROM member WHERE name LIKE '%' || #{keyword } || '%')
</sql>
<insert id="insert">
INSERT INTO board(title, content, writer, filename, filepath)
VALUES (#{title }, #{content}, #{writer}, #{filename, jdbcType=VARCHAR}, #{filepath, jdbcType=VARCHAR} )
</insert>
<update id="read">
UPDATE BOARD SET readcnt= readcnt + 1 WHERE id= #{id }
</update>
<select id="detail" resultType="board.BoardVO">
SELECT b.*, (SELECT name FROM member m WHERE m.id= b.writer) name
FROM board b
WHERE id=#{id }
</select>
<update id="update">
UPDATE board SET title=#{title }, content=#{content }, filename=#{filename, jdbcType=VARCHAR}, filepath=#{filepath, jdbcType=VARCHAR}
WHERE id=#{id }
</update>
<delete id="delete">
DELETE FROM board WHERE id=#{id}
</delete>
<insert id="comment_insert">
INSERT INTO board_comment(content, pid, writer)
VALUES (#{content}, #{pid}, #{writer})
</insert>
<select id="comment_list" resultType="board.BoardCommentVO">
SELECT c.*, (SELECT name FROM member m WHERE m.id=writer) name,
TO_CHAR(writedate, 'yyyy-mm-dd hh24:mi:ss') writedate
FROM board_comment c
WHERE pid=#{pid}
ORDER BY id DESC
</select>
<update id="comment_update">
UPDATE board_comment SET content=#{content} WHERE id=#{id}
</update>
<delete id="comment_delete">
DELETE FROM board_comment WHERE id=#{id}
</delete>
</mapper>
▲board-mapper.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><response><header><resultCode>00</resultCode><resultMsg>NORMAL SERVICE.</resultMsg></header><body><items><item><addr>서울특별시 강남구 영동대로112길 15 103호 (삼성동, 풍림아파트상가)</addr><clCd>81</clCd><clCdNm>약국</clCdNm><estbDd>19790209</estbDd><postNo>06082</postNo><sgguCd>110001</sgguCd><sgguCdNm>강남구</sgguCdNm><sidoCd>110000</sidoCd><sidoCdNm>서울</sidoCdNm><telno>545-0164</telno><XPos>127.0615148</XPos><YPos>37.5155186</YPos><yadmNm>부활약국</yadmNm><ykiho>JDQ4MTg4MSM1MSMkMSMkMCMkMDMkMzgxMzUxIzExIyQxIyQzIyQ3OSQyNjEwMDIjNDEjJDEjJDgjJDgz</ykiho></item><item><addr>서울특별시 강남구 봉은사로 465 (삼성동)</addr><clCd>81</clCd><clCdNm>약국</clCdNm><emdongNm>삼성동</emdongNm><estbDd>19741211</estbDd><postNo>06096</postNo><sgguCd>110001</sgguCd><sgguCdNm>강남구</sgguCdNm><sidoCd>110000</sidoCd><sidoCdNm>서울</sidoCdNm><telno>02-545-2467</telno><XPos>127.0504907</XPos><YPos>37.5124855</YPos><yadmNm>신삼성약국</yadmNm><ykiho>JDQ4MTg4MSM1MSMkMSMkMCMkMDMkMzgxMzUxIzExIyQxIyQzIyQ3OSQyNjE4MzIjODEjJDEjJDIjJDgz</ykiho></item><item><addr>서울특별시 강남구 봉은사로114길 42 (삼성동)</addr><clCd>81</clCd><clCdNm>약국</clCdNm><emdongNm>삼성동</emdongNm><estbDd>20000630</estbDd><postNo>06172</postNo><sgguCd>110001</sgguCd><sgguCdNm>강남구</sgguCdNm><sidoCd>110000</sidoCd><sidoCdNm>서울</sidoCdNm><telno>02-556-8357</telno><XPos>127.0653425</XPos><YPos>37.5121721</YPos><yadmNm>강남소화약국</yadmNm><ykiho>JDQ4MTg4MSM1MSMkMSMkMCMkMDMkMzgxMzUxIzExIyQxIyQzIyQ3OSQzNjE4MzIjNDEjJDEjJDgjJDgz</ykiho></item><item><addr>서울특별시 강남구 삼성로 549 (삼성동, 정화빌딩)</addr><clCd>81</clCd><clCdNm>약국</clCdNm><estbDd>19860906</estbDd><postNo>06155</postNo><sgguCd>110001</sgguCd><sgguCdNm>강남구</sgguCdNm><sidoCd>110000</sidoCd><sidoCdNm>서울</sidoCdNm><telno>557-7676</telno><XPos>127.0542916</XPos><YPos>37.5106027</YPos><yadmNm>은약국</yadmNm><ykiho>JDQ4MTg4MSM1MSMkMSMkMCMkMDMkMzgxMzUxIzExIyQxIyQzIyQ4OSQzNjE4MzIjODEjJDEjJDIjJDgz</ykiho></item><item><addr>서울특별시 서초구 서초대로74길 23 102호 (서초동)</addr><clCd>81</clCd><clCdNm>약국</clCdNm><emdongNm>서초동</emdongNm><estbDd>20070222</estbDd><postNo>06621</postNo><sgguCd>110021</sgguCd><sgguCdNm>서초구</sgguCdNm><sidoCd>110000</sidoCd><sidoCdNm>서울</sidoCdNm><telno>02-3474-0617</telno><XPos>127.0271068</XPos><YPos>37.4956227</YPos><yadmNm>서초삼성약국</yadmNm><ykiho>JDQ4MTg4MSM1MSMkMSMkMCMkMDMkMzgxMzUxIzExIyQxIyQzIyQ5OSQyNjE0ODEjODEjJDEjJDIjJDgz</ykiho></item><item><addr>서울특별시 강동구 천호대로 1195 지앤지타워 1층 101호 (길동)</addr><clCd>81</clCd><clCdNm>약국</clCdNm><estbDd>20200309</estbDd><postNo>05350</postNo><sgguCd>110002</sgguCd><sgguCdNm>강동구</sgguCdNm><sidoCd>110000</sidoCd><sidoCdNm>서울</sidoCdNm><telno>02-472-3311</telno><XPos>127.1439027</XPos><YPos>37.5350031</YPos><yadmNm>강동엠약국</yadmNm><ykiho>JDQ4MTg4MSM1MSMkMSMkMCMkMDMkMzgxMzUxIzExIyQxIyQzIyQ5OSQzNjE0ODEjNDEjJDEjJDgjJDgz</ykiho></item><item><addr>서울특별시 강남구 논현로 88 3층 (개포동, 노엘빌딩)</addr><clCd>81</clCd><clCdNm>약국</clCdNm><emdongNm>개포동</emdongNm><estbDd>20100810</estbDd><postNo>06307</postNo><sgguCd>110001</sgguCd><sgguCdNm>강남구</sgguCdNm><sidoCd>110000</sidoCd><sidoCdNm>서울</sidoCdNm><telno>02-571-0043</telno><XPos>127.0451614</XPos><YPos>37.4778221</YPos><yadmNm>다나약국</yadmNm><ykiho>JDQ4MTg4MSM1MSMkMSMkMCMkMDMkMzgxMzUxIzExIyQxIyQzIyQ5OSQ0NjE0ODEjNTEjJDEjJDYjJDgz</ykiho></item><item><addr>서울특별시 성북구 돌곶이로41길 10 (장위동)</addr><clCd>81</clCd><clCdNm>약국</clCdNm><emdongNm>장위동</emdongNm><estbDd>20050303</estbDd><postNo>02754</postNo><sgguCd>110012</sgguCd><sgguCdNm>성북구</sgguCdNm><sidoCd>110000</sidoCd><sidoCdNm>서울</sidoCdNm><telno>02-942-4553</telno><XPos>127.0457034</XPos><YPos>37.6184653</YPos><yadmNm>선약국</yadmNm><ykiho>JDQ4MTg4MSM1MSMkMSMkMCMkMDMkMzgxMzUxIzExIyQyIyQzIyQwMCQzNjE0ODEjODEjJDEjJDIjJDgz</ykiho></item><item><addr>서울특별시 동작구 시흥대로 662 (신대방동)</addr><clCd>81</clCd><clCdNm>약국</clCdNm><estbDd>20101220</estbDd><postNo>07068</postNo><sgguCd>110008</sgguCd><sgguCdNm>동작구</sgguCdNm><sidoCd>110000</sidoCd><sidoCdNm>서울</sidoCdNm><telno>02-6104-1234</telno><XPos>126.9082173</XPos><YPos>37.4906353</YPos><yadmNm>대림온누리약국</yadmNm><ykiho>JDQ4MTg4MSM1MSMkMSMkMCMkMDMkMzgxMzUxIzExIyQyIyQzIyQwMCQzNjEwMDIjNjEjJDEjJDgjJDgz</ykiho></item><item><addr>서울특별시 강남구 도산대로 113 1층 (신사동)</addr><clCd>81</clCd><clCdNm>약국</clCdNm><estbDd>20170721</estbDd><postNo>06035</postNo><sgguCd>110001</sgguCd><sgguCdNm>강남구</sgguCdNm><sidoCd>110000</sidoCd><sidoCdNm>서울</sidoCdNm><telno>02-549-8774</telno><XPos>127.0208674</XPos><YPos>37.5170222</YPos><yadmNm>가나안약국</yadmNm><ykiho>JDQ4MTg4MSM1MSMkMSMkMCMkMDMkMzgxMzUxIzExIyQxIyQzIyQ2MiQyNjEyMjIjODEjJDEjJDYjJDgz</ykiho></item></items><numOfRows>10</numOfRows><pageNo>1</pageNo><totalCount>23138</totalCount></body></response>
▲가져온 약국 API 데이터
package com.hanul.iot;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import common.CommonService;
@Controller
public class DataController {
private String key = "API 키";
@Autowired private CommonService common;
@RequestMapping("/list.da")
public String data(HttpSession session) {
session.setAttribute("category", "da");
return "data/list";
}
//약국 정보 조회 요청
@ResponseBody @RequestMapping("/data/pharmacy")
public String pharmarcy_list() {
StringBuilder url
= new StringBuilder("http://apis.data.go.kr/B551182/pharmacyInfoService/getParmacyBasisList");
url.append("?ServiceKey=" + key);
return common.xml_list(url);
}
}
▲DataController.java
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>data list jsp</title>
</head>
<body>
<h3>공공 데이터</h3>
<div class="btnSet">
<a class="btn-fill">약국 조회</a>
<a class="btn-fill">유기 동물 조회</a>
</div>
<div id="data-list" style="margin:20px 0 auto"></div>
<script type="text/javascript">
$('.dataOption a').click(function() {
//이미 선택된 내용에 대해서는 적용하지 않으려면
if( $(this).hasClass('btn-empty') ) {
alert('누름')
$('.dataOption a').removeClass();
$(this).addClass('btn-fill');
var idx = $(this).index();
$('.dataOption a:not(:eq(' + idx + '))').addClass('btn-empty');
if( idx == 0) { pharmacy_list(); }
else { animal_list(); }
}
});
pharmacy_list();
function pharmacy_list() {
$.ajax({
url:'data/pharmacy',
success: function(){
}, error: function(text, req) {
alert(text + " : " + req.status)
}
});
}
function animal_list() {
}
</script>
</body>
</html>
▲list.jsp
package common;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.mail.EmailAttachment;
import org.apache.commons.mail.HtmlEmail;
import org.apache.commons.mail.MultiPartEmail;
import org.apache.commons.mail.SimpleEmail;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
@Service
public class CommonService {
public void sendEmail(String email, String name, HttpSession session) {
//1. 기본 이메일 전송 처리
//sendSimple(email, name);
//2. 첨부 파일 있는 이메일 전송 처리
//session이 있어야 파일 첨부가 가능
//sendAttach(email, name, session);
//3. HTML 태그 이메일 전송 처리
sendHtml(email, name, session);
//4. 공공 데이터 REST API 요청 처리
};
private void sendSimple(String email, String name) {
SimpleEmail mail = new SimpleEmail();
mail.setHostName("smtp.naver.com"); //메일 전송 서버 지정, 네이버 메일 - 환경설정 - pop3 설정
mail.setCharset("utf-8"); //인코딩 설정
mail.setDebug(true); //메일 전송 과정 추적해서 콘솔에 띄워줌
mail.setAuthentication("아이디", "비밀번호"); //로그인하기 위해 정보 입력
mail.setSSLOnConnect(true); //입력한 정보로 로그인 요청
try {
mail.setFrom("보내는 메일", "관리자"); //보내는 사람 메일 / 이름 설정
mail.addTo(email, name); //받는 사람 메일 / 이름, 회원가입 페이지에에서 가져온다.
mail.addTo("받을 메일", "수신자"); //복수의 사람 지정 가능
mail.setSubject("회원가입 축하"); //메일 제목
mail.setMsg(name + "님! 가입을 축하드립니다!"); //메일 내용
mail.send(); //메일 발송
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
private void sendAttach(String email, String name, HttpSession session) {
MultiPartEmail mail = new MultiPartEmail();
mail.setHostName("smtp.naver.com"); //메일 전송 서버 지정, 네이버 메일 - 환경설정 - pop3 설정
mail.setCharset("utf-8"); //인코딩 설정
mail.setDebug(true); //메일 전송 과정 추적해서 콘솔에 띄워줌
mail.setAuthentication("아이디", "비밀번호"); //로그인하기 위해 정보 입력
mail.setSSLOnConnect(true); //입력한 정보로 로그인 요청
try {
mail.setFrom("보내는 메일", "관리자"); //보내는 사람 메일 / 이름 설정
mail.addTo(email, name); //받는 사람 메일 / 이름, 회원가입 페이지에에서 가져온다.
mail.addTo("받을 메일", "수신자"); //복수의 사람 지정 가능
mail.setSubject("첨부 파일 테스트"); //메일 제목
mail.setMsg(name + "님! 가입을 축하드립니다!\n 첨부 파일 테스트"); //메일 내용
//파일 첨부하기
EmailAttachment file = new EmailAttachment();
//① 물리적 디스크내 파일 첨부
file.setPath("D:\\이력서-자소서-양식.hwp");
mail.attach(file);
//② 프로젝트 내의 파일 첨부
file = new EmailAttachment();
file.setPath(session.getServletContext().getRealPath("resources/images/logo.png"));
mail.attach(file);
//③ URL을 통해 파일 첨부
file = new EmailAttachment();
file.setURL(new URL("https://mvnrepository.com/assets/images/392dffac024b9632664e6f2c0cac6fe5-logo.png"));
mail.attach(file);
mail.send(); //메일 발송
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
private void sendHtml(String email, String name, HttpSession session) {
HtmlEmail mail = new HtmlEmail();
mail.setHostName("smtp.naver.com"); //메일 전송 서버 지정, 네이버 메일 - 환경설정 - pop3 설정
mail.setCharset("utf-8"); //인코딩 설정
mail.setDebug(true); //메일 전송 과정 추적해서 콘솔에 띄워줌
mail.setAuthentication("아이디", "비밀번호"); //로그인하기 위해 정보 입력
mail.setSSLOnConnect(true); //입력한 정보로 로그인 요청
try {
mail.setFrom("보내는 메일", "관리자"); //보내는 사람 메일 / 이름 설정
mail.addTo(email, name); //받는 사람 메일 / 이름, 회원가입 페이지에에서 가져온다.
mail.addTo("받을 메일", "수신자"); //복수의 사람 지정 가능
mail.setSubject("HTML 메일 테스트");
StringBuffer msg = new StringBuffer();
msg.append("<html>");
msg.append("<body>");
msg.append("<a href='https://mvnrepository.com'><img src='https://mvnrepository.com/assets/images/392dffac024b9632664e6f2c0cac6fe5-logo.png' /></a>");
msg.append("<hr>");
msg.append("<h3>HTML 메일 테스트</h3>");
msg.append("<p>가입을 축하드립니다.</p>");
msg.append("<p>HTML 메일 테스트</p>");
msg.append("</body>");
msg.append("</html>");
mail.setHtmlMsg(msg.toString());
EmailAttachment file = new EmailAttachment();
file.setPath(session.getServletContext().getRealPath("resources/css/common.css"));
mail.attach(file);
file = new EmailAttachment();
file.setURL(new URL("https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"));
mail.attach(file);
mail.send();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
//첨부 파일 업로드 처리////////////////////////////////////////////////////////
public String upload(String category, MultipartFile file, HttpSession session) {
//서버의 업로드할 물리적 위치
// workspace/.metadata/....../wtpwebapps/iot/resources
String resources = session.getServletContext().getRealPath("resources");
String upload = resources + "/upload";
//업로드할 파일의 형태 : .../upload/notice/2020/07/13/abc.txt
//String folder = upload + "/upload/2020/07/13";
String folder = upload + "/" + category + "/" + new SimpleDateFormat("yyyy/MM/dd").format(new Date());
//폴더가 없다면 폴더를 생성
File f = new File(folder);
if(!f.exists()) { f.mkdirs(); } //폴더가 존재하지 않으면 경로 생성
//동시 다발적 동일명의 파일 업로드를 위한 고유 ID 부여: afd324adfa_abc.txt
String uuid = UUID.randomUUID().toString() + "_" + file.getOriginalFilename();
try {
file.transferTo( new File(folder, uuid) );
} catch (Exception e) {
System.out.println(e.getMessage());
}
// /upload/.../asdfadsfsa_abc.txt ▶ 업로드한 파일의 경로를 반환
// ① folder.replace(resources, "")
// ② folder.substring(resources.length()) + "/" + uuid;
return folder.substring(resources.length()) + "/" + uuid;
} //upload()
//첨부 파일 다운로드 처리///////////////////////////////////////////////////////
public File download(String filename, String filepath, HttpSession session, HttpServletResponse response) {
File file = new File(session.getServletContext().getRealPath("resources") + filepath);
//filepath에 resources/ << 슬래쉬부터의 경로가 저장되어 있다
String mime = session.getServletContext().getMimeType(filename);
response.setContentType(mime);
try {
filename = URLEncoder.encode(filename, "utf-8").replaceAll("\\+", "%20");
// + 는 기호라 \ 필요, \ 또한 기호라 \ 필요
// %20 = 스페이스바
response.setHeader("content-disposition", "attachment; filename=" + filename);
ServletOutputStream out = response.getOutputStream();
FileCopyUtils.copy(new FileInputStream(file), out);
out.flush();
} catch(Exception e) {
System.out.println(e.getMessage());
}
return file;
} //download()
// 공공 데이터 REST API 요청 처리=========================================================================
public String xml_list(StringBuilder url) {
String result = url.toString();
try {
HttpURLConnection conn
= (HttpURLConnection)new URL( result ).openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-type", "application/json");
BufferedReader rd;
if(conn.getResponseCode() >= 200 && conn.getResponseCode() <= 300) {
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
} else {
rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
}
StringBuilder sb = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
conn.disconnect();
result = sb.toString();
System.out.println(result);
}catch(Exception e) {
System.out.println(e.getMessage());
}
return result;
}
}
▲CommonService.java
반응형
'취업성공패키지 SW 개발자 교육 > Spring' 카테고리의 다른 글
[Spring] 21. 약국 조회 리스트뷰, 그리드뷰, 페이징 구현 (0) | 2020.07.29 |
---|---|
[Spring] 20. 공공 데이터 약국 API 출력, 구글 지도 API로 구글 지도 활용 (2) | 2020.07.28 |
[Spring] 18. 방명록 만들기 ④ : 사진 미리보기, 덧글 기능 (0) | 2020.07.24 |
[Spring] 17. 방명록 만들기 ③ : 글 상세 조회, 수정 (0) | 2020.07.23 |
[Spring] 16. 방명록 만들기 ② : 첨부파일 미리보기, 게시글 표시 갯수, 게시판 표시 형태 (0) | 2020.07.22 |