ServletContext,File explorer -22.06.20
오늘의 목표 : implicitObject.jsp: 5, 9번 공부,scpoe
5.application(ServletContext) : 서블릿 컨테이너와 커뮤니케이션 하기 위해 사용되는 객체.
서버와 현재 실행중인 어플리케이션에 대한 정보를 가진 객체.
-Context : 맥락, 어느한가지 구성요소가 아니라 구성요소 둘러싸고 있는 전체
-CAC- Context Aware Computing
ex) 공연장, 어떤공연 아 여기서는 핸드폰이 매너모드
Context 는 사용자의 현재의 시간과 위치에서 발생 가능한 모든 정보를 의미
-ServletContext : 어플리케이션 하나당 한개씩 존재
1) 현재 서블릿이 운영중인 어플리케이션 정보
2) 그 어플리케이션 운영중인 서버 정보
ServletContext application
-ServletConfig(1vs1, 일대일) - 서블릿이 컨테이너에 의해 운영되는 과정에서 생성되는 메타 정보를 가진 객체.
서블릿이 운영되는 어플리케이션과 해당 어플리케이션이 운영되는 서버에 대한 정보를 가진 객체.
컨텍스트 하나당 하나의 싱글턴 객체가 운영됨.
예를 들어 파일의 MIME 유형을 가져오거나 요청을 발송하거나 로그 파일에 쓰기 위해 서블릿이 해당 서블릿 컨테이너와 통신하는 데 사용하는 메소드 세트를 정의합니다.
Java Virtual Machine당 "웹 애플리케이션"당 하나의 컨텍스트가 있습니다.
폴더가 7개이면 서블릿 컨텍스트도 7개
<ServletContextDesc.jsp>
싱글톤 -> hashcode 값이 동일하다.
<h4>servlet Context hashcode : <%=application.hashCode() %></h4>
<a href="<%=request.getContextPath() %>/desc.do">/desc.do</a>
****컨테이너와 대화하는 과정에서 사용
1. MIME 데이터 사용
<%=application.getMimeType("test.jpg") %>
2. 서버의 정보
<%=application.getServerInfo() %>
servlet spec version : <%=application.getMajorVersion() %>.<%=application.getMinorVersion() %>
3. 로깅(log 기록) : 클라이언트에게 노출시키지 않는다.
<%
application.log("로그 메시지");
%>
4(****) 웹리소스 확보 : /WebStudy02_MVN/src/main/webapp/resources/images/cat1.jpg
1)개발 환경
D:\B_Util\eGovFrameDev-3.9.0-64bit\workspace\WebStudy02_MVN\src\main\webapp\resources\images\cat1.jpg
2)실행 환경
D:\B_Util\eGovFrameDev-3.9.0-64bit\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\WebStudy02_MVN\resources\images\cat01.jpg
3) D:\B_Util\eGovFrameDev-3.9.0-64bit\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0
4) <%=application.getRealPath("/resources/images/cat1.jpg") %>
5)
<%
String imageUrl = "/resources/images/cat1.jpg";
File imageFile = new File(application.getRealPath(imageUrl));
out.println("파일 크기 : "+imageFile.length());
%>
File explorer
Templatemethod 패턴
-클래스 다이어그램
1.Template Class : 작업 전체의 순서정의
2.DerivedClass : 구체적인 작업 정의 ,구체 클래스
# : 추상 메서드
** Template method pattern
: 특정 작업의 단계가 명확히 고정되어있고, 해당 단계 내의 세부 작업의 내용이 여러 형태가 존재할 때 사용하는 구조 패턴
1. template class : 작업의 단계를 정의하고 있는 클래스로 재정의 하지 않음
1) template method : 작업의 단계 정의
2) hook method(abstract) : 단계 내의 세부 작업 정의
2. concrete class : template 내에 정의된 단계에서 어느 한 세부 단계의 작업을 정의하고 있는 클래스
만들어보자
template설명
public final void template() {
stepOne();
stepTwo();
stepThreed();
}
template() :실제로 일하진 않고 일시키는 순서만 정의
<TempletCalss.java 코드 >
package kr.or.ddit.designpattern.templetmethodpattern;
public abstract class TempletClass {
public final void template() {
stepOne(); hook method는 stepOne, stepTwo, stepThreed
stepTwo();
stepThreed();
}
private void stepOne() {
System.out.println("1단계");
}
protected abstract void stepTwo();
//protected : 상속 구조 내에서만 접근 가능
//abstract : 상속 구조 내에서 자식이 먼저 나와야지 나를 정의할 수 있다.
private void stepThreed() {
System.out.println("3단계");
}
}
<DerivedClass1>
package kr.or.ddit.designpattern.templetmethodpattern;
public class DerivedClass1 extends TempletClass {
@Override
protected void stepTwo() {
System.out.println("A형태의 2단계");
}
}
<DerivedClass2>
package kr.or.ddit.designpattern.templetmethodpattern;
public class DerivedClass2 extends TempletClass {
@Override
protected void stepTwo() {
System.out.println("B형태의 2단계");
}
}
=> 메이븐과 다르게 src에 test생김
<TempletClassTest>
package kr.or.ddit.designpattern.templetmethodpattern;
import static org.junit.Assert.*;
import org.junit.Test;
public class TempletClassTest {
@Test
public void testTemplate() {
TempletClass derived1 = new DerivedClass1();
TempletClass derived2 = new DerivedClass2();
TempletClass[] array = new TempletClass[] {derived1, derived2};
for(TempletClass single : array) {
single.template(); //main메소드 안쓰고 JUnit
}
}
}
adapterpattern 패턴
클래스의 인터페이스를 사용자가 기대하는 다른 인터페이스로 변환하는 패턴으로, 호환성이 없는 인터페이스 때문에 함께 동작할 수 없는 클래스들이 함께 작동하도록 해준다.
어트리뷰트: 전역변수 표현
다이아몬드 : 포함관계
1,2,3순서대로 만들어보자
<Target.java>
package kr.or.ddit.designpattern.adapterpattern;
public interface Target {
public void request();
}
<OtherConcreate.java>
package kr.or.ddit.designpattern.adapterpattern;
public class OtherConcrete implements Target {
@Override
public void request() {
System.out.println(this.getClass().getSimpleName()+"에서 요청이 처리됨.");
}
}
<Client.java>
package kr.or.ddit.designpattern.adapterpattern;
public class Client {
private Target target;
public static void main(String[] args) {
Client client = new Client();
// client.target = new OtherConcrete();
client.target = new Adapter(new Adaptee());
client.target.request();
}
}
클라이언트가 Adaptee사용하려면
1) Adaptee를 바꿔
2) Adapter가 Adaptee소유해서 사용할 수 있도록
<Adaptee.java>
package kr.or.ddit.designpattern.adapterpattern;
public class Adaptee {
public void specificRequest() {
System.out.println("Target 과 전혀 관계가 없는 다른 구조의 객체에 의해 요청이 처리됨.");
}
}
<Adapter.java>
package kr.or.ddit.designpattern.adapterpattern;
public class Adapter implements Target {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
super();
this.adaptee = adaptee;
}
@Override
public void request() {
adaptee.specificRequest();
}
}
FancyTree -> 아까 다시 이어서 해보자 (browsing.jsp>
https://wwwendt.de/tech/fancytree/demo/
Fancytree - Example Browser
wwwendt.de
https://github.com/mar10/fancytree/wiki
GitHub - mar10/fancytree: JavaScript tree view / tree grid plugin with support for keyboard, inline editing, filtering, checkbox
JavaScript tree view / tree grid plugin with support for keyboard, inline editing, filtering, checkboxes, drag'n'drop, and lazy loading - GitHub - mar10/fancytree: JavaScript tree view / tr...
github.com
api reference 들어가기
https://wwwendt.de/tech/fancytree/doc/jsdoc/FancytreeNode.html
JSDoc: Class: FancytreeNode
Call fn(node) for all parent nodes, bottom-up, including invisible system root. Stop iteration, if fn() returns false. Return false if iteration was stopped.
wwwendt.de
File -> 어뎁티 사용해서 어뎁터로 만들자
FancyTreeNode
서로다름
<browsing.jsp>
<%@page import="java.io.File"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<%-- <link rel="stylesheet" href="<%=request.getContextPath() %>/resources/js/fancytree/ui.fancytree.min.css"> --%>
<%-- <script type="text/javascript" src="<%=request.getContextPath() %>/resources/js/fancytree/jquery.fancytree-all-deps.min.js"></script> --%>
<script type="text/javascript" src="<%=request.getContextPath() %>/resources/js/jquery-3.6.0.min.js"></script>
<link href="//cdn.jsdelivr.net/npm/jquery.fancytree@2.27/dist/skin-win8/ui.fancytree.min.css" rel="stylesheet">
<script src="//cdn.jsdelivr.net/npm/jquery.fancytree@2.27/dist/jquery.fancytree-all-deps.min.js"></script>
</head>
<body>
<div id="tree"></div>
<script type="text/javascript">
$("#tree").fancytree({
source: {
url :"<%=request.getContextPath()%>/server/browsing.do"
}
});
</script>
</body>
</html
<ServerFileBrowsingServlet .java>
package kr.or.ddit.servlet07;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import kr.or.ddit.vo.fancytree.FancyTreeNode;
import kr.or.ddit.vo.fancytree.FancyTreeNodeFileAdapter;
@WebServlet("/server/browsing.do")
public class ServerFileBrowsingServlet extends HttpServlet {
private ServletContext application;
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
this.application =getServletContext();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String accept= req.getHeader("Accept");
if(StringUtils.containsIgnoreCase(accept, "json")) {
Set<String> children = application.getResourcePaths("/"); //web root(context root)
List<File> fileList = new ArrayList<>();
for(String childPath : children) {
String realPath =application.getRealPath(childPath);
File childFile = new File(realPath);
fileList.add(childFile);
}
List<FancyTreeNode> adapterList = fileList.stream().map((file)->{
return new FancyTreeNodeFileAdapter(file);
}).collect(Collectors.toList());
resp.setContentType("application/json;charset=UTF-8");
ObjectMapper mapper = new ObjectMapper();
// try~with~resource 문법 구조(1.7)
try(
// closable 객체 생성 코드 -> 자동 close 됨.
PrintWriter out = resp.getWriter();
){
mapper.writeValue(out, adapterList);
}
}else {
// req.setAttribute("fileList", fileList);
// req.setAttribute("adapterList",adapterList);
String view ="/WEB-INF/views/server/browsing.jsp";
req.getRequestDispatcher(view).forward(req, resp);
}
}
}
=> 근데 날짜 정리하고싶어
힌트는 Comparable
인터페이스는 static만 근데 1.7이후부터 non-static가능
<FancyTreeNode..java>
package kr.or.ddit.vo.fancytree;
public interface FancyTreeNode extends Comparable<FancyTreeNode> {
public String getKey();
public String getTitle();
public boolean isFolder();
@Override
default int compareTo(FancyTreeNode o) {
return getTitle().compareTo(o.getTitle());
}
}
package kr.or.ddit.servlet07;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import kr.or.ddit.vo.fancytree.FancyTreeNode;
import kr.or.ddit.vo.fancytree.FancyTreeNodeFileAdapter;
@WebServlet("/server/browsing.do")
public class ServerFileBrowsingServlet extends HttpServlet {
private ServletContext application;
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
this.application =getServletContext();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String accept= req.getHeader("Accept");
if(StringUtils.containsIgnoreCase(accept, "json")) {
Set<String> children = application.getResourcePaths("/"); //web root(context root)
List<File> fileList = new ArrayList<>();
for(String childPath : children) {
String realPath =application.getRealPath(childPath);
File childFile = new File(realPath);
fileList.add(childFile);
}
List<FancyTreeNode> adapterList = fileList.stream().map((file)->{
return new FancyTreeNodeFileAdapter(file);
}).sorted().collect(Collectors.toList());
resp.setContentType("application/json;charset=UTF-8");
ObjectMapper mapper = new ObjectMapper();
try(
PrintWriter out = resp.getWriter();
){
mapper.writeValue(out, adapterList);
}
}else {
// req.setAttribute("fileList", fileList);
// req.setAttribute("adapterList",adapterList);
String view ="/WEB-INF/views/server/browsing.jsp";
req.getRequestDispatcher(view).forward(req, resp);
}
}
}
<유진언니 참고>
jsonView.do 로 보내서 json으로 마셜링
<ServerFileBrowsingServlet>
package kr.or.ddit.servlet07;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import kr.or.ddit.vo.fancytree.FancyTreeNode;
import kr.or.ddit.vo.fancytree.FancyTreeNodeFileAdapter;
@WebServlet("/server/browsing.do")
public class ServerFileBrowsingServlet extends HttpServlet{
private ServletContext application;
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
this.application = getServletContext();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//헤더의 값 가져오기
String accept = req.getHeader("Accept");
if( StringUtils.containsIgnoreCase(accept, "json")) {
//containsIgnoreCase : 대소문자 식별하지 않고 accept에 json이라는 문자열이 있는가
Set<String> children = application.getResourcePaths("/"); // web root(context root)에 접근
List<File> fileList = new ArrayList<>();
for(String childPath : children) {
String realPath = application.getRealPath(childPath);
File childFile = new File(realPath);
fileList.add(childFile);
}
//map : 하나의 컬렉션을 또다른 형태의 컬렉션으로 바꾸고 싶을 때 사용
List<FancyTreeNode> adapterList = fileList.stream().map((file)->{
return new FancyTreeNodeFileAdapter(file);
}).collect(Collectors.toList());
resp.setContentType("application/json;charset=UTF-8");
ObjectMapper mapper = new ObjectMapper();
// try~with~resource 문법 구조(1.7)
try(
//closable 객체 생성 코드 -> 자동 close 됨
PrintWriter out = resp.getWriter();
){
mapper.writeValue(out, adapterList);
}
}else {
// req.setAttribute("fileList", fileList);
// req.setAttribute("adapterList", adapterList);
String view = "/WEB-INF/views/server/browsing.jsp";
req.getRequestDispatcher(view).forward(req, resp);
}
}
}
<browsing.jsp>
<%@page import="java.io.File"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<%-- <link rel="stylesheet" href="<%=request.getContextPath() %>/resources/js/fancytree/ui.fancytree.min.css"> --%>
<%-- <script src="<%=request.getContextPath() %>/resources/js/fancytree/jquery.fancytree-all-deps.min.js"></script> --%>
<script src="<%=request.getContextPath() %>/resources/js/jquery-3.6.0.min.js"></script>
<link href="//cdn.jsdelivr.net/npm/jquery.fancytree@2.27/dist/skin-win8/ui.fancytree.min.css" rel="stylesheet">
<script src="//cdn.jsdelivr.net/npm/jquery.fancytree@2.27/dist/jquery.fancytree-all-deps.min.js"></script>
</head>
<div id="tree"></div>
<body>
<script type="text/javascript">
$("#tree").fancytree({
source: {
url:"<%=request.getContextPath()%>/server/browsing.do"
}
});
</script>
</body>
</html>
<FancyTreeNode.java>
package kr.or.ddit.vo.fancytree;
public interface FancyTreeNode {
public String getKey(); //key 프로퍼티가 있어야한다고 정의
public String getTitle(); //title 프로퍼티가 있어야한다고 정의
public boolean isFolder(); //folder 프로퍼티가 있어야한다고 정의
}
<FancyTreeNodeFileAdapter.java>
package kr.or.ddit.vo.fancytree;
import java.io.File;
public class FancyTreeNodeFileAdapter implements FancyTreeNode {
private File adaptee; //진짜 데이터
public FancyTreeNodeFileAdapter(File adaptee) { //adaptee가 있어야 Adapter를 만들 수 있다
super();
this.adaptee = adaptee;
}
@Override
public String getKey() {
return adaptee.getName();
}
@Override
public String getTitle() {
return adaptee.getName();
}
@Override
public boolean isFolder() {
return adaptee.isDirectory();
}
}
4. Lazy Loading
: 페이지를 읽어들이는 시점에 중요하지 않은 리소스 로딩을 추후에 하는 기술이다
단일 노드는 '지연'으로 표시될 수 있다.
이러한 노드는 처음 확장될 때 Ajax 요청을 생성한다.
Lazy loading은 효율적인 방법으로 무한한 크기의 계층 구조를 나타낼 수 있게 한다.
(ex, 사용자가 웹페이지를 로드하고 즉시 남겨 두면 웹페이지의 맨 위 부분 이외의 항목이 로드되지 않는다.)
<browsing.jsp>
<%@page import="java.io.File"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="<%=request.getContextPath() %>/resources/js/jquery-3.6.0.min.js"></script>
<link href="//cdn.jsdelivr.net/npm/jquery.fancytree@2.27/dist/skin-win8/ui.fancytree.min.css" rel="stylesheet">
<script src="//cdn.jsdelivr.net/npm/jquery.fancytree@2.27/dist/jquery.fancytree-all-deps.min.js"></script>
</head>
<div id="tree"></div>
<body>
<script type="text/javascript">
$("#tree").fancytree({
source: {
url:"<%=request.getContextPath()%>/server/browsing.do"
},
//lazyLoad는 폴더를 expanded할때 1번 호출된다
lazyLoad: function(event, data){
var node = data.node;
data.result = {
url: "<%=request.getContextPath()%>/server/browsing.do",
data: {mode: "children", parent: node.key},
cache: false
};
}
});
</script>
</body>
</html>
=> /09/ 이렇게 나옴
5. 데이터 정렬하기
<FancyTreeNodeFileAdapter.java>
package kr.or.ddit.vo.fancytree;
import java.io.File;
public class FancyTreeNodeFileAdapter implements FancyTreeNode<File> {
private File adaptee; //진짜 데이터- 파일,폴더
private String serverFilePath;
public FancyTreeNodeFileAdapter(File adaptee, String serverFilePath) { //adaptee가 있어야 Adapter를 만들 수 있다
super();
this.adaptee = adaptee;
this.serverFilePath = serverFilePath;
}
@Override
public String getKey() {
return this.serverFilePath;
}
@Override
public String getTitle() {
return adaptee.getName();
}
@Override
public boolean isFolder() {
return adaptee.isDirectory();
}
@Override
public boolean isLazy() {
return isFolder();
}
@Override
public boolean isExpanded() {
return false;
}
@Override
public File getAdaptee() {
return this.adaptee;
}
@Override
public int compareTo(FancyTreeNode<File> o) {
File otherFile = o.getAdaptee();
if(!(adaptee.isDirectory()^otherFile.isDirectory())) { //둘다 파일이거나 디렉토리
//^(베타적 or연산자) : 둘이 서로 다른 값을 가져야 true
return FancyTreeNode.super.compareTo(o); //둘다 똑같으니까 이름으로 정렬
}else { //둘 중 하나는 파일이고 하나는 디렉토리
//폴터가 앞에 나와야됨
if(adaptee.isDirectory()) {
return -1; //내가 앞으로 감
}else {
return 1; //내가 뒤로 감
}
}
}
}
둘다 파일이거나 디렉토리, 비교조건만 정의 :
package kr.or.ddit.vo.fancytree;
public interface FancyTreeNode<T> extends Comparable<FancyTreeNode<T>>{
public String getKey(); //key 프로퍼티가 있어야한다고 정의
public String getTitle(); //title 프로퍼티가 있어야한다고 정의
public boolean isFolder(); //folder 프로퍼티가 있어야한다고 정의
public boolean isLazy();
public boolean isExpanded();
// T 제너릭타입, 처음에는 타입이 고정되어있지 않음.
public T getAdaptee();
//정렬, 비교조건
@Override
default int compareTo(FancyTreeNode<T> o) {
return getTitle().toLowerCase().compareTo(o.getTitle().toLowerCase());
//toLowerCase : 소문자로 비교해서 대소문자 비교 없애기
}
}
실제로 정렬하기 <ServerFileBrowsingServlet.java>
package kr.or.ddit.servlet07;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import kr.or.ddit.vo.fancytree.FancyTreeNode;
import kr.or.ddit.vo.fancytree.FancyTreeNodeFileAdapter;
@WebServlet("/server/browsing.do")
public class ServerFileBrowsingServlet extends HttpServlet{
private ServletContext application;
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
this.application = getServletContext();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//헤더의 값 가져오기
String accept = req.getHeader("Accept");
if( StringUtils.containsIgnoreCase(accept, "json")) {
//containsIgnoreCase : 대소문자 식별하지 않고 accept에 json이라는 문자열이 있는가
String parent = req.getParameter("parent");
String currentRoot = null;
if(StringUtils.isBlank(parent)) { //상위가 없으면
currentRoot = "/";
}else { //상위가 있으면
if(parent.charAt(0)=='/') {
currentRoot = parent;
}else{
currentRoot = "/"+parent;
}
}
Set<String> children = application.getResourcePaths(currentRoot); // web root(context root)에 접근
List<FancyTreeNode> adapterList = new ArrayList<>();
for(String childPath : children) {
String realPath = application.getRealPath(childPath);
File childFile = new File(realPath);
FancyTreeNodeFileAdapter adapter = new FancyTreeNodeFileAdapter(childFile,childPath);
adapterList.add(adapter);
}
//sorted로 정렬, collect로 리스트 뿌려주기
adapterList = adapterList.stream().sorted().collect(Collectors.toList());
resp.setContentType("application/json;charset=UTF-8");
ObjectMapper mapper = new ObjectMapper();
// try~with~resource 문법 구조(1.7)
try(
//closable 객체 생성 코드 -> 자동 close 됨
PrintWriter out = resp.getWriter();
){
mapper.writeValue(out, adapterList);
}
}else {
// req.setAttribute("fileList", fileList);
// req.setAttribute("adapterList", adapterList);
String view = "/WEB-INF/views/server/browsing.jsp";
req.getRequestDispatcher(view).forward(req, resp);
}
}
}
<선생님의 말씀>
plugin 문서 찾아보기가 중요
어댑터 디자인 패턴 (객체의 구조가 다달라... 코드가 너저분해짐 )
전자정부스프링 템플릿 굉장히 많이 사용 디자인패턴 모르고 사용할 수 없음