스프링 & 리액트 이미지 파일 등록(MultipartHttpServletRequest)

2023. 5. 11. 22:45·FE/React

스프링(서버)

1. mapper

- namespace를 지정하여 다른 mapper와 구분지어준다.

<?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.example.mapper.BookMapper">
<insert id="insert">
	insert into books(title,price,author,image) values (#{title},#{price},#{author},#{image})
</insert>

 

2. BookVO 생성하기

- DB의 테이블 컬럼명과 동일하게 주는 것이 좋다

- getter, setter 메소드 생성해서 외부 파일에서 사용할 수 있도록 해줌

private int code;
	private String title;
	private int price;
	private String author;
	private String image;
	private int viewcnt;
	private String content;

 

3. BookDAO 생성

- 인터페이스로 만든다

public interface BookDAO {
	public void insert(BookVO vo);
}

 

4. BookDAOImpl 생성

- DAO 구현체

@Repository
public class BookDAOImpl implements BookDAO{
@Autowired
SqlSession session;
String namespace="com.example.mapper.BookMapper";

    @Override
    public void insert(BookVO vo) {
        session.insert(namespace+".insert",vo);
    }
}

- 해당 mapper의 namespace를 지정하여 id가 Insert인 sql문을 실행하여 vo값을 넘겨준다

 

5. BookController 생성

- 데이터 처리만 하기 위해 @RestController 어노테이션을 지정해준다.

- 기본 경로는 books로 @RequestMapping 어노테이션으로 지정

@RestController
@RequestMapping("/books")
public class BookController {	
	@Autowired
	BookDAO dao;
    
@RequestMapping(value="/insert", method=RequestMethod.POST)
public void insert(BookVO vo, MultipartHttpServletRequest multi) {
    try {
        if(multi.getFile("file")!=null) {
            MultipartFile file = multi.getFile("file");
            String path = "/Users/sy/images/books/";
            String fileName = System.currentTimeMillis()+".jpg";
            file.transferTo(new File(path+fileName));
            vo.setImage(fileName);
        }
        dao.insert(vo);

    }catch(Exception e) {
        System.out.println("도서등록오류"+e.toString());
    }
}
}

- MultipartHttpServletRequest는 멀티파트 요청에서 전송된 데이터를 처리하기 위한 클래스로 파일데이터를 가져온다.

- MultipartFile로 멀티파트 요청에서 file필드를 가져온다

* getFile로 가져온 file필드는 은 요청 보내줄 때 이름을 동일하게 file로 작성해야함

- try~catch문으로 등록 오류시 메세지 출력

- path변수에는 파일을 저장할 폴더 경로 지정, fileName에는 저장할 파일 이름 지정

* System.currentTimeMillis()는 1970.1.1~현재까지의 시간을 밀리초 단위로 반환해주는 메소드, 파일 식별자 생성시 주로 사용됨

- vo의 image필드에 새로 생성한 fileName으로 이미지를 저장한다.

 

리액트 

 1. 폼 상태변수 생성 & 비구조화 할당

 const [form, setForm] = useState({
    title:"",
    author:"",
    price: "",
    file: null
});

const {title, author, price, file} = form;

 

- 폼 안에 있는 각각의 input태그에다 각각의 속성을 value값으로 담아주고 동일한 이름을 name="속성명"으로 작성한다

 

2.  폼내용 변경함수 onChange

 const onChange = (e) => {      
        setForm({
            ...form,
            [e.target.name]: e.target.value
        })
    }

- value값을 준 input상자는 값이 변하지 않기 때문에 함수를 만들어주어야 한다.

- setForm으로 기존 폼 데이터를 복사하고 (...form), 여러 input중 해당 이름과 동일한 value값을 현재 입력한 값으로 변경해준다.

 

 

3. 등록버튼 눌렀을 때 실행할 함수 onClickInsert

const onClickInsert = (e) => {
    e.preventDefault();
    if (!title || !author || !price || !file) {
        setBox({
            show: true,
            message: "모든 필드를 채워주세요"
        })
        return;
    }
    setBox({
        show: true,
        message: "도서를 등록하시겠습니까?",
        action: onInsert
    })
}

- 각각의 input 상자가 공백일 경우 유효성 체크를 해준 다음 Insert 작업을 해준다

 

4. 도서등록 함수 onInsert

* 업로드할 파일이 없을 경우는 axios에 form객체만 넘겨주면 된다.

 const onInsert = async () => {
        const formData = new FormData();
        formData.append("title", title);
        formData.append("price", price);
        formData.append("author", author);
        formData.append("file", file);
        const config = {
            headers: { "content-type": "multipart/form-data" }
        }
        await axios.post('/books/insert', formData, config);
        setBox({
            show: true,
            message: "도서 한권이 등록되었습니다"
        })
        history.push("/");
    }

- HTML폼 데이터를 생성하기 위한 FormData 객체 생성 (키-값 쌍의 데이터를 담을 수 있다)

- append()메서드를 사용해 도서정보를 formData에 추가

- HTTP요청 헤더를 설정하기 위한 config변수 생성, 타입은 multipart/form-data로 지정

- 데이터등록을 처리해주는 Url에 데이터 담은 formData와 config를 넘겨주면 된다.

* config 생략시 axios.post 메서드에서 요청헤더 기본값이 application/json으로 설정되기 때문에 오류가 날 수 있어 명시해줘야함

5. return문 작성

return (
    <Row className="justify-content-center my-5">
    <Col md={8}>
        <Card>
            <h1 className="mt-3">도서정보</h1>
            <Form className="px-5 py-5 text-center" onSubmit={onClickInsert}> 
                <InputGroup className='my-2'>
                    <InputGroup.Text className='px-5'>제목</InputGroup.Text>
                    <Form.Control value={title} onChange={onChange} name="title" />
                </InputGroup>
                <InputGroup className='my-2'>
                    <InputGroup.Text className='px-5'>가격</InputGroup.Text>
                    <Form.Control name="price" value={price} onChange={onChange} />
                </InputGroup>
                <InputGroup className='my-2'>
                    <InputGroup.Text className='px-5'>저자</InputGroup.Text>
                    <Form.Control name="author" value={author} onChange={onChange} />
                </InputGroup>
                <div className='my-3'>
                    <img src={fileName} width="30%" />
                    <Form.Control type="file" className="my-2" onChange={onChangeFile} />
                </div>
                <div className='mt-3 text-center'>
                    <Button className='me-2' type="submit">등록하기</Button>
                    <Button variant='secondary'>취소</Button>
                </div>
            </Form>
        </Card>
    </Col>
</Row>
  )

'FE > React' 카테고리의 다른 글

리액트로 에디터 생성하기 (CKEditor 라이브러리) + 부트스트랩 Tap  (0) 2023.05.09
리액트 구글 차트 사용법 (react google charts 라이브러리)  (0) 2023.05.08
React Context API 사용법 및 Props와 Context차이점  (0) 2023.03.16
리액트로 라우터 생성하기 (react-router-dom & qs 라이브러리)  (0) 2023.03.09
React - 카카오 API를 이용한 도서검색 (axios라이브러리, async, await)  (0) 2023.03.06
'FE/React' 카테고리의 다른 글
  • 리액트로 에디터 생성하기 (CKEditor 라이브러리) + 부트스트랩 Tap
  • 리액트 구글 차트 사용법 (react google charts 라이브러리)
  • React Context API 사용법 및 Props와 Context차이점
  • 리액트로 라우터 생성하기 (react-router-dom & qs 라이브러리)
시녜's
시녜's
성장중인 새싹 개발자 🌱
  • 시녜's
    개발기록
    시녜's
  • 전체
    오늘
    어제
    • 분류 전체보기
      • FE
        • React
        • javascript(jQuery)
        • HTML & CSS
      • BE
        • Java [Servlet , Spring]
        • C & C++
        • Node.js
        • node.js
        • SQL (Oracle, mysql)
      • CS
        • 프로그래밍 이론(정보처리기사)
      • Etc
        • 코딩 챌린지
        • 개발 성장 일지
        • 코딩테스트
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    코딩테스트
    백준
    코딩테스트입문
    백준문제풀이
    리액트
    제이쿼리
    자바기초
    코딩기초
    CharAt함수
    자바
    자바조건문
    html
    mysql
    코테기초
    자바문자열
    Java
    jquery
    프로그래밍
    자바반복문
    스프링
    백준브론즈
    백준코딩테스트
    자바배열
    백준단계별문제
    코테
    코딩입문
    jsp
    React
    자바스크립트
    javascript
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
시녜's
스프링 & 리액트 이미지 파일 등록(MultipartHttpServletRequest)
상단으로

티스토리툴바