Axios 라이브러리
자바스크립트에서 사용하는 HTTP 클라이언트 라이브러리이다.
비동기통신을 할 때 사용하는 라이브러리이다.
Ajax 와 더불어서 많이 사용하는 라이브러리인데 내가 배운건 Axios 이기 때문에 앞으로는
이쪽을 사용해서 프로젝트를 진행하게 될 것 같다.
(언젠간 Ajax 도 배워야겠지..? )
Axios 사용법
우선 구글에 axios cdn 을 검색한다. 그리고
cdnjs 라는 사이트에 있는 axios 를 검색.
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.7.7/axios.js"
integrity="sha512-luUnkeG+uabiT2pZdi5ME5uADvq+FpDs2fK5V0nVXrHCND9F077fKaE9W//oJvGnWSmwQmCau63A6s3um1NZmg=="
crossorigin="anonymous"
referrerpolicy="no-referrer"></script>
사용하고자 하는 jsp 페이지에 axios 를 사용할 수 있게 추가해준다.
사용
<div class="put">
<h6>[UPDATE]비동기 PUT 요청</h6>
<form name="axiosAsyncPutForm" method="" action=""
onsubmit="return false">
<input name="id" placeholder="id" /> <input name="text"
placeholder="text" /> <input name="writer" placeholder="text" />
<button class="axiosAsyncPutBtn">전송</button>
</form>
</div>
jsp 페이지에 이렇게 put 요청을 하는 버튼을 만들었다.
/* put */
const btn3 = document.querySelector('.axiosAsyncPutBtn'); //버튼 불러오기
btn3.addEventListener('click',function(){ //클릭 이벤트처리
const form1 = document.axiosAsyncPutForm;
const id = form1.id.value; //id 내용
const text = form1.text.value; //text 내용
const writer = form1.writer.value; //writer 내용
console.log(id,text,writer);
console.log('clicked');
const data = {id:id,text:text,writer:writer}; //키 - 값 구조 data 생성
const headers = {"Content-type":"application/json"};
axios.put(projectPath+'/memo/put',data,{headers,}) //axios memo/put 요청을 받을시
.then( resp=>{ //요청성공시. //서버로 전송데이터 data , header 추가 설정
console.log(resp);
const resultBlock = document.querySelector('.result .body')
while(resultBlock.firstChild){
resultBlock.removeChild(resultBlock.firstChild);
}
resultBlock.innerHTML = "비동기 Put...!" +resp.data;
})
.catch( err=>{console.log(err); })
})
이런식으로 axios 를 사용해서 비동기 방식으로 put 요청을 함.
@PutMapping(value="/put",consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
public ResponseEntity<Boolean> update_put(@RequestBody MemoDto memoDto) { //@RequestBody 로 실려 나온다.
log.info("put mapping.. /memo/put"+memoDto);
boolean isUpdate= memoServiceImpl.memoUpdate_patch(memoDto); //유효성 검사를 위해 boolean 에 결과값 저장
return isUpdate? new ResponseEntity(isUpdate,HttpStatus.OK) : new ResponseEntity(isUpdate,HttpStatus.BAD_REQUEST);
// return new ResponseEntity("okokk!!",HttpStatus.OK); ResponseEntity<String>이라는 반환형에 해도 되긴 하던데 ?
}
axios 전에 controller 가 실행되고 그 다음 데이터가 axios 로 전달된다.
비동기 처리 방식에는 axios 말고도 방식이 더 있는데 ,
- axios
- xhr
- jquery
- ajax
나중에 알아보도록 하자..
servlet-context.xml 대체하기
servlet-context.xml 파일을 대체해서 직접 config 를 통해 만들어보았다.
@EnableWebMvc 어노테이션을 통해 servlet-context.xml 파일처럼 취급한다.
(일단은 간단하게 이렇게만 이해하자.)
@Configuration
@EnableWebMvc
@ComponentScans({
@ComponentScan("com.example.ex01.controller"),
@ComponentScan("com.example.ex01.restController"),
})
public class WebMVCConfig implements WebMvcConfigurer{
@Bean
public ViewResolver viewResolver() { // 뷰 리졸버 직접 만들기
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
스프링부트로 넘어가면 xml 파일은 잘 사용하지 않는다고함.
그래서 이런 servlet-context.xml 파일 주석처리후 직접 viewResolver 를 만들어줌.
<resources mapping="/resources/**" location="/resources/" />
<resources mapping="/resources/**" location="/resources/" /> **가 모든 파일을 매핑하겠다는뜻
WEB-INF 폴더 안의 파일들은 web에 관련된 정보가 있는 파일들이기 때문에 직접적으로 접근을 할 수는 없고 Controller 를 통해서만 접근이가능하다. 그렇기 때문에 보안성이 높다.
webapp 폴더는 비즈니스 로직 없이도 직접 뷰에 접근하여 내용을 볼 수 있다.
대신 보안에는 취약함 !!
공개되어도 상관없는 정적자원들은 바깥(wabapp)폴더에 넣어두어도 무방함.
파일 업다운로드할 때 DB 저장방식 , 프로젝트 안 저장방식(권장안함)
파일 입출력(IO)
웹에서 파일을 다운받거나 업로드 할 때가 있다.
이 때 스프링에서 설정을 하려면 몇가지 라이브러리와 코드를 구현해야한다.
<!-- FILE UP/DOWNLAOD -->
<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
파일 업/다운 로드에 필요한 라이브러리인 Apache common 라이브러리를 추가해준다.
(2가지 추가해주어야함)
common-fileupload 는 업로드를 위한 라이브러리
commos-io 는 파일을 읽기 , 쓰기 , 삭제 , 복사 등 파일을 다루는데 필요한 라이브러리이다.
간단하게만 코드를 살펴보자.
그 전에 ! 우선 설정.
@Bean
public MultipartResolver multipartResolver() {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(1024*1024*10*2); //전체 업로드 허용 사이즈 20MB
multipartResolver.setMaxUploadSizePerFile(1024*1024*10*2); //파일 1개당 허용가능한 업로드 20MB
multipartResolver.setMaxInMemorySize(1024*1024*10*2); // 캐시 공간
return multipartResolver;
}
파일의 크기를 지정하는 멀티파트 Resolver. (Config에 설정했다.)
@PostMapping("/upload")
public void upload_post(@RequestParam("file") MultipartFile file) throws IllegalStateException, IOException {
log.info("POST /file/upload..."+file);
log.info(file.getOriginalFilename());
log.info(file.getSize()+" byte");
//폴더생성
String dir = UPLOAD_PATH+File.separator+UUID.randomUUID();
File dirPath = new File(dir);
if(!dirPath.exists())
dirPath.mkdirs();
//파일명 추출
String filename = file.getOriginalFilename();
//파일객체 생성
File fileObject = new File(dir,filename);
//업로드 처리
file.transferTo(fileObject);
}
POST 요청을 받아 데이터를 보낼 시에 파일을 생성해서 데이터로 보낸다.
AOP 란 ??
AOP는 관점(Aspect)지향 프로그래밍으로, 관점을 기준으로 다양한 기능을 분리하여 보는 프로그래밍이다. 관점(Aspect)이란, 부가 기능과 그 적용처를 정의하고 합쳐서 모듈로 만든 것이다.
= 프로젝트 할 때 그다지 중요하지 않은 코드를 여기서 처리함. 중요코드는 서비스로직에서 처리
👉 AOP의 목적
OOP와 이름이 비슷하여 상반된 개념 같지만, 관점지향 프로그래밍은 객체지향 프로그래밍을 보완하기 위해 쓰인다. 기존 객체(Object) 지향은 목적에 따라 클래스를 만들고 객체를 만들었다. 따라서 핵심 비즈니스 로직이든, 부가 기능의 로직이든 하나의 객체로 분리하는데 그치고, 그래서 이 기능들을 어떻게 바라보고 나눠쓸지에 대한 정의가 부족하다는 단점이 있다.
보통 비즈니스 웹 애플리케이션이라면 사업에 핵심적인 핵심 비즈니스 로직이 있고, 애플리케이션 전체를 관통하는 부가 기능 로직이 있다. 이를 횡단 관심사(cross-cutting concerns)라고 한다. (종류는 로깅, 보안, 트랜젝션이 있다.)
횡단 관심사의 코드를 핵심 비즈니스 로직의 코드와 분리하여, 코드의 간결성을 높이고 변경에 유연함과 무한한 확장이 가능하도록 하는 것이 AOP의 목적이다.
package com.example.ex01.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
@Component
@Slf4j
@Aspect
public class LoggingAdvice {
//포인트컷 표현식
//"execution(* com.example.ex01.domain.service.simpleServiecImpl.get1())"
// execution : 메서드 실행
// * : 모든 리턴 타입
// com.example.ex01.domain.service.simpleServiecImpl.get1() : 함수명
@Before("execution(* com.example.ex01.domain.service.MemoServiceImpl.memoAddTx(..))") // 파라미터 .. 은 파라미터가 어떤 것이든 상관없다는 뜻
public void loggingBefore(JoinPoint joinPoint) {
log.info("[AOP] BEFORE : " + joinPoint);
}
@After("execution(* com.example.ex01.domain.service.MemoServiceImpl.getMemos())") //service함수 지정
public void loggingAfter(JoinPoint joinPoint) {
log.info("AOP BEFORE " + joinPoint); //함수 실행전 로깅
log.info("AFTER.." + joinPoint.getTarget()); // 대상 객체 반환
log.info("AFTER.." + joinPoint.getSignature()); //불러오는 경로명
log.info("AFTER.." + joinPoint.getSignature().getName()); //함수명
}
@Around("execution(* com.example.ex01.domain.service.*.*(..))")
public Object loggingAround(ProceedingJoinPoint pip) throws Throwable {
//이전시점
log.info("AOP AROUND BEFORE");
long startTime = System.currentTimeMillis();
//MVC 흐름대로 진행
Object isUpdate =(Object)pip.proceed();
//이후시점
log.info("AOP AROUND AFTER");
long endTime = System.currentTimeMillis();
log.info("[AOP] TIME : " + (endTime-startTime)+ "ms");
return isUpdate;
}
}
'Developer Note > 국비과정 수업내용 정리&저장' 카테고리의 다른 글
24년 11월 19일 (1) | 2024.11.25 |
---|---|
24년 11월 18일 (0) | 2024.11.24 |
24년 11월 14일 (0) | 2024.11.24 |
24년 11월 13일 (0) | 2024.11.24 |
24년 11월 12일 (0) | 2024.11.22 |