Controller
package com.kh.spring.idol.controller;
import java.nio.charset.Charset;
import java.util.List;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.kh.spring.idol.model.service.IdolService;
import com.kh.spring.idol.model.vo.Idol;
import lombok.RequiredArgsConstructor;
@CrossOrigin("*")
@RestController
@RequiredArgsConstructor
public class IdolController {
@GetMapping("/idols")
public ResponseEntity<List<Idol>> selectIdols() {
List<Idol> idolList = idolService.selectIdols();
//System.out.println(idolList);
HttpHeaders header = new HttpHeaders();
header.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
return new ResponseEntity<List<Idol>>(idolList, header, HttpStatus.OK);
}
// ResponseEntity => 반환할 때 쓰는 데이터 타입
// produces에 담았던 아이들은 원래 header에 들어가는 것들
// 이게 contentType 정하는 건데 HttpHeaders로 세팅할 수 있음
// Post방식을 쓰면 헤더가 아닌 바디에 데이터가 들어옴
// RequestBody를 이용하여 커맨드객체 방식을 쓸 수 있음
@PostMapping("/idol")
public ResponseEntity<String> insertIdol(@RequestBody Idol idol) {
//System.out.println(idol);
String result = idolService.insertIdol(idol) != 0 ? "success" : "fail";
HttpHeaders header = new HttpHeaders();
header.setContentType(new MediaType("text", "html", Charset.forName("UTF-8")));
return new ResponseEntity<String>(result, header, HttpStatus.OK);
}
// 업데이트 put매핑
// 삭제 delete매핑
@DeleteMapping("/idol/{id}")
public ResponseEntity<String> deleteIdol(@PathVariable(name="id") String id) {
System.out.println(id);
String result = idolService.deleteIdol(id) != 0 ? "success" : "fail";
HttpHeaders header = new HttpHeaders();
header.setContentType(new MediaType("text", "html", Charset.forName("UTF-8")));
return new ResponseEntity<String>(result, header, HttpStatus.OK);
}
}
import { useEffect, useState } from "react";
import IdolDetail from "./IdolDetail";
import IdolMain from "./IdolMain";
import axios from 'axios';
import Button from "react-bootstrap/esm/Button";
const IdolInfo = props => {
/*
console.log(props);
console.log(props.idolList[0]);
const [idol1, idol2, idol3] = props.idolList;
*/
// const idolList = props.idolList;
// console.log(idolList);
/*
const idol1 = props.idolList[0];
const idol2 = props.idolList[1];
const idol3 = props.idolList[2];
*/
const [idolList, setIdolList] = useState([]);
const [nameValue, setNameValue] = useState('');
const [memberValue, setMemberValue] = useState('');
const [songValue, setSongValue] = useState('');
const [imageValue, setImageValue] = useState('');
// 초기값은 반드시 넣어준다 => 숫자는 0, 문자열은 '', 배열은 []
// 안넣으면 undefined
const [scriptValue, setScriptValue] = useState('');
const inputName = e => {
// console.log('진짜임?');
setNameValue(e.target.value);
}
const inputMember = e => {
setMemberValue(e.target.value);
}
const inputSong = e => {
setSongValue(e.target.value);
}
const inputImage = e => {
setImageValue(e.target.value);
}
const inputScript = e => {
setScriptValue(e.target.value);
}
const [flag, isFlag] = useState(false);
const addIdol = () => {
// 빈문자열이면 Falsy한 값 => 조건으로 사용
if(nameValue && memberValue && songValue && imageValue){
//const ids = idolList.map(i => i.id);
//console.log(Math.max(...ids)); // ...은 스프레드문법 => 배열안의 요소들을 쫙 펼쳐줌
const idol = {
//id : Math.max(...ids) + 1,
name : nameValue,
member : memberValue,
song : songValue,
image : imageValue,
description : scriptValue
}
// console.log(idol);
// idolList.push(idol); => 스페이스라도 눌러야 뜸
//let copyArr = [...idolList, idol];
//console.log(copyArr);
//setIdolList(copyArr);
axios.post('/spring/idol', idol)
.then(result => {
//console.log(result); => data가 success
if(result.data == 'success'){
isFlag(!flag);
}
});
setNameValue('');
setMemberValue('');
setSongValue('');
setImageValue('');
setScriptValue('');
}
else{
alert('모든 항목을 입력해 주세요!!');
}
}
useEffect(() => {
axios.get('/spring/idols')
.then(result => {
//console.log(result);
let copyArr = [...result.data];
setIdolList(copyArr);
})
}, [flag]); // flag가 변경될 때마다 useEffect실행
return (
<>
<IdolMain />
{
/*
<IdolDetail idol={idol1} />
<IdolDetail idol={idol2} />
<IdolDetail idol={idol3} />
*/
// for문ㄴㄴ
idolList.map((idol, index) => {
// console.log(idol);
// console.log(index);
// key는 안넘겨주면 오류가 뜨기 때문에 index로 넘겨줌
return (
<IdolDetail idol={idol} key={index} setList={setIdolList} list={idolList} flag={flag} isFalg={isFlag} />
)
})
}
<br/>
<div id="enroll-form">
<div>
<h3>그룹명</h3>
<textarea onChange={inputName} value={nameValue}></textarea>
</div>
<div>
<h3>인원수</h3>
<textarea onChange={inputMember} value={memberValue}></textarea>
</div>
<div>
<h3>대표곡</h3>
<textarea onChange={inputSong} value={songValue}></textarea>
</div>
<div>
<h3>사진주소</h3>
<textarea onChange={inputImage} value={imageValue}></textarea>
</div>
<div>
<h3>그룹설명</h3>
<textarea onChange={inputScript} value={scriptValue}></textarea>
</div>
</div>
<Button onClick={addIdol} >아이돌을 추가하자</Button>
<br/><br/><br/><br/><br/>
</>
);
}
export default IdolInfo;
import Button from "react-bootstrap/esm/Button";
import { useNavigate } from "react-router-dom";
import axios from 'axios';
const IdolDetail = props => {
// console.log(props);
const idol = props.idol;
const setList = props.setList;
const list = props.list;
function deleteIdol(e){
/*
if(list.length != 1){
const newIdolList = list.filter(idol => { return idol.id != e.target.id });
//console.log(newIdolList);
setList(newIdolList);
}
else {
alert('다 없앨 순 없어요');
}
*/
//e.target.id
axios.delete('/spring/idol/' + e.target.id)
.then(result => {
if(result.data == 'success'){
props.isFlag(!props.flag);
}
})
};
const navigate = useNavigate();
const detailPage = () => {
navigate('/detailpage', {state : idol});
}
return(
<div className="info">
<div>
<img src={idol.image} alt="아이돌사진" onClick={detailPage} />
</div>
<div>
<p>그룹명</p>
<p>{idol.name}</p>
</div>
<div>
<p>인원</p>
<p>{idol.member}</p>
</div>
<div>
<p>대표곡</p>
<p>{idol.song}</p>
</div>
<div>
<Button onClick={deleteIdol} id={idol.id} variant="dark">삭제하기</Button>
</div>
</div>
)
}
export default IdolDetail;
서버를 두개 키려면 빵!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1. 서버를 멈춘다.
2. 프로젝트 우클릭
3. Run As > Maven install
이클립스에서 도는 게 아니라 나가서
4. target폴더에 spring-1.0.0-BUILD-SNAPSHOT.war이 생김
5. 그 파일C:\spring-workspace\springProject\target을 직접 찾아가서 잘라내기
6. C:\development\apache-tomcat-8.5.93\webapps 에 가서 붙여넣기
7. 파일명 수정 (spring으로 변경했음)
8. C:\development\apache-tomcat-8.5.93\conf 에서 server.xml열기
9. <Connector port="8001" protocol="HTTP/1.1".... => 8080을 8001로 변경
10. C:\development\apache-tomcat-8.5.93\bin 에서 startup.bat 실행
11. 그러면 서버를 굳이 안켜도 됨
12. localhost:8001/spring도 잘 돌아감