- package 하나 더 만들어주기 (handler)
Spring Starter Project | oBootMybatis01 |
folder | resource/static |
html | index |
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>회원 관리</h1>
<a href="/listEmpStart">회원 목록(기본 CRUD)</a><p>
<a href="/listEmpDept">직원부서조회(Join/Mail전송)</a><p>
<a href="/writeDeptIn">PL/SQL(부서입력) </a><p>
<a href="/writeDeptCursor">PL/SQL(부서조회 Cursor) </a><p>
<a href="/memberJpa/new">JPA Member(CRUD) </a><p>
<a href="/interCeptorForm">interCeptor(가로채기) </a><p>
<a href="/upLoadFormStart">UpLoad(이미지 올리기) </a><p>
<a href="/ajaxForm">Ajax Form Test </a><p>
<a href="/transactionInsertUpdate">Transaction Test</a><p>
<a href="/chat">Chating </a><p>
</body>
</html>
Console |
Spring Starter Project | oBootMybatis01 |
folder | src/main/webapp/WEB-INF/views |
JSP | ajaxForm.jsp |
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>다양한 Ajax Test</h1>
<a href="/helloText">helloText</a><p>
<a href="/sample/sendVO2?deptno=123">sample/sendVO2(객체)</a><p>
<a href="/sendVO3">sendVO3</a><p>
<a href="/getDeptName?deptno=10">getDeptName(EmpController)</a><p>
<a href="/listEmpAjaxForm">listEmpAjaxForm(aJax JSP 연동)</a><p>
<a href="/listEmpAjaxForm2">listEmpAjaxForm2(aJax JSP 객체리스트 Get)</a><p>
<a href="/listEmpAjaxForm3">listEmpAjaxForm3(aJax List를 Controller로 전송)</a><p>
</body>
</html>
Console |
Spring Starter Project | oBootMybatis01 |
folder | src/main/webapp/WEB-INF/views |
JSP | listEmpAjaxForm2.jsp |
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">
function getListDept() {
alert("getListDept Run....");
var str = "";
var str2 = "";
$.ajax(
{
url:"/sendVO3",
dataType:'json',
success:function(deptList) {
var jsonStr = JSON.stringify(deptList);
alert("jsonStr->" +jsonStr);
$('#dept_list_str').append(jsonStr);
str += "<select name='dept'>";
$(deptList).each(
function(){
str2 = "<option value='"+this.deptno +"'> "+this.dname+"</option>";
str += str2;
}
)
str += "</select><p>"
alert("combobox str-> "+str);
$('#dept_list_combobox').append(str);
}
}
);
}
function getEmpnoDelete(pIndex) {
alert("getDeptDelete Run....");
// url -> empnoDelete(EmpRestController)
// parm -> empno : selEmpno
// empno만 넘겨주면 되는데, parameter 2개 넘겨주는 거 연습하기 위해서 ename까지
// 성공하면 -> Delete Tag
var selEmpno = $("#empno"+pIndex).val();
var selEname = $("#ename"+pIndex).val();
/* $.ajax(
{
url:"/empnoDelete",
data:{empno : selEmpno,
ename : selEname},
dataType:'text',
success:function(data){
alert(".ajax getDeptDelete data-> "+data);
if (data =='1') {
//성공하면 아래라인 수행 --> Delete Tag
$('#emp'+pIndex).remove();
}
}
}
);
*/
//결과를 객체로 받음
$.ajax(
{
url:"/empnoDelete03",
//위: 물리적 삭제
//아래: 화면 단(view) 삭제
data:{empno : selEmpno,
ename : selEname},
dataType:'json',
success:function(response){
alert(".ajax getDeptDelete response.delStatus-> "+response.delStatus);
if (response.delStatus =='1') {
//성공하면 아래라인 수행 --> Delete Tag
$('#emp'+pIndex).remove();
}
}
}
);
}
</script>
</head>
<body>
<h2>회원 정보</h2>
<table>
<tr>
<th>번호</th>
<th>사번</th>
<th>이름</th>
<th>업무</th>
<th>부서</th>
</tr>
<c:forEach var="emp" items="${listEmp }" varStatus="status">
<tr id="emp${status.index }">
<td>emp${status.index }</td>
<td>
<input type="hidden" id="deptno${status.index }" value="${emp.deptno }">
<input type="text" id="empno${status.index }" value="${emp.empno }">
</td>
<td>
<input type="text" id="ename${status.index }" value="${emp.ename }">
</td>
<td>${emp.job }</td>
<td>${emp.deptno }
<input type="button" id="btn_idCheck2" value="사원 Row Delete"
onclick="getEmpnoDelete(${status.index})">
</td>
</tr>
</c:forEach>
</table>
RestController LISTVO3: <input type="button"
id="btn_Dept3"
value="부서명 LIST"
onclick="getListDept()"><p>
dept_list_str: <div id="dept_list_str"></div><p>
dept_list_combobox:
<div id="dept_list_combobox"></div>
<h1>The End </h1>
</body>
</html>
Console |
- status 써주는 이유
multi Row를 가져왔을 때, 하나하나를 ajax처리를 해줄 수 없다.
status 를 주면, 전체 row에 대한 index 값이 주어진다.
- ajax를 이용해서 list combobox만들기 (getListDept ajax 만들어주기)
(1) 항상 하나씩 입력하면서 작성해주기 - 작동하는지 확인해보기 ajax가 !! (작동 O)
(2)
(3)
(4) each : 향상형 for문처럼 계속 돌아간다.
- 삭제 ajax 해보기 (방법1 : text 방식)
@RequestBody @Valid 안해줘도 되는 이유
(1) 위에 2개는 json을 stringify로 보내주었을 때 쓰는 것 (json으로 보내주기는 하지만 string으로 전달한다.)
객체를 string으로 전달했을 때 필요한 annotation이다.
(2) 여기서는 직접 값을 넘겨주어씩 때문에 Emp emp 만 정의해주면 된다. 객체로 직접 넘겨주었다.
- 삭제 로직 (방법2: 객체로 받아서 Map으로 처리하는 (dto로 처리할 수도 있음))
여기서는 객체로 받아주기 때문에 String으로 바꿔줄 필요가 없다.......
Spring Starter Project | oBootMybatis01 |
folder | src/main/webapp/WEB-INF/views |
JSP | listEmpAjaxForm3.jsp |
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ include file="header.jsp"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">
// listEmpAjaxForm3.jsp 에서 수정 전 작업 sample
function getEmpListUpdateTest() {
alert("getEmpListUpdateTest Run....")
// Group 번호 가져오기
var arr = new Array();
var item;
<c:forEach items="${listEmp}" var="item">
arr.push({
empno:"${item.empno}",
ename:"${item.ename}",
deptno:"${item.deptno}"
});
</c:forEach>
for (var i=0 ; i<arr.length;) {
alert("arr.empno-> "+i+" : "+arr[i].empno + ", arr.ename-> "+i+" : "+arr[i].ename);
i++;
if (i > 2) return;
}
}
// listEmpAjaxForm3.jsp 에서 수정 후 작업 sample
//JavaScript에서 empList를 수정한 Data를 JSON 데이터로 전환 empController로 보내기 예제
function getEmpListUpdate() {
alert("getEmpListUpdate Run....")
let empList = [];
const inputs = document.querySelectorAll('input[name="empno"], input[name="ename"], input[name="deptno"]');
for (let i=0; i< inputs.length; i += 3) {
const empno = inputs[i+1].value;
const ename = inputs[i+2].value;
const deptno = inputs[i+3].value;
//불러온 값들을 JSON 객체 형태로 만든다.
const empItem = {
"empno":empno,
"ename":ename,
"deptno":deptno
};
//alert("ename-> "+ename);
// JSON 객체를 배열 안에 넣어둔다.
empList.push(empItem);
if(i>5) break;
}
//수정 후의 list
alert("JSON.stringify(empList)-> "+JSON.stringify(empList));
if (empList.length > 0) {
$.ajax({
url: 'empListUpdate',
contentType: 'application/json',
data: JSON.stringify(empList), //JSON 객체를 불러와서 stringify() 함수 안에 배열
method: 'POST',
// 위 까지가 서버프로
//아래가 return
dataType: 'json',
success: function(response) {
console.log(response.updateResult);
}
});
alert("Ajax empListUpdate 수행...");
}
}
</script>
</head>
<body>
<h2>회원 정보3</h2>
<table id="empList">
<tr>
<th>번호</th>
<th>사번</th>
<th>이름</th>
<th>업무</th>
<th>부서</th>
</tr>
<c:forEach var="emp" items="${listEmp}" varStatus="status">
<tr id="empListRow"><td>emp${status.index}</td>
<td>
<input type="hidden" class="deptno" id="deptno" name="deptno" value="${emp.deptno }">
<input type="text" class="empno" id="empno" name="empno" value="${emp.empno }">${emp.empno }
</td>
<td>
<input type="text" class="ename" id="ename" name="ename" value="${emp.ename }">${emp.ename }
</td>
<td>${emp.job }</td>
<td>${emp.deptno }</td>
</tr>
</c:forEach>
</table><p>
RestController LISTVO3: <input type="button" id="btn_Dept3"
value="empLISTTest 전송 "
onclick="getEmpListUpdateTest()"><p>
RestController LISTVO3: <input type="button" id="btn_Dept3"
value="empLIST 전송 "
onclick="getEmpListUpdate()"><p>
<h1>The End </h1>
</body>
</html>
Console |
- getEmpListUpdateTest 로직
- getEmpListUpdate ajax 로직 먼저 확인되는지 본다. (qusrudehls rkqtdl)
(1)
(2)
(3)
Spring Starter Project | oBootMybatis01 |
package | com.oracle.oBootMybatis01.controller |
class | EmpController |
package com.oracle.oBootMybatis01.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.oracle.oBootMybatis01.model.Dept;
import com.oracle.oBootMybatis01.model.DeptVO;
import com.oracle.oBootMybatis01.model.Emp;
import com.oracle.oBootMybatis01.model.EmpDept;
import com.oracle.oBootMybatis01.model.Member1;
import com.oracle.oBootMybatis01.service.EmpService;
import com.oracle.oBootMybatis01.service.Paging;
import com.oracle.wls.shaded.org.apache.regexp.RE;
import com.oracle.wls.shaded.org.apache.xalan.xsltc.compiler.sym;
import jakarta.mail.internet.MimeMessage;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Controller
@RequiredArgsConstructor
//logger 쓰는 것!!!
@Slf4j
public class EmpController {
private final EmpService es;
private final JavaMailSender mailSender;
@RequestMapping(value = "listEmpStart")
public String listEmpStart(Emp emp, Model model) {
System.out.println("EmpController listEmpStart Start...");
//21명 -> 3page가 있어야 한다.
int totalEmp = es.totalEmp();
String currentPage = "1";
//Paging 작업
Paging page = new Paging(totalEmp, currentPage);
//Parameter emp --> Page만 추가 Setting
emp.setStart(page.getStart()); //시작 시 1
emp.setEnd(page.getEnd()); //시작 시 10
List<Emp> listEmp = es.listEmp(emp);
System.out.println("EmpController list listEmp.size()-> "+listEmp.size());
model.addAttribute("totalEmp", totalEmp);
model.addAttribute("listEmp",listEmp);
model.addAttribute("page",page);
System.out.println("EmpController listEmpStart End...");
// ViewResolver에 의해 list.jsp로 이동
return "list";
}
@RequestMapping(value = "listEmp")
public String listEmp(Emp emp, Model model) {
System.out.println("EmpController listEmp Start...");
//21명 -> 3page가 있어야 한다.
int totalEmp = es.totalEmp();
//Paging 작업
Paging page = new Paging(totalEmp, emp.getCurrentPage());
//Parameter emp --> Page만 추가 Setting
emp.setStart(page.getStart()); //시작 시 1
emp.setEnd(page.getEnd()); //시작 시 10
List<Emp> listEmp = es.listEmp(emp);
System.out.println("EmpController list listEmp.size()-> "+listEmp.size());
model.addAttribute("totalEmp", totalEmp);
model.addAttribute("listEmp",listEmp);
model.addAttribute("page",page);
System.out.println("EmpController listEmp End...");
// ViewResolver에 의해 list.jsp로 이동
return "list";
}
@GetMapping(value = "detailEmp")
public String detailEmp(Emp emp1, Model model) {
System.out.println("EmpController Start detailEmp...");
// 1. EmpService안에 detailEmp method 선언
// 1) parameter : empno
// 2) Return Emp
//
// 2. EmpDao detailEmp method 선언
//// mapper ID , Parameter
// emp = session.selectOne("tkEmpSelOne", empno);
// System.out.println("emp-> "+emp1);
Emp emp = es.detailEmp(emp1.getEmpno());
System.out.println("emp-> "+emp1);
model.addAttribute("emp", emp);
System.out.println("EmpController End detailEmp...");
return "detailEmp";
}
@GetMapping(value = "updateFormEmp")
public String updateFormEmp(Emp emp1, Model model) {
// emp1에 empno가 들어가진다.
System.out.println("EmpController Start updateFormEmp...");
Emp emp = es.detailEmp(emp1.getEmpno());
System.out.println("EmpController updateFormEmp emp-> "+emp);
// 문제
// 1. DTO String hiredate
// 2.View : 단순조회 OK ,JSP에서 input type="date" 문제 발생
// 3.해결책 : 년월일만 짤라 넣어 주어야 함
String hiredate="";
if(emp.getHiredate() != null) {
hiredate = emp.getHiredate().substring(0,10);
emp.setHiredate(hiredate);
}
System.out.println("hiredate-> "+hiredate);
model.addAttribute("emp", emp);
System.out.println("EmpController End updateFormEmp...");
return "updateFormEmp";
}
@PostMapping(value = "updateEmp")
public String updateEmp(Emp emp, Model model) {
log.info("EmpController updateEmp Start....");
int updateCount = es.updateEmp(emp);
// 1. EmpService안에 updateEmp method 선언
// 1) parameter : Emp
// 2) Return updateCount (int)
//
// 2. EmpDao updateEmp method 선언
// mapper ID , Parameter
// updateCount = session.update("tkEmpUpdate", emp);
System.out.println("EmpController es.updateEmp updateCount--> "+updateCount);
model.addAttribute("uptCnt",updateCount); //Test Controller 간 Data 전달
model.addAttribute("kk3","Message Test"); //Test Controller 간 Data 전달
System.out.println("EmpController addAttribute After....");
log.info("EmpController updateEmp End....");
//redirect: 같은 controller 안에 있는 listEmp로 돌아간다는 의미!!!!
return "forward:listEmp";
// return "redirect:listEmp";
}
@RequestMapping(value = "writeFormEmp")
public String writeFormEmp(Model model) {
System.out.println("EmpController writeFormEmp Start...");
//관리자 사번만 Get
List<Emp> empList = es.listManager();
System.out.println("EmpController writeForm empList.size()-> "+ empList.size());
model.addAttribute("empMngList", empList); //emp Manager List
// 1. service -> listManager
// 2. Dao -> listManager
// 3. mapper -> tkSelectManager
//부서(코드, 부서명)
List<Dept> deptList = es.deptSelect();
model.addAttribute("deptList", deptList); //dept
System.out.println("EmpController writeForm deptList.size()-> "+deptList.size());
System.out.println("EmpController writeFormEmp End...");
return "writeFormEmp";
}
@PostMapping(value = "writeEmp")
public String writeEmp(Emp emp, Model model) {
System.out.println("EmpController start writeEmp...");
// Service, Dao , Mapper명[insertEmp] 까지 -> insert
int insertResult = es.insertEmp(emp);
if (insertResult > 0) return "redirect:listEmp";
else {
model.addAttribute("msg", "입력 실패! 확인해보세요");
return "forward:writeFormEmp";
}
}
@GetMapping(value = "confirm")
public String confirm(Emp emp1, Model model) {
Emp emp = es.detailEmp(emp1.getEmpno());
model.addAttribute("empno", emp1.getEmpno());
if (emp != null) {
System.out.println("EmpController confirm 중복된 사번..");
model.addAttribute("msg", "중복된 사번입니다.");
// return "forward:writeFormEmp";
} else {
System.out.println("EmpController confirm 사용 가능한 사번..");
model.addAttribute("msg", "사용 가능한 사번입니다.");
// return "forward:writeFormEmp";
}
return "forward:writeFormEmp";
}
@RequestMapping(value = "deleteEmp")
public String deleteEmp(Emp emp, Model model) {
System.out.println("EmpController Start deleteEmp...");
// Controller --> deleteEmp 1.parameter : empno
// name -> Service, dao , mapper
// return -> listEmp
int result = es.deleteEmp(emp.getEmpno());
return "redirect:listEmp";
}
@RequestMapping(value = "writeFormEmp3")
public String writeFormEmp3(Model model) {
System.out.println("EmpController writeFormEmp3 Start...");
//관리자 사번만 Get
List<Emp> empList = es.listManager();
System.out.println("EmpController writeForm empList.size()-> "+ empList.size());
model.addAttribute("empMngList", empList); //emp Manager List
// 1. service -> listManager
// 2. Dao -> listManager
// 3. mapper -> tkSelectManager
//부서(코드, 부서명)
List<Dept> deptList = es.deptSelect();
model.addAttribute("deptList", deptList); //dept
System.out.println("EmpController writeForm deptList.size()-> "+deptList.size());
System.out.println("EmpController writeFormEmp3 End...");
return "writeFormEmp3";
}
// Validation시 참조
@PostMapping(value = "writeEmp3")
public String writeEmp3(@ModelAttribute("emp") @Valid Emp emp
, BindingResult result
, Model model) {
System.out.println("EmpController start writeEmp3...");
// Validation 오류시 Result
if (result.hasErrors()) {
System.out.println("EmpController writeEmp3 hasErrors...");
model.addAttribute("msg", "BindingResult 입력 실패 확인해보세요");
return "forward:writeFormEmp3";
}
// Service, Dao , Mapper명[insertEmp] 까지 -> insert
int insertResult = es.insertEmp(emp);
if (insertResult > 0) return "redirect:listEmp";
else {
model.addAttribute("msg", "입력 실패! 확인해보세요");
return "forward:writeFormEmp3";
}
}
@RequestMapping(value = "listSearch3")
public String listSearch3(Emp emp, Model model) {
System.out.println("EmpController listSearch3 Start...");
System.out.println("EmpController listSearch3 emp-> "+emp);
//Emp 전체 count
int totalEmp = es.condTotalEmp(emp);
System.out.println("EmpController listSearch3 totalEmp-> "+totalEmp);
//Paging 작업
Paging page = new Paging(totalEmp, emp.getCurrentPage());
//Parameter emp --> Page 만 추가 Setting
emp.setStart(page.getStart()); //시작 시 1
emp.setEnd(page.getEnd()); //시작 시 10
System.out.println("EmpController listSearch3 page-> "+page);
List<Emp> listSearchEmp = es.listSearchEmp(emp);
System.out.println("EmpController listSearch3 listSearchEmp.size()-> "+listSearchEmp.size());
model.addAttribute("totalEmp", totalEmp);
//왜 listEmp로 보내주냐면, list.jsp로 가보면 listEmp로 되어있기 때문에 (재활용 위해서)
model.addAttribute("listEmp", listSearchEmp);
model.addAttribute("page", page);
return "list";
}
@GetMapping(value = "listEmpDept")
public String listEmpDept(Model model) {
System.out.println("EmpController listEmpDept start...");
// Service ,DAO -> listEmpDept
// Mapper만 ->EmpDept.xml(tkListEmpDept)
List<EmpDept> listEmpDept = es.listEmpDept();
model.addAttribute("listEmpDept", listEmpDept);
System.out.println("EmpController listEmpDept End...");
return "listEmpDept";
}
@RequestMapping(value = "mailTransport")
public String mailTransport(HttpServletRequest request, Model model) {
System.out.println("mailSending...");
String tomail = "kate__@naver.com"; //받는 사람 이메일
System.out.println(tomail);
String setfrom = "kateshs0521@gmail.com";
String title = "mailTransport 입니다"; //제목
try {
// MIME(영어: Multipurpose Internet Mail Extensions)는 전자 우편을 위한 인터넷 표준 포맷
MimeMessage message = mailSender.createMimeMessage();
//값을 세팅하기 위해서 Helper를 이용해야 한다.
MimeMessageHelper messageHelper = new MimeMessageHelper(message, true,"UTF-8");
messageHelper.setFrom(setfrom); //보내는 사람 생략하거나 하면 정삭작동을 안함
messageHelper.setTo(tomail); //받는 사람 이메일
messageHelper.setSubject(title); //메일 제목은 생략이 가능하다
String tempPassword = (int) (Math.random() * 999999) +1 +"";
messageHelper.setText("임시 비밀번호입니다 : "+tempPassword); //메일 내용
System.out.println("임시 비밀번호입니다 : "+tempPassword);
mailSender.send(message);
model.addAttribute("check", 1); //정상 전달
//DB Logic
} catch (Exception e) {
System.out.println("mailTransport e.getMessage()-> "+e.getMessage());
model.addAttribute("check", 2); //메일 전달 실패
}
return "mailResult";
}
// Procedure Test 입력화면
@RequestMapping(value = "writeDeptIn")
public String writeDeptIn(Model model) {
System.out.println("writeDeptIn Start.,..");
System.out.println("writeDeptIn End....");
return "writeDept3";
}
//Procedure 통한 Dept 입력 후 VO 전달
@PostMapping(value = "writeDept")
public String writeDept(DeptVO deptVO, Model model) {
es.insertDept(deptVO);
if (deptVO == null) {
System.out.println("deptVO NULL");
} else {
System.out.println("deptVO.getOdeptno()"+deptVO.getOdeptno());
System.out.println("deptVO.getOdname()"+deptVO.getOdname());
System.out.println("deptVO.getOloc()"+deptVO.getOloc());
model.addAttribute("msg", "정상 입력 되었습니다. ^^");
model.addAttribute("dept", deptVO);
}
return "writeDept3";
}
//Map 적용
@GetMapping(value = "writeDeptCursor")
public String writeDeptCursor(Model model) {
System.out.println("EmpController writeDeptCursor Start...");
// 부서범위 조회
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("sDeptno", 10);
map.put("eDeptno", 55);
//call by reference map
es.selListDept(map);
List<Dept> deptLists = (List<Dept>)map.get("dept");
for(Dept dept : deptLists) {
System.out.println("writeDeptCursor dept -> "+dept);
System.out.println("dept.getDname()-> "+dept.getDname());
System.out.println("dept.getLoc()-> "+dept.getLoc());
}
System.out.println("deptList Size-> "+deptLists.size());
model.addAttribute("deptList", deptLists);
return "writeDeptCursor";
}
//interCeptor 시작 화면
@RequestMapping(value = "interCeptorForm")
public String interCeptorForm() {
System.out.println("EmpController interCeptorForm start...");
return "interCeptorForm";
}
// 2. interCeptor Number2
@RequestMapping(value = "interCeptor")
public String interCeptor(Member1 member1, Model model) {
System.out.println("EmpController interCeptor Test Start");
System.out.println("EmpController interCeptor id-> "+member1.getId());
// 존재 : 1, 비존재 : 0
int memCnt = es.memCount(member1.getId());
System.out.println("EmpController interCeptor memCnt -> "+memCnt);
model.addAttribute("id", member1.getId());
model.addAttribute("memCnt", memCnt);
System.out.println("EmpController interCeptor Test End");
return "interCeptor"; //User 존재하면 User 이용 조회 Page
}
//SampleInterCeptor 내용을 받아 처리
@RequestMapping(value = "doMemberWrite")
public String doMemberWrite(Model model, HttpServletRequest request) {
String ID = (String) request.getSession().getAttribute("ID");
System.out.println("doMemberWrite 부터 하세요");
model.addAttribute("id", ID);
return "doMemberWrite";
}
//interCeptor 진행 Test
@RequestMapping(value = "doMemberList")
public String doMemberList(Model model, HttpServletRequest request) {
System.out.println("EmpController doMemberList Start...");
String ID = (String) request.getSession().getAttribute("ID");
System.out.println("doMemberList Test Start ID -> "+ID);
Member1 member1 = null;
// 로그인 한 사람만 보여주고 싶은 페이지일 때!!
// Member1 List Get Service
// Service, DAO --> listMem
// Mapper --> listMember1
// Member1 모든 Row Get
List<Member1> listMem = es.listMem(member1);
model.addAttribute("ID", ID);
model.addAttribute("listMem", listMem);
System.out.println("EmpController doMemberList End...");
return "doMemberList"; //User 존재하면 User 이용 조회 Page
}
// ajaxForm Test 입력하면
@RequestMapping(value = "ajaxForm")
public String ajaxForm(Model model) {
System.out.println("ajaxForm Start...");
return "ajaxForm";
}
@ResponseBody
@RequestMapping(value = "getDeptName")
public String getDeptName(Dept dept, Model model) {
System.out.println("EmpController getDeptName Start...");
System.out.println("deptno-> "+dept.getDeptno());
String deptName = es.deptName(dept.getDeptno());
System.out.println("deptName-> "+deptName);
//mapper --> EmpDept(tkDeptName)
System.out.println("EmpController getDeptName End...");
return deptName;
}
//Ajax List Test (ajax를 수행하기 위한 준비 화면 -> @ResponseBody 안붙혀도 된다.)
@RequestMapping(value = "listEmpAjaxForm")
public String listEmpAjaxForm(Model model) {
Emp emp = new Emp();
System.out.println("EmpController listEmpAjaxForm Start...");
//Parameter emp --> Page만 추가 Setting
emp.setStart(1); //시작 시 1
emp.setEnd(10); //시작 시 10
List<Emp> listEmp = es.listEmp(emp);
System.out.println("EmpController listEmpAjaxForm listEmp.size()-> "+listEmp.size());
model.addAttribute("result", "kkk");
model.addAttribute("listEmp", listEmp);
return "listEmpAjaxForm";
}
@ResponseBody
@RequestMapping(value = "empSerializeWrite")
// string으로 받아온 것을 json형태로 날라와도 @RequestBody가 있으면 알아서 key, value로 넘어가진다.
public Map<String, Object> empSerializeWrite(@RequestBody @Valid Emp emp) {
//map 방식으로 주는 이유: 상대방이 받을 때 string 방식으로 받는 것 보다 객체 방식으로 받는게 더 편해서
// public Map<String, Object> empSerializeWrite(@Valid Emp emp) {
System.out.println("EmpController empSerializeWrite Start...");
System.out.println("EmpController empSerializeWrite emp-> "+emp);
int writeResult = 1;
// int writeResult = kkk.writeEmp(emp);
// writeResult가 1이나 0이 왔다는 전제 하에 to string으로
// String followingProStr = Integer.toString(followingPro);
Map<String, Object> resultMap = new HashMap<>();
System.out.println("EmpController empSerializeWrite writeResult-> "+writeResult);
//객체로 만들어준 것 (하나 이상의 값을 보내줄 수 있다)
//map방식이면, 요구사항을 받아서 바로 해결할 수 있다.
resultMap.put("writeResult", writeResult);
// resultMap.put("anyResult", "anyR");
return resultMap;
}
@RequestMapping(value = "listEmpAjaxForm2")
public String listEmpAjaxForm2(Model model) {
System.out.println("EmpController listEmpAjaxForm2 Start...");
Emp emp = new Emp();
// Parameter emp --> Page만 추가 setting
emp.setStart(1); //시작 시 1
emp.setEnd(15); //시작 시 15
List<Emp> listEmp = es.listEmp(emp);
System.out.println("EmpController listEmpAjaxForm2 listEmp.size()"+ listEmp.size());
model.addAttribute("listEmp", listEmp);
return "listEmpAjaxForm2";
}
@RequestMapping(value = "listEmpAjaxForm3")
public String listEmpAjaxForm3(Model model) {
System.out.println("EmpController listEmpAjaxForm3 Start...");
Emp emp = new Emp();
// Parameter emp --> Page만 추가 setting
emp.setStart(1); //시작 시 1
emp.setEnd(15); //시작 시 15
List<Emp> listEmp = es.listEmp(emp);
System.out.println("EmpController listEmpAjaxForm3 listEmp.size()"+ listEmp.size());
model.addAttribute("listEmp", listEmp);
return "listEmpAjaxForm3";
}
@ResponseBody
@RequestMapping(value = "empListUpdate")
public Map<String, Object> empListUpdate(@RequestBody @Valid List<Emp> listEmp) {
System.out.println("EmpController empListUpdate Start...");
int updateResult = 1;
for (Emp emp : listEmp) {
System.out.println("EmpController empListUpdate emp-> "+emp);
//int writeResult = kkk.listUpdateEmp(emp);
}
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("updateResult", updateResult);
return resultMap;
}
@ResponseBody
@RequestMapping(value = "transactionInsertUpdate")
public String transactionInsertUpdate(Emp emp, Model model) {
System.out.println("EmpController transactionInsertUpdate Start....");
//memberInsert 성공과 실패
int returnMember = es.transactionInsertUpdate();
System.out.println("EmpController transactionInsertUpdate returnMember=> "+returnMember);
String returnMemberString = String.valueOf(returnMember);
return returnMemberString;
}
}
Console |
- controller에서 view로 보내지는 것은 많이 해보았고 반대 경우 logic
Spring Starter Project | oBootMybatis01 |
package | com.oracle.oBootMybatis01.controller |
class | EmpRestController |
package com.oracle.oBootMybatis01.controller;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.oracle.oBootMybatis01.model.Dept;
import com.oracle.oBootMybatis01.model.Emp;
import com.oracle.oBootMybatis01.model.SampleVO;
import com.oracle.oBootMybatis01.service.EmpService;
import lombok.RequiredArgsConstructor;
//@Controller + @ResponseBody
@RestController
@RequiredArgsConstructor
public class EmpRestController {
private final EmpService es;
@RequestMapping("/helloText")
public String helloText() {
System.out.println("EmpRestController helloText Start...");
String hello = "안녕";
// StringConverter
return hello;
}
// http://jsonviewer.stack.hu/
@RequestMapping(value = "/sample/sendVO2")
public SampleVO sendVO2(Dept dept) {
System.out.println("EmpRestController SampleVO Start....");
System.out.println("@RestController SampleVO dept.getDeptno()-> "+dept.getDeptno());
SampleVO vo = new SampleVO();
vo.setFirstName("길동");
vo.setLastName("홍");
vo.setMno(dept.getDeptno());
System.out.println("EmpRestController SampleVO End....");
//객체가 return
return vo;
}
@RequestMapping("/sendVO3")
public List<Dept> sendVO3() {
System.out.println("EmpRestController @RestController sendVO3 START..");
List<Dept> deptList = es.deptSelect();
return deptList;
}
//결과 text로 보내지는 것
@RequestMapping("/empnoDelete")
public String empnoDelete(Emp emp) {
System.out.println("EmpRestController @RestController empnoDelete START..");
System.out.println("EmpRestController @RestController empnoDelete emp-> "+emp);
int delStatus = es.deleteEmp(emp.getEmpno());
String delStatusStr = Integer.toString(delStatus);
return delStatusStr;
}
//결과 --> 객체로 전달 (객체는 DTO로 or Map으로!)
@RequestMapping("/empnoDelete03")
public Map<String, Object> empnoDelete03(Emp emp) {
System.out.println("EmpRestController @RestController empnoDelete03 START..");
System.out.println("EmpRestController @RestController empnoDelete03 emp-> "+emp);
int delStatus = es.deleteEmp(emp.getEmpno());
// String delStatusStr = Integer.toString(delStatus);
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("delStatus", delStatus);
return resultMap;
}
}
Console |
- delete 로직 (service 부터는 만들어져 있는 logic 사용하면 된다.)
여기서 return 값을 string 으로 형변환 해주여야 한다. -> int는 인식을 못한다.
(HttpMessageConverter는 string 형태와 json(객체)형태만 인식하기 때문에)
Spring Starter Project | oBootMybatis01 |
package | com.oracle.oBootMybatis01.service |
interface | EmpService |
package com.oracle.oBootMybatis01.service;
import java.util.HashMap;
import java.util.List;
import com.oracle.oBootMybatis01.model.Dept;
import com.oracle.oBootMybatis01.model.DeptVO;
import com.oracle.oBootMybatis01.model.Emp;
import com.oracle.oBootMybatis01.model.EmpDept;
import com.oracle.oBootMybatis01.model.Member1;
public interface EmpService {
int totalEmp();
List<Emp> listEmp(Emp emp);
Emp detailEmp(int empno);
int updateEmp(Emp emp);
List<Emp> listManager();
List<Dept> deptSelect();
int insertEmp(Emp emp);
int deleteEmp(int empno);
int condTotalEmp(Emp emp);
List<Emp> listSearchEmp(Emp emp);
List<EmpDept> listEmpDept();
void insertDept(DeptVO deptVO);
void selListDept(HashMap<String, Object> map);
int memCount(String id);
List<Member1> listMem(Member1 member1);
String deptName(int deptno);
int transactionInsertUpdate();
}
Console |
Spring Starter Project | oBootMybatis01 |
package | com.oracle.oBootMybatis01.service |
class | EmpServiceImpl |
package com.oracle.oBootMybatis01.service;
import java.util.HashMap;
import java.util.List;
import org.springframework.stereotype.Service;
import com.oracle.oBootMybatis01.dao.DeptDao;
import com.oracle.oBootMybatis01.dao.EmpDao;
import com.oracle.oBootMybatis01.dao.Member1Dao;
import com.oracle.oBootMybatis01.model.Dept;
import com.oracle.oBootMybatis01.model.DeptVO;
import com.oracle.oBootMybatis01.model.Emp;
import com.oracle.oBootMybatis01.model.EmpDept;
import com.oracle.oBootMybatis01.model.Member1;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class EmpServiceImpl implements EmpService {
//interface가 각각 하나라면, 여러개의 dao를 만들 수 있다.
//if EmpDao interface에 JPA dao가 하나 더 연결(implement)되어 있으면, 기존의 myBatis는 annotation 없애주어야 한다.
private final EmpDao ed;
private final DeptDao dd;
private final Member1Dao md;
@Override
public int totalEmp() {
System.out.println("EmpServiceImpl totalEmp start...");
int totEmpCnt = ed.totalEmp();
System.out.println("EmpServiceImpl totalEmp totEmpCnt->"+totEmpCnt);
return totEmpCnt;
}
@Override
public List<Emp> listEmp(Emp emp) {
List<Emp> empList = null;
System.out.println("EmpServiceImpl listManager Start...");
empList = ed.listEmp(emp);
System.out.println("EmpServiceImpl listEmp empList.size()-> "+empList.size());
return empList;
}
@Override
public Emp detailEmp(int empno) {
System.out.println("EmpServiceImpl detailEmp start...");
Emp emp = ed.detailEmp(empno);
System.out.println("EmpServiceImpl detailEmp emp-> "+emp);
// 1. EmpService안에 detailEmp method 선언
// 1) parameter : empno
// 2) Return Emp
return emp;
}
@Override
public int updateEmp(Emp emp) {
// 1. EmpService안에 updateEmp method 선언
// 1) parameter : Emp
// 2) Return updateCount (int)
System.out.println("EmpServiceImpl updateEmp Start...");
int updateCount = 0;
updateCount = ed.updateEmp(emp);
System.out.println("EmpServiceImpl updateEmp updateCount-> "+updateCount);
System.out.println("EmpServiceImpl updateEmp ed.updateEmp After...");
return updateCount;
}
@Override
public List<Emp> listManager() {
System.out.println("EmpServiceImpl listManager Start...");
List<Emp> empList = null;
empList = ed.listManager();
System.out.println("EmpServiceImpl listManager empList.size()-> "+empList.size());
System.out.println("EmpServiceImpl listManager ed.listManager After...");
return empList;
}
@Override
public List<Dept> deptSelect() {
System.out.println("EmpServiceImpl deptSelect Start...");
List<Dept> deptList = null;
deptList = dd.deptSelect();
System.out.println("EmpServiceImpl deptSelect deptList.size()-> "+deptList.size());
System.out.println("EmpServiceImpl deptSelect dd.deptSelect After...");
//tkSelectDept
return deptList;
}
@Override
public int insertEmp(Emp emp) {
System.out.println("EmpServiceImpl insertEmp Start...");
int result = ed.insertEmp(emp);
System.out.println("EmpServiceImpl insertEmp result-> "+result);
System.out.println("EmpServiceImpl insertEmp ed.insertEmp After...");
return result;
}
@Override
public int deleteEmp(int empno) {
System.out.println("EmpServiceImpl deleteEmp Start...");
int result = ed.deleteEmp(empno);
System.out.println("EmpServiceImpl insertEmp result-> "+result);
System.out.println("EmpServiceImpl insertEmp ed.insertEmp After...");
return result;
}
@Override
public int condTotalEmp(Emp emp) {
System.out.println("EmpServiceImpl condTotalEmp Start...");
int totEmpCnt = ed.condTotalEmp(emp);
System.out.println("EmpServiceImpl condTotalEmp totEmpCnt -> "+totEmpCnt);
return totEmpCnt;
}
@Override
public List<Emp> listSearchEmp(Emp emp) {
System.out.println("EmpServiceImpl listSearchEmp Start...");
List<Emp> empList = null;
// 1. DAO ed.empSearchList3(emp);
// 2. Mapper selectList("tkEmpSearchList3", emp);
empList = ed.empSearchList3(emp);
System.out.println("EmpServiceImpl listSearchEmp empList -> "+empList);
return empList;
}
@Override
public List<EmpDept> listEmpDept() {
System.out.println("EmpServiceImpl listEmpDept Start...");
List<EmpDept> listEmpDept = null;
listEmpDept = ed.listEmpDept();
System.out.println("EmpServiceImpl listEmpDept listEmpDept.size() -> "+listEmpDept.size());
return listEmpDept;
}
@Override
public void insertDept(DeptVO deptVO) {
System.out.println("EmpServiceImpl insertDept Start...");
dd.insertDept(deptVO);
}
@Override
public void selListDept(HashMap<String, Object> map) {
System.out.println("EmpServiceImpl selListDept Start...");
dd.selListDept(map);
}
@Override
public int memCount(String id) {
System.out.println("EmpServiceImpl memCount Start...");
System.out.println("EmpServiceImpl memCount id -->"+id);
return md.memCount(id);
}
@Override
public List<Member1> listMem(Member1 member1) {
List<Member1> listMem = null;
System.out.println("EmpServiceImpl listMem Start...");
System.out.println("EmpServiceImpl listMem.size() -->"+listMem.size());
listMem = md.listMem(member1);
return listMem;
}
@Override
public String deptName(int deptno) {
System.out.println("EmpServiceImpl deptName Start...");
String deptName = null;
deptName = ed.deptName(deptno);
System.out.println("EmpServiceImpl deptName -->"+deptName);
return deptName;
}
@Override
public int transactionInsertUpdate() {
System.out.println("EmpServiceImpl transactionInsertUpdate Start...");
// return md.transactionInsertUpdate(); //transaction X
return md.transactionInsertUpdate3(); //transaction OK
}
}
Console |
Spring Starter Project | oBootMybatis01 |
package | com.oracle.oBootMybatis01.dao |
interface | Member1Dao |
package com.oracle.oBootMybatis01.dao;
import java.util.List;
import com.oracle.oBootMybatis01.model.Member1;
public interface Member1Dao {
int memCount(String id); //Member1의 count
List<Member1> listMem(Member1 member1);
int transactionInsertUpdate();
int transactionInsertUpdate3();
}
Console |
Spring Starter Project | oBootMybatis01 |
package | com.oracle.oBootMybatis01dao |
class | Member1DaoImpl |
package com.oracle.oBootMybatis01.dao;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import com.oracle.oBootMybatis01.model.Member1;
import lombok.RequiredArgsConstructor;
@Repository
@RequiredArgsConstructor
public class Member1DaoImpl implements Member1Dao {
private final PlatformTransactionManager transactionManager;
//My Batis 연동
public final SqlSession session;
@Override
public int memCount(String id) {
// Mapper --> Member1.xml
// result = session.selectOne("memCount", id);
System.out.println("Member1DaoImpl memCount start.....");
int result = 0;
try {
result = session.selectOne("memCount", id);
System.out.println("Member1DaoImpl memCount memCount(result)-> "+result);
} catch (Exception e) {
System.out.println("Member1DaoImpl memCount e.getMessage()-> "+e.getMessage());
}
return result;
}
@Override
public List<Member1> listMem(Member1 member1) {
List<Member1> listMem = null;
System.out.println("Member1DaoImpl listMem start.....");
try {
listMem = session.selectList("listMember1",member1);
System.out.println("Member1DaoImpl listMem member-> "+member1);
} catch (Exception e) {
System.out.println("Member1DaoImpl listMem e.getMessage()-> "+e.getMessage());
}
return listMem;
}
//둘 중 오류난 하나만 값이 안들어가짐
@Override
public int transactionInsertUpdate() {
int result = 0;
System.out.println("Member1DaoImpl transactionInsertUpdate Start...");
Member1 member1 = new Member1();
Member1 member2 = new Member1();
try {
//두 개의 transaction Test 성공과 실패
// 결론 --> SqlSession 은 하나 실행할 때마다 자동 Commit
member1.setId("1005");
member1.setPassword("2345");
member1.setName("강유6");
result = session.insert("insertMember1", member1);
System.out.println("Member1DaoImpl transactionInsertUpdate member1 result-> "+result);
//같은 PK로 실패 유도
member2.setId("1005");
member2.setPassword("3457");
member2.setName("이순신7");
result = session.insert("insertMember1", member2);
System.out.println("Member1DaoImpl transactionInsertUpdate member2 result-> "+result);
} catch (Exception e) {
System.out.println("Member1DaoImpl transactionInsertUpdate Exception -> "+e.getMessage());
result = -1;
}
return result;
}
//하나의 method 안에 하나라도 안넣어지면 둘 다 안들어가짐
//(이렇게 해야한다. 하나는 들어가고 하나는 안들아가고가 아니라)
@Override
public int transactionInsertUpdate3() {
int result = 0;
System.out.println("Member1DaoImpl transactionInsertUpdate3 Start...");
Member1 member1 = new Member1();
Member1 member2 = new Member1();
TransactionStatus txStatus =
transactionManager.getTransaction(new DefaultTransactionDefinition());
try {
//두 개의 transaction Test 성공과 실패
// 결론 --> SqlSession 은 하나 실행할 때마다 자동 Commit
//Transaction관리는 transactionManager의 getTransaction을 가지고 상태따라 설정
member1.setId("1007");
member1.setPassword("2345");
member1.setName("강유6");
result = session.insert("insertMember1", member1);
System.out.println("Member1DaoImpl transactionInsertUpdate3 member1 result-> "+result);
//같은 PK로 실패 유도
member2.setId("1008");
member2.setPassword("3457");
member2.setName("이순신7");
result = session.insert("insertMember1", member2);
System.out.println("Member1DaoImpl transactionInsertUpdate3 member2 result-> "+result);
transactionManager.commit(txStatus);
} catch (Exception e) {
transactionManager.rollback(txStatus);
System.out.println("Member1DaoImpl transactionInsertUpdate3 Exception -> "+e.getMessage());
result = -1;
}
return result;
}
}
Console |
- transaction 걸어주는 2가지 방법!
1. TransactionStatus를 걸어주기
2. pl/sql procedure 를 활용하면 transaction 된다.
transaction 4가지
원자성, 지속성, 일관성, 독립성
Spring Starter Project | oBootMybatis01 |
package | com.oracle.oBootMybatis01 |
xml | Member1.xml |
<?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="com.oracle.oBootMyBatis01.Member1Mapper">
<select id="memCount" parameterType="java.lang.String" resultType="int">
SELECT COUNT(*)
FROM member1
WHERE id=#{id}
</select>
<select id="listMember1" parameterType="Member1" resultType="Member1">
SELECT *
FROM member1
</select>
<insert id="insertMember3" parameterType="Member1">
INSERT INTO Member1(id, password, name)
VALUES (#{id}, #{password}, #{name})
</insert>
<insert id="insertMember1" parameterType="Member1">
INSERT INTO Member1(id, password, name)
VALUES (#{id}, #{password}, #{name, jdbcType=VARCHAR})
</insert>
</mapper>
Console |
- null값이 들어가도 입력되게 하기 위해서는 jdbcType을 해주어야 한다.
- transa
websocket 만들어주기 -> 채팅!!
package 하나 더 만들어주기
com.oracle.oBootMybatis01.handler
Spring Starter Project | oBootMybatis01 |
package | com.oracle.oBootMybatis01.configuration |
class | WebSocketConfig |
package com.oracle.oBootMybatis01.configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import com.oracle.oBootMybatis01.handler.SocketHandler;
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
//소켓에서 서버역할 하는!!
// socket 서버 -> controller랑 비슷한 역할을 하는!! (controller는 아니다!!!)
@Autowired
SocketHandler socketHandler;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
// 누군가 URL '/chating' 치면 --> socketHandler 발동
//socket 세상에서는 얘가 controller 같은 역할을 해준다.
registry.addHandler(socketHandler, "/chating");
}
}
Console |
-
Spring Starter Project | oBootMybatis01 |
package | com.oracle.oBootMybatis01.handler |
class | SocketHandler |
package com.oracle.oBootMybatis01.handler;
import java.util.HashMap;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
//bean 으로 설정되어야 해서
@Component
public class SocketHandler extends TextWebSocketHandler {
// 웹소켓 세션을 담아둘 맵
HashMap<String, WebSocketSession> sessionMap = new HashMap<>();
// 웹소켓 세션 ID과 Member을 담아둘 맵
HashMap<String, String> sessionUserMap = new HashMap<>();
// 웹소켓 세션 ID과 Member을 담아둘 JSONObject
JSONObject jsonUser = null;
// 2. handleTextMessage 메소드는 메시지를 수신하면 실행
//메세지 보낼 때
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
// super.handleTextMessage(session, message);
//Message 수신
String msg = message.getPayload();
System.out.println("SocketHandler handleTextMessage msg-> "+msg);
JSONObject jsonObj = jsonToObjectParser(msg);
//type을 Get 하여 분기
String msgType = (String) jsonObj.get("type");
System.out.println("SocketHandler handleTextMessage msgType-> "+msgType);
}
// 1. 웹소켓 연결이 되면 동작
//연결할 때
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
// TODO Auto-generated method stub
System.out.println("SocketHandler afterConnectionEstablished Start...");
// 웹소켓 연결이 되면 동작
super.afterConnectionEstablished(session);
//연결 소켓을 MAP에 등록
sessionMap.put(session.getId(), session);
}
// 3. 웹소켓이 종료되면 동작
//연결을 끊을 때 쓰는 method
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
System.out.println("SocketHandler afterConnectionClosed Start...");
//웹소켓 종료
sessionMap.remove(session.getId());
super.afterConnectionClosed(session, status);
}
//내부적으로 사용되는 parsing 하는 method
// handleTextMessage 메소드에 JSON파일이 들어오면 파싱해주는 함수를 추가
private static JSONObject jsonToObjectParser(String jsonStr) {
JSONParser parser = new JSONParser();
JSONObject jsonObj = null;
try {
jsonObj = (JSONObject) parser.parse(jsonStr);
} catch (ParseException e) {
System.out.println("SocketHandler JSONObject ParseException -> "+e.getMessage());
}
return jsonObj;
}
}
Console |
- TextWebSocketHandler를 상속받아주기 (class 상속)
- bean으로 설정해주어야 해서 @Component 해주어야 한다.
-
-
Spring Starter Project | oBootMybatis01 |
package | com.oracle.oBootMybatis01.controller |
class | SocketController |
package com.oracle.oBootMybatis01.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import lombok.extern.slf4j.Slf4j;
@Controller
@Slf4j
public class SocketController {
@RequestMapping("/chat")
public ModelAndView chat() {
//ModelAndView 는 Model과 view를 같이 쓴다.
System.out.println("SocketController chat Start...");
ModelAndView mv = new ModelAndView();
// viewResolver로 인해서
mv.setViewName("chatView");
return mv;
}
}
Console |
Spring Starter Project | oBootMybatis01 |
folder | src/main/webapp/WEB-INF/views |
JSP | chatView.jsp |
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<style>
*{
margin:0;
padding:0;
}
.container{
width: 500px;
margin: 0 auto;
padding: 25px
}
.container h1{
text-align: left;
padding: 5px 5px 5px 15px;
color: #FFBB00;
border-left: 3px solid #FFBB00;
margin-bottom: 20px;
}
.chating{
background-color: #000;
width: 500px;
height: 500px;
overflow: auto;
}
.chating .me{
color: #F6F6F6;
text-align: right;
}
.chating .others{
color: #FFE400;
text-align: left;
}
input{
width: 330px;
height: 25px;
}
#yourMsg{
display: none;
}
#yourNameDel{
display: none;
}
</style>
</head>
<script type="text/javascript">
// web Socket
var ws;
function wsOpen(){
console.log("wsOpen location.host: " + location.host);
var wsUri = "ws://" + location.host + "${pageContext.request.contextPath}/chating";
// WebSocket 프로토콜을 사용하여 통신하기 위해서는 WebSocket객체를 생성.
// 객체는 자동으로 서버로의 연결
ws = new WebSocket(wsUri);
wsEvt();
}
function wsEvt() {
console.log("wsEvt start... ");
alert("wsEvt start...")
//소켓이 열리면 동작
ws.onopen = function(data){
console.log("wsEvt 소켓이 열리면 초기화 세팅하기..");
}
//메시지를 받으면 동작
ws.onmessage = function(data) {
var msg = data.data;
var memberSave = false;
alert("ws.onmessage->"+msg)
if(msg != null && msg.trim() != ''){
memberSave = false;
// JSON 오브젝트를 자바스크립트 오브젝트로 변환
var jsonMsg = JSON.parse(msg);
// msg가 배열이고, 2개이상의 Count이면 , member 등록 대상
if (Array.isArray(jsonMsg)) {
if (Object.keys(jsonMsg).length > 1) {
memberSave = true;
alert("JSONArray jsonMsg Count->"+ Object.keys(jsonMsg).length);
}
}
}
// 파싱한 객체의 type값을 확인하여 getId값이면 초기 설정된 값이므로 채팅창에 값을 입력하는게 아니라
// 추가한 태그 sessionId에 값을 세팅
if(jsonMsg.type == "getId"){
alert("jsonMsg.type->getId");
var sid = jsonMsg.sessionId != null ? jsonMsg.sessionId : "";
if(sid != ''){
$("#sessionId").val(sid);
// session User 등록 수행
sendUser('Create');
}
}else if(jsonMsg.type == "message"){
alert("jsonMsg.type->message");
// type이 message인 경우엔 채팅이 발생한 경우.
// 상대방과 자신을 구분하기 위해 여기서 sessionId값을 사용
// 최초 이름을 입력하고 연결되었을때, 발급받은 sessionId값을 비교하여 같다면 자기 자신이 발신한
// 메시지이므로 오른쪽으로 정렬하는 클래스를 처리하고 메시지를 출력.
// 비교하여 같지 않다면 타인이 발신한 메시지이므로 왼쪽으로 정렬하는 클래스를 처리하고 메시지를 출력
if(jsonMsg.sessionId == $("#sessionId").val()){
$("#chating").append("<p class='me'>나 :" + jsonMsg.msg + "</p>");
}else{
$("#chating").append("<p class='others'>" + jsonMsg.userName + " :" + jsonMsg.msg + "</p>");
}
}
// Session에 변동이 일어 날때
if(memberSave == true){
alert("userSave");
$('#member_sub').remove();
// memberSave = true 면 --> User 등록/삭제 일경우
// div로 감싸주면 재정의시 삭제(Refresh)후 다시 생성
//var str = " <div id='member_sub' class='member_sub'> ";
var str = " ";
str += " <select name='member' id='member_sub' class='member_sub'> ";
str += " <option value='ALL'>전체 </option> ";
$(jsonMsg).each(
function(){
var str2 = "";
// User를 선택하여 message전송 가능토록 member에 등록
alert("내 sessionId->"+ $("#sessionId").val())
alert("this.sessionId->"+ this.sessionId)
if(this.sessionId == $("#sessionId").val()){
alert("내꺼임"+ $("#sessionId").val())
} else { // 타인 session일 경우 추가 등록
str2 += " <option value='"+this.sessionId + "'> "+this.userName + "</option> ";
str += str2 ;
}
}
);
str += " </select>"
str += " </div><p>"
$('#member').append(str);
memberSave = false;
}else{
console.warn("unknown type!");
}
}
document.addEventListener("keypress", function(e){
if(e.keyCode == 13){ //enter press
send();
}
});
}
// User 등록 Message 전송 saveStatus --> Create / Delete
function sendUser(saveStatus) {
var userOption ={
type : "userSave",
sessionId : $("#sessionId").val(),
userName : $("#userName").val(),
saveStatus : saveStatus
}
alert("sendUser Start..")
// 자바스크립트의 값을 JSON 문자열로 변환
// Client --> Server
ws.send(JSON.stringify(userOption));
//자기자신 창을 닫습니다.
if(saveStatus == "Delete") {
alert("sendUser saveStatus-->"+saveStatus);
//window.open('','_self').close();
window.open(location.href, "_self", "");
window.close()
}
}
function chatName(){
alert("chatName Start..");
var userName = $("#userName").val();
console.log("chatName userName: " + userName);
if(userName == null || userName.trim() == ""){
alert("사용자 이름을 입력해주세요.");
$("#userName").focus();
}else{
wsOpen();
$("#meName").append('나의이름:'+userName);
$("#yourName").hide();
$("#yourMsg").show();
// $("#yourNameDel").show();
}
}
// 전체 Message 전송
function send() {
var option ={
type: "message",
sessionId : $("#sessionId").val(),
userName : $("#userName").val(),
yourName : $("#member_sub").val(),
msg : $("#sendMsg").val()
}
// 자바스크립트의 값을 JSON 문자열로 변환
ws.send(JSON.stringify(option));
$('#sendMsg').val("");
}
</script>
<body>
<div id="container" class="container">
<h1>채팅</h1>
<input type="hidden" id="sessionId" value="">
<div id="meName"></div>
<div id="chating" class="chating">
</div>
<div id="member" class="member">
</div>
<div id="yourName">
<table class="inputTable">
<tr>
<th>사용자명</th>
<th><input type="text" name="userName" id="userName"></th>
<th><button onclick="chatName()" id="startBtn">이름 등록</button></th>
</tr>
</table>
</div>
<div id="yourNameDel">
<table class="deleteTable">
<tr>
<th>사용자명 삭제</th>
<!-- <th><input type="text" name="userName" id="userName"></th> -->
<th><button onclick="sendUser('Delete')" id="startBtn">이름 삭제</button></th>
</tr>
</table>
</div>
<div id="yourMsg">
<table class="inputTable">
<tr>
<th>메시지</th>
<th><input id="sendMsg" placeholder="보내실 메시지를 입력하세요."></th>
<th><button onclick="send()" id="sendBtn">보내기</button></th>
</tr>
</table>
</div>
</div>
</body>
</html>
Console |
- 직접 입력 안하고 선생님 파일 넣는다.
Socket 로직
WebSocket
1. @Configuration을 넣으면 프로그램 시작 시 제일 먼저 시작
addHandler로 socketHandler를 사용하기 위한 로직을 만들기
/chating이라는 것이 발동되면, controller역할을 socketHandler가 해준다는 의미!! (controller는 아니다)
2.
'Spring' 카테고리의 다른 글
oBootMyBatis (0) | 2024.09.12 |
---|---|
Day63 2024.08.21.수 #코딩일기 (0) | 2024.08.21 |
Day61 2024.08.19.월 #코딩일기 (0) | 2024.08.19 |
Day60 2024.08.14.수 #코딩일기 (0) | 2024.08.14 |
Day59 2024.08.13.화 #코딩일기 (0) | 2024.08.13 |