728x90
참고
config패키지 및 클래스 생성
WebMvcConfigurer상속을 받아주고 @Configuration 주석 달아줌
소스에 오버라이드 메소드 클릭해서
필요한 addResourceHandlers만 체크
package com.suji.merong.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration //자바파일을 설정 파일로 변경시켜줌
public class MyConfig implements WebMvcConfigurer{
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
System.out.println("요기가 실행되었는지 check?");
registry.addResourceHandler("/kmerong/**") // 웹 접근 경로
.addResourceLocations("file:///d:/merong/"); // 서버내 실제 경로
}
}
실제 파일 경로 만들어줌
서버 재실행
콘솔 확인해서 check 나오는지 확인
url주소 쳐서 확인
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js" integrity="sha512-3gJwYpMe3QewGELv8k/BX9vcqhryRdzRMxVfq6ngyWXwo03GFEzjsUm8Q7RZcHPHksttq7/GFoxjCVUjkjvPdw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>
<body>
<div id="list"></div>
<div id="sajin"></div>
<form>
넘버 : <input type="text" name="sujiNum" value="" placeholder="번호를 입력하세요"><br/>
이름 : <input type="text" name="sujiName" value=""><br/>
내용 : <textarea type="text" name="sujiContent" value=""></textarea><br/>
파일 : <input type="text" name="sujiFile" value=""><br/>
진짜 파일 : <input type="file" name="sujiFile2" value="">
<button type="button" id="create">생성</button>
<button type="button" id="search">조회</button>
<button type="button" id="update">수정</button>
<button type="button" id="delete">삭제</button><br/>
<button type="button" id="fileUp">파일Up</button>
</form>
<script>
const $sajin = $("#sajin");
const $fileUp = $("#fileUp");
const $upBtn = $("#update");
const $delBtn = $("#delete");
const $search = $("#search");
const $creBtn = $("#create");
const $sujiNum =$("input[name='sujiNum']");
const $sujiName =$("input[name='sujiName']");
const $sujiContent=$("textarea[name='sujiContent']");
const $sujiFile=$("input[name='sujiFile']")
const $sujiFile2=$("input[name='sujiFile2']")
//파일 업로드
$fileUp.on("click",()=>{
console.log(document.querySelector("input[name='sujiFile2']").files);
console.log($sujiFile2[0].files[0]);
//파일업로드 하면 생각나는 거?
let formData = new FormData(); //얘는 전송방식이 무조건 multipart/form-data
formData.append("hynhak",$sujiFile2[0].files[0]);
//바닐라 자바스크립트롱
let xhr = new XMLHttpRequest();
xhr.open("post","/rest/suji2",true);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
let rslt = xhr.responseText;
console.log("이것은rslt",rslt);
let myImg = document.createElement("img");
myImg.src = rslt;
myImg.width = 100; myImg.height=100;
document.querySelector("#sajin").appendChild(myImg);
}
}
xhr.send(formData);
/*
//제이쿼리 방식
$.ajax({
type : "post",
url : "/rest/suji2",
data : formData, //JSON.stringify 하지 않음에 주의!
contentType:false, //defult값이 application/x-www-form-urlencoded
processData:false, //defult값이 application/x-www-form-urlencoded
cache:false, //요건 선택 권장!
dataType : "text",
success : function(rslt){
console.log("체킁",rslt);
document.createElement("img");
$("<img></img")
.attr("src",rslt)
.css("width",200)
.css("height",200)
.appendTo($sajin);
// let mImg = document.createElement("img");
// mImg.src = rslt;
// document.querySelector("#sajin").appendChild(mImg);
},
error:function(xhr, status, error){
console.log("code: " + xhr.status)
console.log("message: " + xhr.responseText)
console.log("error: " + error);
}
});
*/
});
//수정하깅
$upBtn.on("click",()=>{
let sujiVO = {
sujiNum:$sujiNum.val(),
sujiName:$sujiName.val(),
sujiContent:$sujiContent.val(),
sujiFile:$sujiFile.val()
}
console.log("sujiVO",sujiVO);
$.ajax({
url : "/rest/suji",
type : "put",
data:JSON.stringify(sujiVO),
dataType : "text",
contentType : "application/json; charset=utf-8",
success : function(rslt){
console.log(rslt)
if(rslt){
alert("잘 수정 되엇어용");
getList();
}else{
alert("수정되지 않았어용!!!");
}
},
error:function(xhr, status, error){
console.log("code: " + xhr.status)
console.log("message: " + xhr.responseText)
console.log("error: " + error);
}
});
});
//삭제하깅
$delBtn.on("click",()=>{
console.log("확인 : ",$sujiNum.val())
$.ajax({
url : `/rest/suji/${$sujiNum.val()}`,
type : "delete",
dataType : "text",
success : function(rslt){
rslt = parseInt(rslt);
if(rslt){
alert("잘 지워졌어용!!")
console.log(rslt)
$sujiNum.val("");
$sujiName.val("");
$sujiContent.val("");
$sujiFile.val("");
getList();
$sujiNum.focus();
}else{
alert("없는 넘버에용! 알겠어용?!");
getList();
}
},
error:function(xhr, status, error){
console.log("code: " + xhr.status)
console.log("message: " + xhr.responseText)
console.log("error: " + error);
}
});
});
//값 하나 가져오기
$search.on("click",()=>{
console.log("확인 : ",$sujiNum.val())
$.ajax({
url : `/rest/suji/${$sujiNum.val()}`,
type : "get",
dataType : "text",
success : function(rslt){
if(rslt){
console.log(rslt)
rslt = JSON.parse(rslt);
$sujiName.val(rslt.sujiName);
$sujiContent.val(rslt.sujiContent);
$sujiFile.val(rslt.sujiFile);
}else{
alert("없는 넘버에용! 알겠어용?!");
}
},
error:function(xhr, status, error){
console.log("code: " + xhr.status)
console.log("message: " + xhr.responseText)
console.log("error: " + error);
}
});
});
//값 넣기 인설트
$creBtn.on("click",()=>{
let sujiVO = {
sujiName:$sujiName.val(),
sujiContent:$sujiContent.val(),
sujiFile:$sujiFile.val()
}
console.log("sujiVO",sujiVO);
$.ajax({
url : "/rest/suji",
type : "POST",
data:JSON.stringify(sujiVO),
dataType : "text",
contentType : "application/json; charset=utf-8",
async : true,
success : function(rslt){
console.log(rslt)
if(rslt){
alert("잘 입력 되엇어요");
getList();
}else{
alert("입력되지 않았어용");
}
},
error:function(xhr, status, error){
console.log("code: " + xhr.status)
console.log("message: " + xhr.responseText)
console.log("error: " + error);
}
});
});
//JQuery 생성자는 낭비되지 않도록 잘 사용해야함
//여러번 사용될 거로 예상될 때는 꼬옥 변수로 받아서 사용!
const $list = $("#list");
//window.addEventListener("DOMContentLoaded" 이벤트
// $(function(){
// getList();
// });
$(()=>{
getList();
})
//페이지 시작하자마자 리스트 뿌리깅
function getList(){
$.ajax({
type:"get",
url:"/rest/suji",
//data:"", //보낼 데이터가 없어서 생략
dataType:"text",// 요걸 알아서 해줌 JSON.parse(xhr.responseText),클라이언트에서 해줌
//contentType:"application/json; charset=utf-8", //보낼데이터가 없어서 생략
//async:"true", //디폴트가 true라서 안써도됨 생략
success:function(rslt){
console.log("체킁 : ",JSON.parse(rslt));
rslt = JSON.parse(rslt);
//정렬도 클라이언트 사이드에서 하면 성능이나 , 서버부하
//줄이는 측면에서 유리함
rslt.sort((a,b)=>{
return b.sujiNum-a.sujiNum;
})
//빨랑 테이블로 출력해보삼
let tblStr = "<table border=1>"
tblStr += "<tr><td>넘버</td><td>이름</td><td>내용</td><td>파일</td></tr>"
for(let i=0; i<rslt.length; i++){
tblStr += `<tr><td>${rslt[i].sujiNum}</td><td>${rslt[i].sujiName}</td><td>${rslt[i].sujiContent}</td><td>${rslt[i].sujiFile}</td></tr>`
}
tblStr +="</table>"
//disp에 뿌리기
$list.html(tblStr)
},
error:function(xhr, status, error){
console.log("code: " + xhr.status)
console.log("message: " + xhr.responseText)
console.log("error: " + error);
}
});
}
</script>
</body>
</html>
SujiController
@PostMapping("/rest/suji2")
public String insertSuji2(MultipartFile hynhak) { //@RequestBody 사용하지 않음에 유의!!
log.debug("fileName" + hynhak.getOriginalFilename());
log.debug("size" + hynhak.getSize());
return "OK";
}
formData.append("hynhak",$sujiFile2[0].files[0]); 여기 값이랑 같아야함(hynhak)
OK확인했으니
Controller 수정
@PostMapping("/rest/suji2")
public String insertSuji2(MultipartFile hynhak) throws Exception { //@RequestBody 사용하지 않음에 유의!!
log.debug("fileName" + hynhak.getOriginalFilename());
log.debug("size" + hynhak.getSize());
//물리적 파일저장 디렉토리
String savePath = "d:/merong/" + hynhak.getOriginalFilename();
hynhak.transferTo(new File(savePath)); //transferTo만 기억하자
// savePath에 해당하는 웹 경로
String webURL = "/kmerong/" + hynhak.getOriginalFilename();
return webURL;
}
여기서
MyConfig와 경로 맞춤
결과확인