웹_프론트_백엔드/JAVA프레임윅기반_풀스택

2020.06.23

shine94 2020. 6. 23. 10:52

1. Maven 빌드시 손상된 Jar 파일 확인(corrupted jar check), 손상된 jar 파일 다운

** com.jar.validator > JarValidator.java

package com.jar.validator;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.jar.JarFile;
import java.util.stream.Collectors;

/*
 * Maven 빌드시 손상된 Jar 파일 확인(corrupted jar check)
 * 
 * 손상된 jar 파일의 경우 다운로드 시도
 * 
 * 다운로드 받은 후 해당 Maven 프로젝트들은 update 해주세요
 * 
 */

public class JarValidator {
	
	private static final String URL_MAVEN2 = "https://repo1.maven.org/maven2";

	private static Path repositoryPath = null;
	
	public static void main(String[] args) throws IOException{
		// 사용자 폴더 밑의 repository 경로
		repositoryPath = Paths.get(System.getProperty("user.home"), ".m2", "repository");
		
		//System.out.println(repositoryPath);
		
		// repository 경로 존재 여부 확인
		if(Files.exists(repositoryPath)) {
			
			JarValidator jv = new JarValidator();
			
			List<Path> jarFiles = jv.getFiles(repositoryPath, ".jar");
			System.out.println("발견된 전체 jar 파일들 : " + jarFiles.size() + " 개");
			
//			for(Path p : jarFiles) {
//				System.out.println(p);
//			}
			
			jv.openJars(jarFiles);
			
			
		} else {
			// repository 경로가 없으면
			System.out.println("Repository path " + repositoryPath + " 경로가 없습니다");
		}
		
	} // end main()

	/**
	 * 주어진 경로에서 부터 시작하여 모든 이하 디렉토리들을 검색하여, 주어진 확장자에 일치하는 파일들의 목록 만들기.
	 * @param filePath      : File의 절대경로
	 * @param fileExtension : 검색할 파일의 확장자 
	 * @return  디렉토리 내에 있는 모든 파일들의 List 
	 */
	private List<Path> getFiles(Path filePath, String fileExtension) throws IOException{
		return Files.walk(filePath)  // filePath 부터 시작하여 이하 모든 파일들 검색
			.filter(p -> p.toString().endsWith(fileExtension)) // 그중에서 특정 확장자 가진것만 골라내서
			.collect(Collectors.toList());  // List로 모음.
	} // end getFiles()
	
	
	private List<String> openJars(List<Path> jarFiles) {
		
		int[] badJars = {0};	// 손상된 jar 파일 개수
								// 굳이 배열인 이유는 local inner에서 사용하기 위해
		
		// 각각의 jar 파일에 대해 아래 수행
		jarFiles.forEach(path -> {
			String absPath = path.toAbsolutePath().toString();	// jar 파일 절대 경로
			
			try {
				JarFile file = new JarFile(path.toString());	// jar 파일 open 시도
				
			} catch (IOException e) {	// ★ jar 파일 open, 실패하면 IOException 발생
				String errMsg = "손상된 jar 발견 : " + absPath + "--exception:" + e.toString();
				System.out.println(errMsg);
				badJars[0]++;	// 손상된 jar 파일 개수 증가
				
				// 다운로드 시도
				String downloadUrl = URL_MAVEN2 + absPath.substring(repositoryPath.toString().length()).replaceAll("\\\\", "/");
				//System.out.println(downloadUrl);
				
				try {
					download(downloadUrl, absPath);
				} catch (IOException ex) {
					System.out.println("다운로드 실패");
				}
			}
		});
		
		System.out.println("손상된 jar 파일 개수 = " + badJars[0]);
		
		return null;
		
	} // end openJars()
	
	/**
	 * 특정 url의 파일 다운로드
	 * @param srcUrl	: 다운로드 받을 파일의 url
	 * @param dstFile	: 다운받아 저장할 파일 경로
	 * @throws IOException
	 */
	public void download(String srcUrl, String dstFile) throws IOException{
		URL url = null;
		HttpURLConnection conn = null;
		InputStream in = null;
		BufferedInputStream bin = null;
		FileOutputStream out = null;
		BufferedOutputStream bout = null;
		
		try {
			System.out.println("다운로드 시도..." + srcUrl + "\n\t → " + dstFile);
			
			url = new URL(srcUrl);
			conn = (HttpURLConnection) url.openConnection();
			int contentLength = conn.getContentLength();	// 파일 크기
			String contentType = conn.getContentType();		// 파일 종료 MIME-Type
			
			// 다운로드 받는 파일 이름 확인 가능
			String raw = conn.getHeaderField("Content-Disposition");  // attachment; filename=abc.jpg
			if(raw != null && raw.indexOf("=") != -1) {
				String fileName = raw.split("=")[1].trim();
				//dstFile = URLDecoder.decode(fileName, "UTF-8");
			}
			
			in = conn.getInputStream();
			bin = new BufferedInputStream(in);
			out = new FileOutputStream(dstFile);
			bout = new BufferedOutputStream(out);
			
			int bytes;	// 읽어들인 바이트수
			
			byte[] buf = new byte[contentLength];	// 버퍼
			
			while((bytes = bin.read(buf))!=-1) {
				bout.write(buf, 0, bytes);
			}
			
			// 다운로드 성공!
			System.out.println("다운로드 성송\t"  + contentLength + " bytes   " + contentType);
			
		} finally {
			if(bout != null) bout.close();
			if(bin != null) bin.close();
		}
		
	} // end download()
	
}

 

 

2. request parameter를 받는 다양한 방법
1) parameter 추출

 : handler 메소드에서도 서블릿에서 보았던 HttpServletRequest, HttpServletResponse 매개변수 가능

 

2) GET 방식, POST 방식

 : GET 방식은 method = RequestMethod.GET, POST 방식은 method = RequestMethod.POST,

   POST와 GET 방식 둘 다 받으려면 method = {RequestMethod.GET, RequestMethod.POST}

 

3) @RequestParam 사용

 : 상황에 따라서는 handler 메소드의 매개변수 이름을  request parameter와 일치시켜주기 어려울 때도 있다.
   그런경우에는 @RequestParam을 사용, request parameter와 다른 이름의 매개변수로 받을 수 있다.

@RequestMapping("/member/find")
public String findMember(Model model,
		@RequestParam("id") String userid,   // name "id" parameter 값을 받아온다.
		@RequestParam("name") String username) {
		
	model.addAttribute("id", userid);
	model.addAttribute("name", username);
		
	return "member/find";		
}


4) 커맨드 객체

 : form으로부터 넘어오는 parameter들을 담는 빈(bean) 객체,

   스프링에서는 커맨드 객체(Command Object)를 통해, 여러 request parameter들을 한 번에 받아올 수 있다.

@RequestMapping("/board/write")
public String writeBoard() {
	return "board/write";
}


5) @ModelAttribute

 : 기본적으로 커맨드 객체는 객체의 타입명이 model의 attribute가 된다.
   커맨드 객체의 model의 attribute 이름을 바꾸어 주기 위해선 @ModelAttribute를 사용

// @RequestParam 사용
@RequestMapping("/member/find")
public String findMember(Model model,
		@RequestParam("id") String userid,   // name "id" parameter 값을 받아온다.
		@RequestParam("name") String username) {
		
	model.addAttribute("id", userid);
	model.addAttribute("name", username);
		
	return "member/find";		
}

 

 

3. STS11_RequestParameter

** [src/main/java] com.lec.sts11_param > HomeController 서블릿

package com.lec.sts11_param;

import java.text.DateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.lec.beans.WriteDTO;

/**
 * Handles requests for the application home page.
 */
@Controller
public class HomeController {
	
	private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
	
	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		logger.info("Welcome home! The client locale is {}.", locale);
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
	// parameter 추출
	// handler 메소드에서도 서블릿에서 보앗던 HttpServletRequest, HttpServletResponse 매개변수 가능.!!!
	
	@RequestMapping(value = "/member/delete", method = RequestMethod.GET)   // -> /member/delete?id=34
	//public String delMember(Model model, HttpServletRequest request) {
	public String delMember(HttpServletRequest request, Model model) {		// 순서 바뀌어도 동작
		String id = request.getParameter("id");
		model.addAttribute("mbId", id);
		return "member/delete";
	}
	
	@RequestMapping(value="/member/regOk", method = RequestMethod.POST)
	public String regOKMember() {
		System.out.println("/member/regOk : POST");
		return "member/regOk";
	}
	
	@RequestMapping(value="/member/regOk", method = RequestMethod.GET)
	public String regOKMember(Model model) {
		System.out.println("/member/regOk : GET");
		return "member/regOk";
	}
	
	@RequestMapping(value = "/member/regist")
	public String registMember() {
		return "member/regist";
	}
	
	// GET/POST 둘다 받는 handler
	@RequestMapping(value = "/member/regOk2", 
			method = {RequestMethod.GET, RequestMethod.POST})
	public String regOkMember2() {
		return "member/regOk";
	}
	
	// handler 에
	// request parameter 의 name 값과 '같은 이름의 매개변수' 가 있으면
	// 바로 그 매개변수가 request parameter 값을 받아온다.
	
//	@RequestMapping("/member/find")
	//public String findMember(String id, String name, Model model) {
	//public String findMember(Model model, String name, String id) {	// 순서 무관
	
	// 숫자타입으로 하면 바로 parsing 하여 받는다.
	//public String findMember(Model model, String name, double id) {
	
	// 동일한 name의 request parameter 들.
//	public String findMember(Model model, String [] name, int [] id) {	
//		model.addAttribute("id", Arrays.toString(id));
//		model.addAttribute("name", Arrays.deepToString(name));
//	
//		return "member/find";
//	}
	
	// @RequestParam 사용
	@RequestMapping("/member/find")
	public String findMember(Model model,
			@RequestParam("id") String userid,   // name "id" parameter 값을 받아온다.
			@RequestParam("name") String username) {
		
		model.addAttribute("id", userid);
		model.addAttribute("name", username);
		
		return "member/find";		
	}
	
	// ------------------------------------------------------------
	// 커맨드 객체(Command Object)
	
	@RequestMapping("/board/write")
	public String writeBoard() {
		return "board/write";
	}
	
	// 기존 방식으로 구현하려면
	// 매 parameter 들을 매겨변수화 해야하기 때문에 힘들다.
//	@RequestMapping(value = "/board/writeOk", method= RequestMethod.POST)
//	public String writeOkBoard(
//		Model model, 
//		@RequestParam("name") String name,
//		@RequestParam("subject") String subject,
//		@RequestParam("content") String content
//		) {
//		WriteDTO dto = new WriteDTO();
//		dto.setName(name);
//		dto.setSubject(subject);
//		dto.setContent(content);
//		
//		model.addAttribute("dto", dto);
//		
//		return "board/writeOk";
//		
//	}
	
	@RequestMapping(value = "/board/writeOk", method= RequestMethod.POST)
	public String writeOkBoard(WriteDTO dto){
		return "board/writeOk";		
	}
	
}

 

** src > main > webapp > WEB-INF > views > member > delete.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
${mbId }<br>
<%= request.getParameter("id") %>


** src > main > webapp > WEB-INF > views > member > regOk.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%= request.getParameter("name") %>


** src > main > webapp > WEB-INF > views > member > regist.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<form action="regOk" method="post">
	<input type="text" name="name" value="김민자"/>
	<input type="submit"/>
</form>

<form action="regOk2" method="post">
	<input type="text" name="name" value="박숙자"/>
	<input type="submit"/>
</form>

 

** src > main > webapp > WEB-INF > views > member > find.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
${id }<br>
${name }<br>

 

** [src/main/java] com.lec.beans > WrtieDTO.java

package com.lec.beans;

// DTO : Data Trasfer Object
//    데이터를 담아 나르기 위한 객체

// 게시글DTO, 회원DTO, ... 필요한 데이터 객체들 만큼 정의
// Bean 객체

public class WriteDTO {
	private int uid;     // wr_uid
	private String subject;   //wr_subject
	private String content;   //wr_content
	private String name;  // wr_name
	private int viewCnt;   // wr_viewcnt
	private String regDate;   // wr_regdate
	
	// 개발시..
	// 다음 3가지 네이밍은 일치시켜주는 것이 좋다 .
	// 클래스 필드명 = DB 필드명  = form 의 name명
	
	// 기본생성자, 매개변수 생성자
	public WriteDTO() {
		super();
		System.out.println("WriteDTO() 객체 생성");
	}
	public WriteDTO(int uid, String subject, String content, String name, int viewCnt) {
		super();
		this.uid = uid;
		this.subject = subject;
		this.content = content;
		this.name = name;
		this.viewCnt = viewCnt;
		System.out.println("WriteDTO(uid, subject, content, name, viewCnt) 객체 생성");
	}
	
	// getter / setter
	public int getUid() {
		System.out.println("getUid() 호출");
		return uid;
	}
	public void setUid(int uid) {
		System.out.println("setUid(" + uid + ") 호출");
		this.uid = uid;
	}
	public String getSubject() {
		System.out.println("getSubject() 호출");
		return subject;
	}
	public void setSubject(String subject) {
		System.out.println("setSubject(" + subject + ") 호출");
		this.subject = subject;
	}
	public String getContent() {
		System.out.println("getContent() 호출");
		return content;
	}
	public void setContent(String content) {
		System.out.println("setContent(" + content + ") 호출");
		this.content = content;
	}
	public String getName() {
		System.out.println("getName() 호출");
		return name;
	}
	public void setName(String name) {
		System.out.println("setName(" + name + ") 호출");
		this.name = name;
	}
	public int getViewCnt() {
		System.out.println("getViewCnt() 호출");
		return viewCnt;
	}
	public void setViewCnt(int viewCnt) {
		System.out.println("setViewCnt(" + viewCnt + ") 호출");
		this.viewCnt = viewCnt;
	}
	public String getRegDate() {
		System.out.println("getRegDate() 호출");
		return regDate;
	}
	public void setRegDate(String regDate) {
		System.out.println("setRegDate(" + regDate + ") 호출");
		this.regDate = regDate;
	}
	
	// 테스트, 개발용으로 toString() 오버라이딩 하면 좋다.
	@Override
	public String toString() {
		return "WriteDTO] " + uid + " : " + subject + " : " 
			+ content + " : " + name + " : " + viewCnt + " : " + regDate;
	}
	
} // end DTO

 

** src > main > webapp > WEB-INF > views > board > write.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>글작성</title>
</head>
<script>
function chkSubmit(){  // 폼 검증
	frm = document.forms["frm"];
	
	var name = frm["name"].value.trim();
	var subject = frm["subject"].value.trim();
	
	if(name == ""){
		alert("작성자 란은 반드시 입력해야 합니다");
		frm["name"].focus();
		return false;
	}
	if(subject == ""){
		alert("제목은 반드시 작성해야 합니다");
		frm["subject"].focus();
		return false;
	}
	return true;
}

</script>
<body>
<h2>글작성</h2>
<%-- 글 내용이 많을수 있기 때문에 POST 방식 사용 --%>
<form name="frm" action="writeOk" method="post" onsubmit="return chkSubmit()">
작성자:
<input type="text" name="name" value="장윤성"/><br>
제목:
<input type="text" name="subject" value="와 점심이다"/><br>
내용:<br>
<textarea name="content">맛있어용~.</textarea>
<br><br>
<input type="submit" value="등록"/>
</form>
<br>
<button type="button" onclick="location.href='list.jsp'">목록으로</button>


</body>
</html>

 

** src > main > webapp > WEB-INF > views > board > writeOk.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- 
작성자: ${dto.name }<br>
글제목: ${dto.subject }<br>
내용: ${dto.content }<br>
-->
작성자: ${writeDTO.name }<br>
글제목: ${writeDTO.subject }<br>
내용: ${writeDTO.content }<br>

 

[STS11_RequestParameter 의 못다한 부분은 다음 시간에 할 예정]

'웹_프론트_백엔드 > JAVA프레임윅기반_풀스택' 카테고리의 다른 글

2020.06.30  (0) 2020.06.30
2020.06.29  (0) 2020.06.29
2020.06.22  (0) 2020.06.22
2020.06.19  (0) 2020.06.19
2020.06.18  (0) 2020.06.18