프로젝트 외부에 업로드한 파일 불러오기

 

 

# WebConfig.java

import java.util.Arrays;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.resource.PathResourceResolver;
import lombok.RequiredArgsConstructor;

/******************************************************************
 * <pre>
 * <b>Description  : WebMvc 설정</b>
 * <b>Project Name : </b>
 * package  : com.***.config
 *******************************************************************/

@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {

	private final ConfigProperty configProperty;
	
	/**
	 * application.yml - 파일저장경로 참조
	 */
	@Value("${spring.servlet.multipart.location}")
	private String uploadImagePath;
		

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {

		registry.addResourceHandler("/js/**")
				.addResourceLocations("classpath:/static/js/");
		registry.addResourceHandler("/css/**")
				.addResourceLocations("classpath:/static/css/");
		registry.addResourceHandler("/img/**")
				.addResourceLocations("classpath:/static/img/");
		registry.addResourceHandler("/fonts/**")
				.addResourceLocations("classpath:/static/fonts/");
		registry.addResourceHandler("/data/**")
				.addResourceLocations("classpath:/static/data/");
		registry.addResourceHandler("/")
				.addResourceLocations("classpath:/static/index.html");
		
		// 업로드 이미지용 외부 폴더 추가
		registry.addResourceHandler("/upload/**")
		  .addResourceLocations("file:///"+uploadImagePath)    // 웹에서 이미지 호출시 'file:///' 설정됨
          .setCachePeriod(3600)
		  .resourceChain(true)
          .addResolver(new PathResourceResolver());
		  

	}

	@Bean
	public MappingJackson2HttpMessageConverter jackson2HttpMessageConverter() {
		MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
		converter.setDefaultCharset(Constants.DEFAULT_SERVER_STANDARD_CHARSET);
		return converter;
	}

	@Override
	public void addCorsMappings(CorsRegistry registry) {
		if (configProperty.isLocalProfiles()) {
			registry.addMapping("/**").allowedOrigins("*")
					.allowedMethods(Arrays.asList(HttpMethod.values()).stream()
							.map(method -> method.name())
							.collect(Collectors.toList()).stream()
							.toArray(size -> new String[size]))
					.allowCredentials(false).maxAge(3600);
		}
	}
}

 

# /application.yml

# default properties
spring:
  application:
    name: "indiman"
  profiles:
    active: local
  servlet:    #파일 업로드 추가 
    multipart:
      file-size-threshold: 1MB
      # 아래중에 본인 환경에 맞춰서 하자. (외부경로)      
      # location: /var/inde/uploads/                #ex > linux Server 777      
      # location: C:/inde/workspace/inde/uploads/   #ex > local  
      max-file-size: 100MB
      max-request-size: 100MB    

 

# 화면

<img src="/upload/IM004/1586857683470.jpg"/>
<img v-bind:src="dbInfo.urlInfo" />
<img v-bind:src="'/upload/' + dbInfo.fileinfo" />


 

 

 

개발용 Vue로컬서버 에서는 # WebConfig.java 적용이 안된다 반드시 빌드후 개발용 서버주소에서 활용하자.

#vue.js

#modal Popup


 

1. HTML  영역 예

<!-- // QnA 수정 팝업 예-->
		<b-modal id="mdfyPop"
			  ref="modal"
		      title="QnA 수정"
		      @show="resetModal"
		      @hidden="resetModal"
		      @ok="handleOk">
		    <form ref="form" @submit.stop.prevent="handleSubmit" >
		    	<div class="modal-body" >
			        
                    <b-form-group	
			        		:state="nameState"
			          		label="질문입력"
			           		label-for="name-input"
			          		invalid-feedback="질문을 입력하세요.">
			        	<b-form-input id="name-input"
			           		   		  v-model="qna.sj"
			            			  :state="nameState" required>
			        	</b-form-input>
			        </b-form-group>
                    
			        <b-form-group	
			        		:state="nameState"
			          		label="답변입력란"
			           		label-for="name-input"
			          		invalid-feedback="답변을 입력하세요.">
			        	<b-form-input id="name-input"
			           		 v-model="qna.cn"
			            	 :state="nameState" required>
			       		</b-form-input>
			        </b-form-group>
			    </div>
	        </form>
		</b-modal>

 

2.Script

 // Methods 
    methods: {        
        // Modal PopUp Event
        resetModal() {
          this.name = ''
          this.nameState = null
        },
        handleOk(bvModalEvt) {
          // Prevent modal from closing
          bvModalEvt.preventDefault()
          // Trigger submit handler
          this.handleSubmit()
        },
        checkFormValidity() {
          const valid = this.$refs.form.checkValidity()
          this.nameState = valid
          return valid
        },
        handleSubmit() {
          // Exit when the form isn't valid
          if (!this.checkFormValidity()) {
            return
          }
          // Push the name to submitted names
          this.submittedNames.push(this.name)
          // Hide the modal manually
          /* this.$nextTick(() => {
            // this.$bvModal.hide('addQna')
          }) */                    
        }       
        
    }

 

3.Popup Open

this.$refs['modal'].show()    // PopUp Open

 

4. 추가

팝업 위치가 위쪽이라 메뉴를 가려서 스타일도 추가 -> 모달팝업 아이디 확인후 Style 추가함.

/* 모달 팝업 스타일 MOD*/
<style>
#mdfyPop___BV_modal_content_ { margin-top: 100px; }
</style>

 

5. 짠.

 

 

 

준비물
#SpringBoot
#vue.js
#axios
#formData

#application.yml

 

 


1. application.yml 에다가 아래처럼 선언해주시고

default properties
	spring:
		application:
		name: "project"
		profiles:
		active: local
	servlet: # 파일업로드 추가
		multipart:
		file-size-threshold: 1MB
		location: C:/경로 ****/frontend/public/upload/
		max-file-size: 100MB
		max-request-size: 100MB

 

 

2. 화면

- ** Html태그에서 multipart/어쩌구 form 으로 감싸줄필요 없음, Json 형태라 그냥 아래서 formData 로 변환

 

<dl class="option_list clfix">
	<dt>
		<span>이미지업로드</span>
	</dt>
<dd>
<div class="input-container">
	<input v-on:change="$fileSelect()" type="file" ref="imgFile"  />
</div>

 

3. 스크립트 

// 파일 첨부시 Change이벤트
$fileSelect : function $fileSelect(){
	this.scndhandReg.imgFile = this.$refs.imgFile.files[0];
}


// 저장전. 밸리데이션 체크하는 로직,, 필요에 따라서,,사용
$beforeSave : function $beforeSave () {
	const _this = this;
	_this.$validator.validateAll().then((isValid) => {
	if(isValid){
		if(commonUtils.$confirm('신청하시겠습니까?')){
			this.scndhandReg.area = this.scndhandReg.local;            
			_this.$executeSave();    // 저장**            
                }
            } else {
                commonUtils.$alertValidationError(_this.$validator);
            }
        });
    },
    
    
// 저장
$executeSave : function $executeSave () {

        const url = constant.boardFoHost + '/scndH경로(예)dManage/v1.0.0/scnd경로(예)anage';    // ex 컨트롤러 Post경로 


        // Object To FormData 변환
        var formData = new FormData();
        formData.append("sj"        , this.scndhandReg.sj);         // 컨트롤러 넘길 정보 예 1
        formData.append("area"        , this.scndhandReg.area);     // 컨트롤러 넘길 정보 예 2            
        // 이미지 
        if(this.scndhandReg.imgFile != ""){                    
            formData.append("imgFile"    , this.scndhandReg.imgFile);    // 이미지 파일 ^^
        }


        // 파일업로드시 (경로,FormData,Header) 설정       
        this.$axios.post(url, formData, { headers: {'Content-Type': 'multipart/form-data'}}).then(
                 response => {
            if(!!response && response.status === 200){
            
                commonUtils.$alert('감사합니다.\n정상등록되었습니다.');
                this.scndhandReg = Object.assign({}, this.defScndhangReg);

            }
        }).catch( error => {
        console.log(error);
            commonUtils.$alertUncatchedError(error);
        });
    },

 

 

4. 컨트롤러 

-- @ModelAttribute ScndHandManage 형태로 받는다,

@PostMapping("/v1.0.0/scndHandManage")
public ResponseEntity insertScndHandManage(
		@ModelAttribute ScndHandManage scndHandManage){
		return ResponseUtils.createSuccessResponseEntity(this.scndHandManageService.insertScndHandManage(scndHandManage));
}

 

5. 모델 객체

private String sj;
private String area;
private MultipartFile imgFile; // 이미지 파일도 받을수 있게 하나 추가 해주고 **

 

5. 임플

 

// Impl 상단에
@Value("${spring.servlet.multipart.location}")
private String FILE_PATH;
// 선언 해주면 위 application.yml에 선언된 경로 참조한다.



Path path = Paths.get(FILE_PATH + scndHandManage.getImgFile().getOriginalFilename()); // Save Path 생성
scndHandManage.getImgFile().transferTo(path); // 업로드



 

6. 화면에서 불러오기 

 

<img class="product-thumb" v-bind:src="'/upload/'+scndhand.urlInfo" />

이미지 저장경로는 보통 favicon.ico 와 index.html 이 있는 

public 폴더안에 upload 폴더를 생성하였고 (application.yml 참고)

 

 

다른곳에 이미지 저장후 불러오려면 설정을 해야된다. 그건 다음에....

 

 

 

 

 

 

 

 

+ Recent posts