Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- NestedFor
- EnhancedFor
- 환경설정
- 오라클
- 자바
- 추상메서드
- 생성자오버로드
- 예외처리
- 자동차수리시스템
- 한국건설관리시스템
- 제네릭
- 메소드오버로딩
- 객체 비교
- 예외미루기
- exception
- 인터페이스
- 집합_SET
- oracle
- 정수형타입
- Java
- abstract
- 다형성
- 컬렉션프레임워크
- 대덕인재개발원
- cursor문
- 컬렉션 타입
- 참조형변수
- GRANT VIEW
- 어윈 사용법
- 사용자예외클래스생성
Archives
- Today
- Total
거니의 velog
231201_SPRING 2 (8-1) 본문
* 파일 업로드
package kr.or.ddit.controller.file.item01;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Controller
@RequestMapping("/item")
public class FIleUploadController01 {
/*
* [ 13장. 파일 업로드 ]
*
* 1. 파일 업로드 설명
*
* - 서블릿 3.0에서 지원하는 파일 업로드 기능과 스프링 웹에서 제공하는 컴포넌트를 사용하여 파일을 업로드 한다.
*
* # 파일 업로드 설정
*
* 1) 서블릿 3.0 이상 지원
* 2) 서블릿 표준 파일 업로드 기능을 활성화
* 3) 스프링 MVC와 연계
* 4) 업로드 된 파일 저장 위치 설정
*
* # 환경 설정
*
* 1) 의존 관계 정의
* - 파일을 처리하기 위해서 의존 라이브러리를 추가한다.
* > pom.xml commons-io 추가
*
* 2) 웹 컨테이너 설정
* > web.xml 서블릿 표준 버전 3.1로 설정
* > multipart-config 활성화 (web.xml의 servlet 태그 내 설정)
*
* 3) 스프링 웹 설정
* > servlet-context.xml
* > multipartResolver Bean 등록 (id는 multipartResolver로 설정)
*
* [파일 업로드 설정]
* 파일 업로드를 설정하는 방식은 2가지가 있다.
*
* - StandardServletMultipartResolver 사용 시 설정.
* > servlet 3.0의 Part를 이용한 MultipartFile 데이터 처리
* > servlet-context.xml 에 설정
* > StandardServletMultipartResolver bean 등록
* > web.xml에 설정
* > multipart-config (servlet 태그 안에 설정)
*
* - CommonsMultipartResolver 사용 시 설정. ( 우리가 사용할 방식 )
* > Commons Fileupload API를 이용한 MultipartFile 데이터 처리
* > bean 속성으로 maxUploadSize, maxInMemorySize 및 defaultEncoding 설정을 제공
* > 기본값 및 허용되는 값에 대한 자세한 내용은 각 DiskFileUpload 속성을 참조
* > pom.xml 설정
* > commons-fileupload 추가
* > root-context.xml에 설정
* > CommonsMultipartResolver bean 등록
*
* - root-context.xml 에 설정
* > uploadPath bean 등록
*
* - multipartFilter 필터 등록
* > web.xml
*
* # 데이터베이스 준비
*
* - item 테이블 생성 (item, item2, item3, item3_attach)
*
* 2. 이미지 업로드
*
* - 한 개의 이미지를 업로드 하는 기본 파일 업로드 기능을 구현한다.
*
* # 파일 업로드 구현 설명
*
* - 파일 업로드 등록 화면 컨트롤러 만들기 (FileUploadController01)
* - 파일 업로드 등록 화면 컨트롤러 메소드 만들기 (itemRegisterForm:get)
* - 파일 업로드 등록 화면 만들기 (item/register.jsp)
* - 여기까지 확인
*
* - 파일 업로드 등록 기능 컨트롤러 메소드 만들기 (itemRegister:post)
* - 파일 업로드 등록 기능 서비스 인터페이스 메소드 만들기
* - 파일 업로드 등록 기능 서비스 클래스 메소드 만들기
* - 파일 업로드 등록 기능 Mapper 인터페이스 메소드 만들기
* - 파일 업로드 등록 기능 Mapper xml 쿼리 만들기
* - 파일 업로드 등록 완료 페이지 만들기
* - 여기까지 확인
*
* - 파일 업로드 목록 화면 컨트롤러 메소드 만들기 (itemList:get)
* - 파일 업로드 목록 화면 서비스 인터페이스 메소드 만들기
* - 파일 업로드 목록 화면 서비스 클래스 메소드 만들기
* - 파일 업로드 목록 화면 Mapper 인터페이스 메소드 만들기
* - 파일 업로드 목록 화면 Mapper xml 쿼리 만들기
* - 파일 업로드 목록 화면 만들기 (item/list.jsp)
* - 여기까지 확인
*
* - 파일 업로드 수정 화면 컨트롤러 메소드 만들기 (itemModifyForm:get)
* - 파일 업로드 수정 화면 서비스 인터페이스 메소드 만들기
* - 파일 업로드 수정 화면 서비스 클래스 메소드 만들기
* - 파일 업로드 수정 화면 Mapper 인터페이스 메소드 만들기
* - 파일 업로드 수정 화면 Mapper xml 쿼리 만들기
* - 파일 업로드 수정 화면 만들기 (item/modify.jsp)
* - 여기까지 확인
*
* - 파일 업로드 수정 기능 컨트롤러 메소드 만들기 (itemModify:post)
* - 파일 업로드 수정 기능 서비스 인터페이스 메소드 만들기
* - 파일 업로드 수정 기능 서비스 클래스 메소드 만들기
* - 파일 업로드 수정 기능 Mapper 인터페이스 메소드 만들기
* - 파일 업로드 수정 기능 Mapper xml 쿼리 만들기
* - 여기까지 확인
*
* - 파일 업로드 삭제 화면 컨트롤러 메소드 만들기 (itemRemoveForm:get)
* - 파일 업로드 삭제 화면 서비스 인터페이스 메소드 만들기
* - 파일 업로드 삭제 화면 서비스 클래스 메소드 만들기
* - 파일 업로드 삭제 화면 Mapper 인터페이스 메소드 만들기
* - 파일 업로드 삭제 화면 Mapper xml 쿼리 만들기
* - 파일 업로드 삭제 화면 만들기 (item/remove.jsp)
* - 여기까지 확인
*
* - 파일 업로드 삭제 기능 컨트롤러 메소드 만들기 (itemRemove:post)
* - 파일 업로드 삭제 기능 서비스 인터페이스 메소드 만들기
* - 파일 업로드 삭제 기능 서비스 클래스 메소드 만들기
* - 파일 업로드 삭제 기능 Mapper 인터페이스 메소드 만들기
* - 파일 업로드 삭제 기능 Mapper xml 쿼리 만들기
* - 여기까지 확인
*/
}
[pom.xml]
<!--
파일을 처리하기 위한 라이브러리 의존 관계 정의
-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<!--
파일 업로드를 처리하기 위한 라이브러리 의존 관계 정의
-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.2</version>
</dependency>
[servlet-context.xml]
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
<beans:property name="order" value="2" />
</beans:bean>
<!-- Tiles 설정을 위한 Bean 등록 시작 -->
<beans:bean id="tilesViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<beans:property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView" />
<beans:property name="order" value="1" />
</beans:bean>
<beans:bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<beans:property name="definitions">
<beans:list>
<beans:value>/WEB-INF/spring/tiles-config.xml</beans:value>
</beans:list>
</beans:property>
</beans:bean>
<!-- Tiles 설정을 위한 Bean 등록 끝 -->
<context:component-scan base-package="kr.or.ddit" />
<!--
서블릿 표준용 MultipartResolver 를 스프링 빈으로 정의
- StandardServletMultipartResolver 사용 시 설정
> Servlet 3.0의 Part를 이용한 MultipartFile 데이터 처리
-->
<!-- <beans:bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver">
</beans:bean> -->
</beans:beans>
[web.xml]
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_1.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<!--
web.xml의 설정은 WAS(Tomcat) 자체 설정일 뿐이다.
multipart-config : 메모리 사이즈, 업로드 파일 저장 위치, 최대 크기 설정
- location : 저장될 디렉토리(필수)
- max-file-size : 업로드 파일 최대 크기(기본값 : -1L, 제한이 없다)
- max-request-size : 한번 요청 시 업로드 파일 최대 크기
- file-size-threshold : 설정 크기가 넘는 경우 임시 디렉토리에 저장(기본값 0, 설정하지 않는 한 무조건 저장)
web.xml에서 설정하지 않을 때는 @MultipartConfig 어노테이션으로 설정이 가능하다.
- 요청을 받는 컨트롤러에 설정이 가능하다. (메소드 라인이 아니라 컨트롤러인 클래스 라인에 설정한다)
- @MultipartConfig(
location = "D:/upload",
maxFileSize = "24683394",
maxRequestSize = "478212294",
fileSizeThreshold = "154985741"
)
임시 파일이 저장되는 경로는 다음과 같다.
- C:\Users\개인PC이름\AppData\Local\Temp=
-->
<!-- <multipart-config>
<location>C:\\upload</location>
<max-file-size>24683394</max-file-size>
<max-request-size>478212294</max-request-size>
<file-size-threshold>154985741</file-size-threshold>
</multipart-config> -->
</servlet>
[root-context.xml]
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<!--
root-context.xml : 스프링 설정을 위한 파일
스프링 설정이란?
- view와 관련되지 않은 객체를 정의
- service(비즈니스 기능), DAO(repository: 저장소), DB 등 비즈니스 로직과 관련된 설정
- BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
-->
<!-- dataSource : 데이터베이스와 관련된 정보를 설정한다. -->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe" />
<property name="username" value="spring2" />
<property name="password" value="java" />
</bean>
<!--
데이터베이스와 연결을 맺고 끊어질 때까지의 라이프 사이클을 관리해주는 SqlSessionTemplate 객체를 생성한다.
1) dataSource
2) Mapper xml 위치 지정
3) 마이바티스 설정 위치 지정
-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath:/sqlmap/**/*_SQL.xml" />
<property name="configLocation" value="/WEB-INF/mybatisAlias/mybatisAlias.xml" />
</bean>
<!--
데이터베이스에 쿼리를 실행시키는 객체
이 객체를 통해서 query를 실행한다.
-->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg name="sqlSessionFactory" index="0" ref="sqlSessionFactory" />
</bean>
<!--
Mapper 인터페이스 설정
개발자가 직접 DAO를 설정하지 않아도 자동으로 Mapper 인터페이스를 활용하는 객체를 생성하게 된다.
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="kr.or.ddit.mapper" />
</bean>
<!--
MultipartFile CommonsMultipartResolver 설정 시
-->
<bean id="MultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 하나의 요청당 파일 업로드 용량(3145728) -->
<property name="maxUploadSize" value="3145728" />
<!-- 메모리에 저장되는 최대 용량 -->
<property name="maxInMemorySize" value="3145728" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<!-- 파일 업로드 디렉토리 설정 -->
<bean id="uploadPath" class="java.lang.String">
<constructor-arg value="D:\A_TeachingMaterial\07_JSP_Spring\workspace\workspace_spring2\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\Spring2Project\resources\upload" />
</bean>
</beans>
[web.xml]
<!--
MultipartFilter 적용 : 파일 업로드를 위한 필터 적용
- MultipartFilter의 역할은 들어온 요청이 multipart/form-data 유형의 요청인지를 확인하여 multipart 형태의 요청이면
MultipartResolver를 통해 multipart 요청을 확인한다.
그리고 해당 요청이 적절한 요청이면 MultipartHttpServletRequest로 랩핑한다.
- MultipartFilter의 기본 빈 이름은 'filterMultipartResolver'이다.
-->
<filter>
<filter-name>MultipartFilter</filter-name>
<filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MultipartFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
-- 파일 업로드
-- item table 생성
create table item(
item_id number(10) not null,
item_name VARCHAR2(150) null,
price number(10) null,
description VARCHAR2(500) null,
picture_url VARCHAR2(400) null,
CONSTRAINT pk_item PRIMARY KEY(item_id)
);
-- item sequence 생성
create sequence seq_item increment by 1 start with 1 nocache;
-- item2 table 생성
create table item2(
item_id number(10) not null,
item_name VARCHAR2(150) null,
price number(10) null,
description VARCHAR2(500) null,
picture_url VARCHAR2(400) null,
picture_url2 VARCHAR2(400) null,
CONSTRAINT pk_item2 PRIMARY KEY(item_id)
);
-- item sequence 생성
create sequence seq_item2 increment by 1 start with 1 nocache;
-- item3 table 생성
create table item3(
item_id number(10) not null,
item_name VARCHAR2(150) null,
price number(10) null,
description VARCHAR2(500) null,
CONSTRAINT pk_item3 PRIMARY KEY(item_id)
);
-- item sequence 생성
create sequence seq_item3 increment by 1 start with 1 nocache;
-- item3_attach table 생성
create table item3_attach(
fullname VARCHAR2(400) not null,
item_id number(10) not null,
regdate date not null,
CONSTRAINT pk_item3_attach PRIMARY KEY(fullname),
CONSTRAINT fk_item3_attach_item_no foreign key(item_id) references item3(item_id)
);
commit;
package kr.or.ddit.controller.file.item01;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Controller
@RequestMapping("/item")
public class FIleUploadController01 {
//@GetMapping("/register")
@RequestMapping(value = "/register", method = RequestMethod.GET)
//@PostMapping("/register")
public String itemRegisterForm(Model model) {
// 스프링 form 태그를 이용한다면, modelAttribute 속성에 연결된 item 자바 객체와의 연결을 위함
// 스프링 form 태그를 활용한다면 아래와 같이 순환체계를 연결하기 위해서 model에 데이터를 담아 클라이언트로 보낸다.
// model.addAttribute("item", new Item());
return "item/register";
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ITEM</title>
</head>
<body>
<h2>REGISTER</h2>
<form action="/item/register" method="post" enctype="multipart/form-data">
<table border="1">
<tr>
<td>상품명</td>
<td><input type="text" name="itemName" id="itemName" /></td>
</tr>
<tr>
<td>가격</td>
<td><input type="text" name="price" id="price" /></td>
</tr>
<tr>
<td>파일</td>
<td><input type="file" name="picture" id="picture" /></td>
</tr>
<tr>
<td>개요</td>
<td><textarea rows="10" cols="30" wrap="soft" name="description" id="description"></textarea></td>
</tr>
</table>
<div>
<button type="submit" id="registerBtn">Register</button>
<button type="button" id="listBtn" onclick="javascript:location.href='/item/list'">List</button>
</div>
</form>
</body>
</html>
- http://localhost/item/register
package kr.or.ddit.vo;
import org.springframework.web.multipart.MultipartFile;
import lombok.Data;
@Data
public class Item {
private int itemId;
private String itemName;
private int price;
private String description;
private MultipartFile picture;
private String pictureUrl;
}
package kr.or.ddit.controller.file.item01;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
import javax.annotation.Resource;
import javax.inject.Inject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import kr.or.ddit.service.IItemService;
import kr.or.ddit.vo.Item;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Controller
@RequestMapping("/item")
public class FIleUploadController01 {
// root-context.xml에서 설정한 uploadPath 빈등록 path 경로를 사용한다.
@Resource(name = "uploadPath")
private String resourcePath;
@Inject
private IItemService itemService;
//@GetMapping("/register")
@RequestMapping(value = "/register", method = RequestMethod.GET)
//@PostMapping("/register")
public String itemRegisterForm(Model model) {
// 스프링 form 태그를 이용한다면, modelAttribute 속성에 연결된 item 자바 객체와의 연결을 위함
// 스프링 form 태그를 활용한다면 아래와 같이 순환체계를 연결하기 위해서 model에 데이터를 담아 클라이언트로 보낸다.
// model.addAttribute("item", new Item());
return "item/register";
}
@RequestMapping(value = "/register", method = RequestMethod.POST)
public String itemRegister(Item item, Model model) throws IOException {
MultipartFile file = item.getPicture();
log.info("originalName : " + file.getOriginalFilename());
log.info("size : " + file.getSize());
log.info("contentType : " + file.getContentType());
// 넘겨 받은 파일을 이용하여 파일 업로드(복사)를 진행한다.
// return : UUID + "_" + 원본 파일명
String createdFileName = uploadFile(file.getOriginalFilename(), file.getBytes());
item.setPictureUrl(createdFileName);
itemService.register(item);
model.addAttribute("msg", "등록이 완료되었습니다.");
return "item/success";
}
private String uploadFile(String originalName, byte[] fileData) throws IOException {
UUID uuid = UUID.randomUUID(); // UUID로 파일명 생성
// UUID + "_" + 원본 파일명
String createdFileName = uuid.toString() + "_" + originalName;
File file = new File(resourcePath);
if(!file.exists()) {
file.mkdirs();
}
File target = new File(resourcePath, createdFileName); // 파일 업로드 준비
FileCopyUtils.copy(fileData, target); // 파일 복사 진행
return createdFileName;
}
}
package kr.or.ddit.service;
import kr.or.ddit.vo.Item;
public interface IItemService {
public void register(Item item);
}
package kr.or.ddit.service.impl;
import javax.inject.Inject;
import org.springframework.stereotype.Service;
import kr.or.ddit.mapper.IItemMapper;
import kr.or.ddit.service.IItemService;
import kr.or.ddit.vo.Item;
@Service
public class ItemServiceImpl implements IItemService {
@Inject
private IItemMapper mapper;
@Override
public void register(Item item) {
mapper.create(item);
}
}
package kr.or.ddit.mapper;
import kr.or.ddit.vo.Item;
public interface IItemMapper {
public void create(Item item);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="kr.or.ddit.mapper.IItemMapper">
<insert id="create" parameterType="item">
insert into item (
item_id, item_name, price, description, picture_url
) values (
seq_item.nextval, #{itemName}, #{price}, #{description}, #{pictureUrl}
)
</insert>
</mapper>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SUCCESS</title>
</head>
<body>
<h2>${msg }</h2>
<a href="/item/list">List</a>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--
[마이바티스] 스프링에서 "_"를 사용한 컬럼명 사용 시(BOOK 테이블의 BOOK_ID와 같은 컬럼)
카멜케이스로 읽어주는 역할(bookId와 같이)
ex) 테이블 컬럼명이 member_id인 경우 jsp 화면 단에서 이 값을 사용시 memberId로 사용할 수 있다.
-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<typeAliases>
<typeAlias type="kr.or.ddit.vo.Board" alias="board"/>
<typeAlias type="kr.or.ddit.vo.crud.CrudMember" alias="crudMember"/>
<typeAlias type="kr.or.ddit.vo.crud.CrudMemberAuth" alias="crudMemberAuth"/>
<typeAlias type="kr.or.ddit.vo.Item" alias="item"/>
<typeAlias type="kr.or.ddit.vo.crud.PaginationInfoVO" alias="pagingVO"/>
<typeAlias type="kr.or.ddit.vo.crud.NoticeVO" alias="noticeVO"/>
<typeAlias type="kr.or.ddit.vo.crud.NoticeFileVO" alias="noticefileVO"/>
</typeAliases>
</configuration>
- http://localhost/item/register
@RequestMapping(value = "/list", method = RequestMethod.GET)
public String itemList(Model model) {
List<Item> itemList = itemService.list();
model.addAttribute("itemList", itemList);
return "item/list";
}
package kr.or.ddit.service;
import java.util.List;
import kr.or.ddit.vo.Item;
public interface IItemService {
public void register(Item item);
public List<Item> list();
}
package kr.or.ddit.service.impl;
import java.util.List;
import javax.inject.Inject;
import org.springframework.stereotype.Service;
import kr.or.ddit.mapper.IItemMapper;
import kr.or.ddit.service.IItemService;
import kr.or.ddit.vo.Item;
@Service
public class ItemServiceImpl implements IItemService {
@Inject
private IItemMapper mapper;
@Override
public void register(Item item) {
mapper.create(item);
}
@Override
public List<Item> list() {
return mapper.list();
}
}
package kr.or.ddit.mapper;
import java.util.List;
import kr.or.ddit.vo.Item;
public interface IItemMapper {
public void create(Item item);
public List<Item> list();
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="kr.or.ddit.mapper.IItemMapper">
<insert id="create" parameterType="item">
insert into item (
item_id, item_name, price, description, picture_url
) values (
seq_item.nextval, #{itemName}, #{price}, #{description}, #{pictureUrl}
)
</insert>
<select id="list" resultType="item">
select
item_id, item_name, price, description, picture_url
from item
order by item_id desc
</select>
</mapper>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ITEM</title>
</head>
<body>
<h2>LIST</h2>
<a href="/item/register">상품 등록</a>
<hr />
<table border="1">
<tr>
<th width="80">상품 ID</th>
<th width="320">상품명</th>
<th width="100">가격</th>
<th width="80">편집</th>
<th width="80">제거</th>
</tr>
<c:choose>
<c:when test="${empty itemList }">
<tr>
<td colspan="5">조회하신 게시글이 존재하지 않습니다.</td>
</tr>
</c:when>
<c:otherwise>
<c:forEach items="${itemList }" var="item">
<tr>
<td align="center">${item.itemId }</td>
<td align="left">${item.itemName }</td>
<td align="right">${item.price }원</td>
<td align="center">
<a href="/item/modify?itemId=${item.itemId }">상품편집</a>
</td>
<td align="center">
<a href="/item/remove?itemId=${item.itemId }">상품제거</a>
</td>
</tr>
</c:forEach>
</c:otherwise>
</c:choose>
</table>
</body>
</html>
- http://localhost/item/list
@RequestMapping(value = "/modify", method = RequestMethod.GET)
public String itemModifyForm(int itemId, Model model) {
Item item = itemService.read(itemId);
model.addAttribute("item", item);
return "item/modify";
}
package kr.or.ddit.service;
import java.util.List;
import kr.or.ddit.vo.Item;
public interface IItemService {
public void register(Item item);
public List<Item> list();
public Item read(int itemId);
}
package kr.or.ddit.service.impl;
import java.util.List;
import javax.inject.Inject;
import org.springframework.stereotype.Service;
import kr.or.ddit.mapper.IItemMapper;
import kr.or.ddit.service.IItemService;
import kr.or.ddit.vo.Item;
@Service
public class ItemServiceImpl implements IItemService {
@Inject
private IItemMapper mapper;
@Override
public void register(Item item) {
mapper.create(item);
}
@Override
public List<Item> list() {
return mapper.list();
}
@Override
public Item read(int itemId) {
return mapper.read(itemId);
}
}
package kr.or.ddit.mapper;
import java.util.List;
import kr.or.ddit.vo.Item;
public interface IItemMapper {
public void create(Item item);
public List<Item> list();
public Item read(int itemId);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="kr.or.ddit.mapper.IItemMapper">
<insert id="create" parameterType="item">
insert into item (
item_id, item_name, price, description, picture_url
) values (
seq_item.nextval, #{itemName}, #{price}, #{description}, #{pictureUrl}
)
</insert>
<select id="list" resultType="item">
select
item_id, item_name, price, description, picture_url
from item
order by item_id desc
</select>
<select id="read" parameterType="int" resultType="item">
select
item_id, item_name, price, description, picture_url
from item
where item_id = #{itemId}
</select>
</mapper>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ITEM</title>
</head>
<body>
<h2>MODIFY</h2>
<form action="/item/modify" method="post" enctype="multipart/form-data">
<input type="hidden" name="itemId" value="${item.itemId }" />
<input type="hidden" name="pictureUrl" value="${item.pictureUrl }" />
<table border="1">
<tr>
<td>상품명</td>
<td><input type="text" name="itemName" id="itemName" value="${item.itemName }" /></td>
</tr>
<tr>
<td>가격</td>
<td><input type="text" name="price" id="price" value="${item.price }" /></td>
</tr>
<tr>
<td>파일</td>
<td>
<img alt="파일 이미지" src="/item/display?itemId=${item.itemId }" width="210", height="240">
</td>
</tr>
<tr>
<td>파일</td>
<td><input type="file" name="picture" id="picture" /></td>
</tr>
<tr>
<td>개요</td>
<td><textarea rows="10" cols="30" wrap="soft" name="description" id="description">${item.description }</textarea></td>
</tr>
</table>
<div>
<button type="submit" id="modifyBtn">Modify</button>
<button type="button" id="listBtn" onclick="javascript:location.href='/item/list'">List</button>
</div>
</form>
</body>
</html>
@ResponseBody
@RequestMapping(value = "/display")
public ResponseEntity<byte[]> displayFile(int itemId) {
InputStream in = null;
ResponseEntity<byte[]> entity = null;
// itemId에 해당하는 이미지 파일명을 얻어온다.
String fileName = itemService.getPicture(itemId);
log.info("fileName : " + fileName);
try {
String formatName = fileName.substring(fileName.lastIndexOf(".") + 1); // 확장자 추출
MediaType mType = getMediaType(formatName);
HttpHeaders headers = new HttpHeaders();
in = new FileInputStream(resourcePath + File.separator + fileName);
if(mType != null) {
headers.setContentType(mType);
}
entity = new ResponseEntity<byte[]>(IOUtils.toByteArray(in), headers, HttpStatus.CREATED);
} catch (Exception e) {
e.printStackTrace();
entity = new ResponseEntity<byte[]>(HttpStatus.BAD_REQUEST);
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return entity;
}
// 추출된 확장자를 통한 Mime 타입 결정
private MediaType getMediaType(String formatName) {
if(formatName != null) {
if(formatName.toUpperCase().equals("JPG")) {
return MediaType.IMAGE_JPEG;
}
if(formatName.toUpperCase().equals("GIF")) {
return MediaType.IMAGE_GIF;
}
if(formatName.toUpperCase().equals("PNG")) {
return MediaType.IMAGE_PNG;
}
}
return null;
}
package kr.or.ddit.service;
import java.util.List;
import kr.or.ddit.vo.Item;
public interface IItemService {
public void register(Item item);
public List<Item> list();
public Item read(int itemId);
public String getPicture(int itemId);
}
package kr.or.ddit.service.impl;
import java.util.List;
import javax.inject.Inject;
import org.springframework.stereotype.Service;
import kr.or.ddit.mapper.IItemMapper;
import kr.or.ddit.service.IItemService;
import kr.or.ddit.vo.Item;
@Service
public class ItemServiceImpl implements IItemService {
@Inject
private IItemMapper mapper;
@Override
public void register(Item item) {
mapper.create(item);
}
@Override
public List<Item> list() {
return mapper.list();
}
@Override
public Item read(int itemId) {
return mapper.read(itemId);
}
@Override
public String getPicture(int itemId) {
return mapper.getPicture(itemId);
}
}
package kr.or.ddit.mapper;
import java.util.List;
import kr.or.ddit.vo.Item;
public interface IItemMapper {
public void create(Item item);
public List<Item> list();
public Item read(int itemId);
public String getPicture(int itemId);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="kr.or.ddit.mapper.IItemMapper">
<insert id="create" parameterType="item">
insert into item (
item_id, item_name, price, description, picture_url
) values (
seq_item.nextval, #{itemName}, #{price}, #{description}, #{pictureUrl}
)
</insert>
<select id="list" resultType="item">
select
item_id, item_name, price, description, picture_url
from item
order by item_id desc
</select>
<select id="read" parameterType="int" resultType="item">
select
item_id, item_name, price, description, picture_url
from item
where item_id = #{itemId}
</select>
<select id="getPicture" parameterType="int" resultType="string">
select picture_url
from item
where item_id = #{itemId}
</select>
</mapper>
- http://localhost/item/modify?itemId=2
@RequestMapping(value = "/modify", method = RequestMethod.POST)
public String itemModify(Item item, Model model) throws Exception {
MultipartFile file = item.getPicture();
if(file != null && file.getSize() > 0) {
log.info("originalName : " + file.getOriginalFilename());
log.info("size : " + file.getSize());
log.info("contentType : " + file.getContentType());
String createdFileName = uploadFile(file.getOriginalFilename(), file.getBytes());
item.setPictureUrl(createdFileName);
}
itemService.modify(item);
model.addAttribute("msg", "수정이 완료되었습니다.");
return "item/success";
}
package kr.or.ddit.service;
import java.util.List;
import kr.or.ddit.vo.Item;
public interface IItemService {
public void register(Item item);
public List<Item> list();
public Item read(int itemId);
public String getPicture(int itemId);
public void modify(Item item);
}
package kr.or.ddit.service.impl;
import java.util.List;
import javax.inject.Inject;
import org.springframework.stereotype.Service;
import kr.or.ddit.mapper.IItemMapper;
import kr.or.ddit.service.IItemService;
import kr.or.ddit.vo.Item;
@Service
public class ItemServiceImpl implements IItemService {
@Inject
private IItemMapper mapper;
@Override
public void register(Item item) {
mapper.create(item);
}
@Override
public List<Item> list() {
return mapper.list();
}
@Override
public Item read(int itemId) {
return mapper.read(itemId);
}
@Override
public String getPicture(int itemId) {
return mapper.getPicture(itemId);
}
@Override
public void modify(Item item) {
mapper.update(item);
}
}
package kr.or.ddit.mapper;
import java.util.List;
import kr.or.ddit.vo.Item;
public interface IItemMapper {
public void create(Item item);
public List<Item> list();
public Item read(int itemId);
public String getPicture(int itemId);
public void update(Item item);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="kr.or.ddit.mapper.IItemMapper">
<insert id="create" parameterType="item">
insert into item (
item_id, item_name, price, description, picture_url
) values (
seq_item.nextval, #{itemName}, #{price}, #{description}, #{pictureUrl}
)
</insert>
<select id="list" resultType="item">
select
item_id, item_name, price, description, picture_url
from item
order by item_id desc
</select>
<select id="read" parameterType="int" resultType="item">
select
item_id, item_name, price, description, picture_url
from item
where item_id = #{itemId}
</select>
<select id="getPicture" parameterType="int" resultType="string">
select picture_url
from item
where item_id = #{itemId}
</select>
<update id="update" parameterType="item">
update item
set
item_name = #{itemName},
price = #{price},
description = #{description},
picture_url = #{pictureUrl}
where item_id = #{itemId}
</update>
</mapper>
- http://localhost/item/modify?itemId=3
@RequestMapping(value = "/remove", method = RequestMethod.GET)
public String itemRemoveForm(int itemId, Model model) {
Item item = itemService.read(itemId);
model.addAttribute("item", item);
return "item/remove";
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ITEM</title>
</head>
<body>
<h2>REMOVE</h2>
<form action="/item/remove" method="post">
<input type="hidden" name="itemId" value="${item.itemId }" />
<table border="1">
<tr>
<td>상품명</td>
<td><input type="text" name="itemName" id="itemName" value="${item.itemName }" disabled="disabled" /></td>
</tr>
<tr>
<td>가격</td>
<td><input type="text" name="price" id="price" value="${item.price }" disabled="disabled" /></td>
</tr>
<tr>
<td>파일</td>
<td>
<img alt="파일 이미지" src="/item/display?itemId=${item.itemId }" width="210", height="240">
</td>
</tr>
<tr>
<td>개요</td>
<td><textarea rows="10" cols="30" wrap="soft" name="description" id="description" disabled="disabled">${item.description }</textarea></td>
</tr>
</table>
<div>
<button type="submit" id="removeBtn">Remove</button>
<button type="button" id="listBtn" onclick="javascript:location.href='/item/list'">List</button>
</div>
</form>
</body>
</html>
- http://localhost/item/remove?itemId=3
@RequestMapping(value = "/remove", method = RequestMethod.POST)
public String itemRemove(int itemId, Model model) {
itemService.remove(itemId);
model.addAttribute("msg", "삭제가 완료되었습니다.");
return "item/success";
}
package kr.or.ddit.service;
import java.util.List;
import kr.or.ddit.vo.Item;
public interface IItemService {
public void register(Item item);
public List<Item> list();
public Item read(int itemId);
public String getPicture(int itemId);
public void modify(Item item);
public void remove(int itemId);
}
package kr.or.ddit.service.impl;
import java.util.List;
import javax.inject.Inject;
import org.springframework.stereotype.Service;
import kr.or.ddit.mapper.IItemMapper;
import kr.or.ddit.service.IItemService;
import kr.or.ddit.vo.Item;
@Service
public class ItemServiceImpl implements IItemService {
@Inject
private IItemMapper mapper;
@Override
public void register(Item item) {
mapper.create(item);
}
@Override
public List<Item> list() {
return mapper.list();
}
@Override
public Item read(int itemId) {
return mapper.read(itemId);
}
@Override
public String getPicture(int itemId) {
return mapper.getPicture(itemId);
}
@Override
public void modify(Item item) {
mapper.update(item);
}
@Override
public void remove(int itemId) {
mapper.delete(itemId);
}
}
package kr.or.ddit.mapper;
import java.util.List;
import kr.or.ddit.vo.Item;
public interface IItemMapper {
public void create(Item item);
public List<Item> list();
public Item read(int itemId);
public String getPicture(int itemId);
public void update(Item item);
public void delete(int itemId);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="kr.or.ddit.mapper.IItemMapper">
<insert id="create" parameterType="item">
insert into item (
item_id, item_name, price, description, picture_url
) values (
seq_item.nextval, #{itemName}, #{price}, #{description}, #{pictureUrl}
)
</insert>
<select id="list" resultType="item">
select
item_id, item_name, price, description, picture_url
from item
order by item_id desc
</select>
<select id="read" parameterType="int" resultType="item">
select
item_id, item_name, price, description, picture_url
from item
where item_id = #{itemId}
</select>
<select id="getPicture" parameterType="int" resultType="string">
select picture_url
from item
where item_id = #{itemId}
</select>
<update id="update" parameterType="item">
update item
set
item_name = #{itemName},
price = #{price},
description = #{description},
picture_url = #{pictureUrl}
where item_id = #{itemId}
</update>
<delete id="delete" parameterType="int">
delete from item
where item_id = #{itemId}
</delete>
</mapper>
- http://localhost/item/remove?itemId=3
'대덕인재개발원_웹기반 애플리케이션' 카테고리의 다른 글
231201_SPRING 2 (과제 1) (0) | 2023.12.01 |
---|---|
231201_SPRING 2 (8-2) (0) | 2023.12.01 |
231130_SPRING 2 (7-3) (0) | 2023.11.30 |
231130_SPRING 2 (7-2) (0) | 2023.11.30 |
231130_SPRING 2 (7-1) (1) | 2023.11.30 |