Mybatis
오늘은 Mybatis 복습을 하도록 한다.
오라클의 데이터 형이 char인경우 공백을 제거해야
아이디와 비밀번호의 유효성을 확실히 알 수 있다.
<?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="adminTDao">
<select id="adminT_selectOne" parameterType="adminT" resultType="adminT">
select id, password, name from adminT
where TRIM(id) = #{id} and TRIM(password) = #{password}
</select>
<select id="adminT_selectAll" parameterType="adminT" resultType="adminT">
select id, password, name from adminT order by id desc
</select>
<insert id="adminT_insert" parameterType="adminT">
insert into adminT(id,password,name)
values (#{id}, #{password}, #{name})
</insert>
</mapper>
TRIM을 통해 공백을 제거해주어서 ID와 PWD의 유무를 보다 정확하게 구분할 수 있다.
package com.jungbo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.jungbo.k1.adminT.AdminServiceImpl;
import com.jungbo.k1.adminT.AdminTVO;
@Controller
public class AdminTController {
@Autowired
AdminServiceImpl service;
@RequestMapping(value="getAdminTList.do")
public ModelAndView getAdminTList(AdminTVO vo, ModelAndView mav) {
mav.addObject("li",service.selectAll(vo));
mav.setViewName("/adminT/getAdminTList.jsp");
return mav;
}
@RequestMapping(value="getAdminTOne.do")
public ModelAndView getAdminTOne(AdminTVO vo, ModelAndView mav) {
System.out.println("==============> getAdminTOne vo 값 " + service.selectOne(vo));
// 로그인 정보 유효성 검사
AdminTVO key = service.selectOne(vo);
// 내가 입력한 PWD - DB에 저장된 PWD를 비교
if(BCrypt.checkpw(vo.getPassword(), key.getPassword())) {
mav.addObject("m",service.selectOne(vo));
mav.setViewName("/adminT/success.jsp");
}else {
mav.setViewName("/adminT/fail.jsp");
}
return mav;
}
@RequestMapping(value="insertAdminT.do")
public String insertAdminT(AdminTVO vo) {
// 비밀번호 암호화(60자)
String enc = BCrypt.hashpw(vo.getPassword(), BCrypt.gensalt());
vo.setPassword(enc);
service.insert(vo);
return "/getAdminTList.do";
}
}
로그인 정보 유효성 검사를 위해 SelectOne(vo)를 받아 ID값을 비교 후
비밀번호를 암호화 하는 BCrypt 클래스를 불러와 암호를 비교하여
회원 정보의 유효성을 검사한다.
이외에는 기존에 했던 내용과 유사하여 스킵~!
불러온 API 경로 출처
- [공공데이터포털](https://www.data.go.kr/data/15062486/openapi.do)
- [카카오DEVELOP](https://developers.kakao.com/)
공공데이터포털에서는 사용신청 후 미리보기로 형식을 지정하여 XML 형식을 불러올수 있었고, 카카오톡은 내 어플리케이션에서 web 경로 지정후 자바스크립트 코드를 사용해서 할 수 있었다.
package com.jungbo.controller;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.springframework.stereotype.Controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import com.jungbo.k1.openapi.CompanyServiceImpl;
import com.jungbo.k1.openapi.CompanyVO;
@Controller
public class OpenApiController {
@Autowired
CompanyServiceImpl service;
@GetMapping("/company/companySelectAll.do")
String companySelectAll ( CompanyVO vo , Model model ) {
model.addAttribute("li", service.selectAll(vo));
return "/company/getCompanyList.jsp";
}
@GetMapping("/company/companyEdit.do")
String companyEdit ( CompanyVO vo , Model model ) {
model.addAttribute("m", service.getCompany(vo));
CompanyVO vo1 = service.getCompany(vo);
model.addAttribute("m1", vo1.getLatitude());
model.addAttribute("m2", vo1.getLogitude());
return "/company/companyEdit.jsp";
}
// http://apis.data.go.kr/6480000/ <=== https 를 http 로 변경하기
@GetMapping("/company/apiController.do")
public String apiinsert( CompanyVO vo ) throws Exception {
// url Http에서 s가 붙어있으면 제외시키기
StringBuilder urlBuilder = new StringBuilder("http://apis.data.go.kr/6480000/gyeongnamgoodemploycompany/gyeongnamgoodemploycompanylist"); /*URL*/
urlBuilder.append("?" + URLEncoder.encode("serviceKey","UTF-8") + "=vP4H3hy9P5MkOjE3j4%2Fa1FBnWQEK0m655CFmdCBt46INOFeZupMk8Av4dJREFRiRaBW%2B90TkC79D6FiE3uCqig%3D%3D"); /*Service Key (일반인증키)*/
urlBuilder.append("&" + URLEncoder.encode("pageNo","UTF-8") + "=" + URLEncoder.encode("1", "UTF-8")); /*페이지 번호*/
urlBuilder.append("&" + URLEncoder.encode("numOfRows","UTF-8") + "=" + URLEncoder.encode("25", "UTF-8")); /*한 페이지 결과 수 (최소 10, 최대 9999)*/
urlBuilder.append("&" + URLEncoder.encode("returnType","UTF-8") + "=" + URLEncoder.encode("xml", "UTF-8")); /*상태갱신 조회 범위(분) (기본값 5, 최소 1, 최대 10)*/
URL url = new URL(urlBuilder.toString());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-type", "application/json");
System.out.println("Response code: " + conn.getResponseCode());
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();
// XML 데이터 읽어 오기
System.out.println(sb.toString());
Node data1 = null;
Node data2 = null;
Node data3 = null;
Node data4 = null;
Node data5 = null;
Node data6 = null;
try {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder=dbFactory.newDocumentBuilder();
FileOutputStream output = new FileOutputStream("./ApiExplorer");
output.write(sb.toString().getBytes("UTF-8")); // 전체 데이터 읽어 오기
output.close();
Document doc = dBuilder.parse("./ApiExplorer");
doc.getDocumentElement().normalize();
// getElementsByTagName 태그안에있는 메소드를 다 불러온다.
Element body =(Element) doc.getElementsByTagName("body").item(0);
Element items =(Element) body.getElementsByTagName("items").item(0);
// service.deleteAll();
for(int i=0 ; i<=24 ; i++ ) {
Element item =(Element) items.getElementsByTagName("item").item(i);
// 필요한 데이터 값 추출하기
data1 = item.getElementsByTagName("rdnmadr").item(0); // 주소
data2 = item.getElementsByTagName("entrprsNm").item(0); // 회사명
data3 = item.getElementsByTagName("rprsntvNm").item(0); // 회사대표
data4 = item.getElementsByTagName("mainGoods").item(0); // 주력상품
data5 = item.getElementsByTagName("latitude").item(0); // 위도
data6 = item.getElementsByTagName("logitude").item(0); // 경도
String strData1 = data1.getChildNodes().item(0).getNodeValue();
String strData2 = data2.getChildNodes().item(0).getNodeValue();
String strData3 = data3.getChildNodes().item(0).getNodeValue();
String strData4 = data4.getChildNodes().item(0).getNodeValue();
String strData5 = data5.getChildNodes().item(0).getNodeValue();
String strData6 = data6.getChildNodes().item(0).getNodeValue();
System.out.println( strData1 + " " + strData2 + " " + strData3 + " " + strData4 + " " + strData5 + " " + strData6 );
vo.setRdnmadr(strData1);
vo.setEntrprsNm(strData2);
vo.setRprsntvNm(strData3);
vo.setMainGoods(strData4);
vo.setLatitude(strData5);
vo.setLogitude(strData6);
service.insert(vo);
}
} catch (Exception e) {
e.printStackTrace();
}
return "/index.html";
}
}
API를 XML 파일 형식으로 불러와 사용하기 위한 코드이다.
어려운것은 크게 경로설정할때의 HTTP의 S를 빼줘야 한다는것이다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="/include/top.jsp" %>
<section>
<br>
<div align="center">
<h2>경상남도 고용우수기업</h2>
<table border=1 width="900">
<tr height=40 >
<td align=center width=100><b>순번</b></td>
<td align=center width=450><b>회사명</b></td>
<td align=center width=210><b>회사대표</b></td>
<td align=center width=450><b>주력상품</b></td>
<td align=center width=450><b>주소</b></td>
<td align=center width=200><b>위도</b></td>
<td align=center width=200><b>경도</b></td>
</tr>
<c:forEach items="${li}" var="m" varStatus="status">
<tr align="center">
<td>${status.count}</td>
<td>
<c:url value="/company/companyEdit.do" var="url">
<c:param name="entrprsNm" value="${m.entrprsNm}"/>
</c:url>
<a href="${url}">${m.entrprsNm}</a>
<input type=hidden name=latitude value="${m1.latitude}">
<input type=hidden name=logitude value="${m2.logitude}">
</td>
<td>${m.rprsntvNm}</td>
<td>${m.mainGoods}</td>
<td>${m.rdnmadr}</td>
<td>${m.latitude}</td>
<td>${m.logitude}</td>
</tr>
</c:forEach>
</table>
</div>
</section>
<%@ include file="/include/footer.jsp"%>
리스트 형식의 UI를 만들때 중요한 점은, 파라미터 값을 정상적으로 넘기는 것이다. 파라미터 값에 특수문자가 있을때나 한글로된 파라미터 값을 넘길때에는
<c>
태그를 사용하여 전달 할 수 있다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="/include/top.jsp" %>
<section>
<br>
<div align="center">
<h2>경상남도 고용우수기업</h2>
<table border=1 width="900">
<tr height=40 >
<td align=center width=100><b>순번</b></td>
<td align=center width=450><b>회사명</b></td>
<td align=center width=210><b>회사대표</b></td>
<td align=center width=450><b>주력상품</b></td>
<td align=center width=450><b>주소</b></td>
<td align=center width=200><b>위도</b></td>
<td align=center width=200><b>경도</b></td>
</tr>
<c:forEach items="${li}" var="m" varStatus="status">
<tr align="center">
<td>${status.count}</td>
<td>
<c:url value="/company/companyEdit.do" var="url">
<c:param name="entrprsNm" value="${m.entrprsNm}"/>
</c:url>
<a href="${url}">${m.entrprsNm}</a>
<input type=hidden name=latitude value="${m1.latitude}">
<input type=hidden name=logitude value="${m2.logitude}">
</td>
<td>${m.rprsntvNm}</td>
<td>${m.mainGoods}</td>
<td>${m.rdnmadr}</td>
<td>${m.latitude}</td>
<td>${m.logitude}</td>
</tr>
</c:forEach>
</table>
</div>
</section>
<%@ include file="/include/footer.jsp"%>
카카오맵의 스크립트를 호출하여 지도 화면을 구현했다.
찾는것에 비해 적용하는 부분은 빠르게 진행되었고 어렵지는 않았다.