728x90
300x250

[컴퓨터(PC활용)] 데이터로 살펴보는 날씨 - (2/2) (2019년)]

 

1부에서 다뤄보았던 날씨에 대해서 소개하고자 한다.

 

[컴퓨터(PC활용)] 데이터로 살펴보는 날씨 - (1/2) (2019년)], 2021-04-02 22:57
http://yyman.tistory.com/1523 

3. 소개(2)

데이터로 살펴보는 날씨에 대해서 소개하고자 한다.

 

 


4. 첨부[(Attachment)]

 

210402_weather_extractor_tool_guide.zip
7.33MB

[Apache License v2.0을 적용받는다.]


* 맺음글(Conclusion)

데이터로 살펴보는 2019년의 최고온도 날씨에 대해서 알기 쉽게 살펴보았다.


* 참고자료(Reference)

1. 홈 - 기상청, 날씨누리, https://www.weather.go.kr , Accessed by 2021-04-02, Last Modified 2021-04-02

2. OpenJDK, http://openjdk.java.net, Accessed by 2021-04-02, Last Modified 2021-04-02.

3. Commons CSV - Home, https://commons.apache.org/proper/commons-csv/ , Accessed by 2021-04-02, Last Modified 2021-04-02.

반응형
728x90
300x250

[컴퓨터(PC활용)] 데이터로 살펴보는 날씨 - (1/2) (2019년)]

 

데이터로 살펴보는 날씨에 대해서 다뤄보고자 한다.

프로그래밍 언어 자바(Java), 마이크로소프트 오피스 (엑셀VBA)

* 소개

데이터로 살펴보는 날씨에 대해서 소개하고자 한다.

 

 


* 2부에서 만나요.

[컴퓨터(PC활용)] 데이터로 살펴보는 날씨 - (2/2) (2019년)], 2021-04-02 22:57
http://yyman.tistory.com/1524

 

반응형
728x90
300x250

[Java(자바)]  barbecue 바코드 생성 라이브러리

이번에 소개할 내용은 barbecue(바베큐) 바코드 생성 라이브러리에 대해서 소개하고자 한다.


1. 적용 라이선스

오픈소스 "BSD License(이하 "비에스디 라이선스")를 적용받는다.

http://barbecue.sourceforge.net 

 


2. 이클립스에서의 셋팅방법

프로젝트 환경설정에서 Liberies에 ClassPath(클래스패스)에 "Add External JARS..."를 클릭해서 등록해서 사용하면 된다.

그림 1. 프로젝트 속성 -> 라이브러리에 클래스패스에 Jar파일 등록하기

그림 2. 프로젝트 속성, Order and Export("읽기: 오더 엔 익스폴트")

jdom("읽기: 제이돔")과 barbecue("읽기: 바베큐")를 체크한다.

Apply("읽기: 어플라이", "뜻: 적용")을 클릭한다.

 


3. 이클립스 - 자바 소스코드

다음처럼 소스코드를 작성하여 적용할 수 있다.

package com.barcode.sample;

import java.io.File;
import net.sourceforge.barbecue.Barcode;
import net.sourceforge.barbecue.BarcodeFactory;
import net.sourceforge.barbecue.BarcodeImageHandler;

public class Program {

     public static void main(String[] args) {
          String str = "123412341234";
          try {

               Barcode barcode = BarcodeFactory.createCode128(str);
               File file = new File("c:/barcode1.png");

              BarcodeImageHandler.savePNG(barcode, file);
         } catch (Exception e) {
              e.printStackTrace();
         }
    }

}

4. 바코드 생성 모습

실제 적용되는 바코드의 모습이다. 바코드 입출력 장치(이하 "바코드 스캐너라고도 불림. 글자 입력방식의 장치")로
식별하면 인식된다.

 

그림 3. 바코드 생성 모습의 예

 


5. 라이브러리 첨부(Library)

barbecue-1.5-beta1.zip
0.84MB

BSD License를 적용받는다.

 


6. 첨부(Attachment)

 

Sample_Code_Java.zip
0.00MB

자바에 적용된 코드이다. 많은 도움이 되었으면 한다.

 

210309_Java_Barbecue_Barcode_Create_Guideline.zip
0.91MB

[Apache Licence v2.0을 적용받는다.]


* 맺음글(Conclusion)

자바에서 바코드를 생성하는 방법에 대해서 살펴보았다.


* 참고자료(References)

1. Barbecue project, http://barbecue.sourceforge.net, Accessed by 2021-03-09, Last Modified 2021-03-09.

2. OpenJDK (java.net), http://openjdk.java.net, Accessed by 2021-03-09, Last Modified 2021-03-09.

3. Enabling Open Innovation & Collaboration | The Eclipse Foundation, http://www.eclipse.org, Accessed by 2021-03-09, Last Modified 2021-03-09.

4. JDOM, http://www.jdom.org, Accessed by 2021-03-09, Last Modified 2021-03-09.

반응형
728x90
300x250

[GNU - 리눅스(Linux)] Apache Tomcat 9(아파치 톰캣9), 큐브리드 10.2(Cubrid 11), 전자정부 이클립스, 리눅스민트 20에서 연동하기


이번에 소개할 내용은 아파치 톰캣9, 큐브리드 10.2, 전자정부 이클립스, 리눅스민트 20을 연동하여 개발하는 환경을 설정하는 방법에 대해서 소개하겠다.



1. 전자정부 이클립스 설치 복습


설치 방법을 잊어버린 경우를 대비해서 잠시 소개하였다.


그림 1. 리눅스민트20, 전자정부 이클립스 설치 가이드(1)



그림 2. 리눅스민트20, 전자정부 이클립스 설치 가이드(1)



그림 3. 리눅스민트20, 전자정부 이클립스 설치 가이드(1)




2. 큐브리드 10.2(11)와 아파치 톰캣 9 연동하기


큐브리드와 아파치 톰캣 9를 연동하기 위해서 먼저 전자정부 이클립스를 실행하도록 하겠다.

그림 4. 리눅스민트20, 전자정부 이클립스 실행하기




그림 5. 리눅스민트20, 전자정부 이클립스 실행하기





그림 6. 리눅스민트20, 전자정부 이클립스 / 아파치 톰캣 9 환경설정 확인



4. 큐브리드 10.2(11)와 JSP-Dynamic Web Project 생성하기


프로젝트를 생성하여 큐브리드 JDBC와 JSP, Java를 연동하는 방법에 대해 소개하도록 하겠다.



그림 7. 리눅스민트20, 전자정부 이클립스에서 새 프로젝트 생성하기


그림 8. 리눅스민트20, 전자정부 이클립스에서 새 프로젝트 생성하기




그림 9. 리눅스민트20, 전자정부 이클립스에서 새 프로젝트 생성하기





5. 큐브리드 10.2(11) JDBC, 신규 생성한 JSP 프로젝트에 설치하기


앞에서 생성한 다이나믹 웹 프로젝트에 JDBC-11-0-latest-cubrid.jar 파일을 설치하도록 하겠다.

(2021-02-01 기준으로 JDBC-11-0-latest-cubrid.jar 파일이 최신 버전이다.)


그림 10. 리눅스민트20, 전자정부 이클립스와 큐브리드 JDBC 연동하기




6. 큐브리드 10.2(11), 이클립스 프로젝트 (Java, JSP 코드 작성하기)


큐브리드에 사용되는 Java, JSP코드를 작성하는 방법에 대해 소개하도록 하겠다.




그림 11. 큐브리드 소스코드


https://www.cubrid.org/getting_started 해당 링크에 접속하면 자세한 내용을 확인할 수 있다.



그림 12. 자바 코드 생성하기




그림 13. 자바 코드 생성하기




그림 14. 자바 코드 생성하기




그림 15. 자바 코드 생성하기




그림 16. JSP 코드 생성하기




7. 서버 - 배포하기


서버에 배포하는 방법에 대해 소개하도록 하겠다.



그림 17. 구동중인 큐브리드 DB서버 상태를 확인할 것 (2021-02-01)


그림 17처럼 큐브리드 DB서버 상태를 제일 먼저 확인해야 한다.



그림 18. 초록색 (재생)버튼 누르기 (Run On Server 버튼 찾아서 클릭)


톰캣 9.0 서버로 배포 태스트를 할 것이다.




그림 19. 빌드 결과 (2021-02-01)


정상적으로 동작한 것을 확인할 수 있다.



* 첨부(Attachment)


210201_LinuxMint20_Cubrid_10_2_eGovFramework_Eclipse_Cubrid_JDBC_guide.zip

[Apache Licence v2.0을 적용 받는다]



* 맺음글(Conclusion)


리눅스민트20과 전자정부 이클립스, 아파치 톰캣 9를 연동하는 방법에 대해서 소개하였다.



* 참고 자료(Reference)


1. CUBRID Foundation: Getting Started, https://www.cubrid.org/getting_started, Accessed by 2021-02-01, Last Modified 2021-02-01.

-> GNU/GPL v3 License로 배포하고 있음.

2. eGovFrame Portal 온라인 지원 포탈, https://www.egovframe.go.kr, Accessed by 2021-02-01, Last Modified 2021-02-01.

-> 전자정부 이클립스(미리 SVN 배포 기능, 각종 셋팅이 미리 다 되어 있음.) / 전자정부 프레임워크만 사용하지 않았음. 

    (스프링프레임워크의 "외부 접속" 의존성 문제)

-> Apache License v2.0로 배포하고 있음.

3. Main Page - Linux Mint, https://linuxmint.com, Accessed by 2021-02-01, Last Modified 2021-02-01.

-> GNU/GPL v3 License로 배포하고 있음.

4. Oracle VM VirtualBox, https://www.virtualbox.org, Accessed by 2021-02-01, Last Modified 2021-02-01.

-> GNU/GPL v3 License로 배포하고 있음.

5. Enabling Open Innovation & Collaboration | The Eclipse Foundation, https://www.eclipse.org, Accessed by 2021-02-01, Last Modified 2021-02-01

반응형
728x90
300x250
[Spring-Framework] 42. Spring Framework에서 (Jaxb-runtime, activation, Jaxb Api, JSTL)을 활용한 XML 생성하기


이번에 소개할 방법은 Spring Framework에서 Jaxb-runtime, activation, Jaxb Api, JSTL을 활용하여 XML을 생성하는 방법에 대해서 소개하겠다.


JSP/Servlet 방식하고는 차이가 있는 점이 있다면, @(어노테이션)을 사용할 것이다.


* IDE: Eclipse 2020-06
* Library: Maven Project / Spring Framework 4.2.4 Releases.

1. https://mvnrepository.com/artifact/javax.servlet/servlet-api

   javax.servlet 2.5

2. https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api

   jaxb-api 2.3.0-b170201.1204

3. https://mvnrepository.com/artifact/javax.activation/activation

   activation 1.1

4. https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime

   jaxb-runtime 2.3.0-b170127.1453

5. https://mvnrepository.com/artifact/javax.servlet/jstl

   jstl 1.2



1. 프로젝트 구성도


실제로는 코드가 몇 줄 되지는 않지만, 문제는 라이브러리 셋팅 등에서 오류를 많이 경험할 수 있다.



그림 1. 프로젝트 구성도




2. Java Compiler, Build Path, Project Factes


* Java Compiler - compiler compliance level 1.8
* Build Path -> JRE System Library 1.8
* Project Factes - Java : 1.8



3. pom.xml

이 셋팅이 매우 무척 많이 중요하다.


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.website</groupId>
 <artifactId>example</artifactId>
 <name>Spring-XML-Jaxb</name>
 <packaging>war</packaging>
 <version>1.0.0-BUILD-SNAPSHOT</version>
 <properties>
  <java-version>1.8</java-version>
  <org.springframework-version>4.2.4.RELEASE</org.springframework-version>
  <org.aspectj-version>1.6.10</org.aspectj-version>
  <org.slf4j-version>1.6.6</org.slf4j-version>

 </properties>
 <dependencies>
  <!-- Spring -->
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>${org.springframework-version}</version>
   <exclusions>
    <!-- Exclude Commons Logging in favor of SLF4j -->
    <exclusion>
     <groupId>commons-logging</groupId>
     <artifactId>commons-logging</artifactId>
     </exclusion>
   </exclusions>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>${org.springframework-version}</version>
  </dependency>
    
  <!-- AspectJ -->
  <dependency>
   <groupId>org.aspectj</groupId>
   <artifactId>aspectjrt</artifactId>
   <version>${org.aspectj-version}</version>
  </dependency> 
  
  <!-- Logging -->
  <dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-api</artifactId>
   <version>${org.slf4j-version}</version>
  </dependency>
  <dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>jcl-over-slf4j</artifactId>
   <version>${org.slf4j-version}</version>
   <scope>runtime</scope>
  </dependency>
  <dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-log4j12</artifactId>
   <version>${org.slf4j-version}</version>
   <scope>runtime</scope>
  </dependency>
  <dependency>
   <groupId>log4j</groupId>
   <artifactId>log4j</artifactId>
   <version>1.2.15</version>
   <exclusions>
    <exclusion>
     <groupId>javax.mail</groupId>
     <artifactId>mail</artifactId>
    </exclusion>
    <exclusion>
     <groupId>javax.jms</groupId>
     <artifactId>jms</artifactId>
    </exclusion>
    <exclusion>
     <groupId>com.sun.jdmk</groupId>
     <artifactId>jmxtools</artifactId>
    </exclusion>
    <exclusion>
     <groupId>com.sun.jmx</groupId>
     <artifactId>jmxri</artifactId>
    </exclusion>
   </exclusions>
   <scope>runtime</scope>
  </dependency>

  <!-- @Inject -->
  <dependency>
   <groupId>javax.inject</groupId>
   <artifactId>javax.inject</artifactId>
   <version>1</version>
  </dependency>
    
  <!-- Servlet -->
  <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>servlet-api</artifactId>
   <version>2.5</version>
   <scope>provided</scope>
  </dependency>
  <dependency>
   <groupId>javax.servlet.jsp</groupId>
   <artifactId>jsp-api</artifactId>
   <version>2.1</version>
   <scope>provided</scope>
  </dependency>
  <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>jstl</artifactId>
   <version>1.2</version>
  </dependency>
 
  <!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api -->
  <dependency>
      <groupId>javax.xml.bind</groupId>
      <artifactId>jaxb-api</artifactId>
      <version>2.3.0-b170201.1204</version>
  </dependency>
  
  <!-- https://mvnrepository.com/artifact/javax.activation/activation -->
  <dependency>
      <groupId>javax.activation</groupId>
      <artifactId>activation</artifactId>
      <version>1.1</version>
  </dependency>
  
  <!-- https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime -->
  <dependency>
      <groupId>org.glassfish.jaxb</groupId>
      <artifactId>jaxb-runtime</artifactId>
      <version>2.3.0-b170127.1453</version>
  </dependency>
 

  <!-- Test -->
  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.7</version>
   <scope>test</scope>
  </dependency>       
 </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-eclipse-plugin</artifactId>
                <version>2.9</version>
                <configuration>
                    <additionalProjectnatures>
                        <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
                    </additionalProjectnatures>
                    <additionalBuildcommands>
                        <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
                    </additionalBuildcommands>
                    <downloadSources>true</downloadSources>
                    <downloadJavadocs>true</downloadJavadocs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <compilerArgument>-Xlint:all</compilerArgument>
                    <showWarnings>true</showWarnings>
                    <showDeprecation>true</showDeprecation>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <configuration>
                    <mainClass>org.test.int1.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>


파일명: pom.xml


[첨부(Attachments)]

pom.zip




4. HomeController.java (com.website.example)


package com.website.example;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

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.ResponseBody;

import com.website.example.vo.BoardListVO;
import com.website.example.vo.BoardVO;

/**
 * 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";
 }
 
         @RequestMapping(value = "/dataTransform", produces="application/xml")
         @ResponseBody
         public BoardListVO dataTransform(Locale locale, Model model) {

  
              List<BoardVO> boardList = new ArrayList<BoardVO>();
              BoardVO vo = new BoardVO();
             vo.setId(1);
             vo.setTitle("야야야1");
             vo.setSearchCondition("하후");
             vo.setWriter("홍길동");
             vo.setRegDate(java.sql.Date.valueOf("2010-02-01"));
  
             boardList.add(vo);
  
            vo = new BoardVO();
            vo.setId(2);
            vo.setTitle("야야야2");
            vo.setSearchCondition("하후");
            vo.setWriter("홍길동");
            vo.setRegDate(java.sql.Date.valueOf("2010-03-01"));
            boardList.add(vo);
  
            BoardListVO boardListVO = new BoardListVO();
            boardListVO.setBoardList(boardList);
  
            System.out.println("가동중");
  
             return boardListVO;
        }
  
}


파일명: HomeController.java


[첨부(Attachments)]

HomeController.zip



5. BoardVO.java (com.website.example.vo)


package com.website.example.vo;

import java.sql.Date;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlTransient;


@XmlAccessorType(XmlAccessType.FIELD)
public class BoardVO {


         @XmlAttribute        // 사용 할 속성
         private int id;
         private String title;
         private String writer;
         private String content;
         private Date regDate;
 
        @XmlTransient        // 사용 안함
         private String searchCondition;
 
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getTitle() {
  return title;
 }
 public void setTitle(String title) {
  this.title = title;
 }
 public String getWriter() {
  return writer;
 }
 public void setWriter(String writer) {
  this.writer = writer;
 }
 public String getContent() {
  return content;
 }
 public void setContent(String content) {
  this.content = content;
 }
 public Date getRegDate() {
  return regDate;
 }
 public void setRegDate(Date regDate) {
  this.regDate = regDate;
 }
 public String getSearchCondition() {
  return searchCondition;
 }
 public void setSearchCondition(String searchCondition) {
  this.searchCondition = searchCondition;
 }
 
 
 
}


파일명: BoardVO.java


[첨부(Attachments)]

BoardVO.zip

HomeController.zip



6. BoardListVO.java (com.website.example.vo)


package com.website.example.vo;

import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "boardList")
@XmlAccessorType(XmlAccessType.FIELD)
public class BoardListVO {


       @XmlElement(name = "board")
        private List<BoardVO> boardList;
 
        public List<BoardVO> getBoardList(){
                 return this.boardList;
        }
 
        public void setBoardList(List<BoardVO> boardList) {
                 this.boardList = boardList;
        }
 
}


파일명: BoardListVO.java


[첨부(Attachments)]

BoardListVO.zip



7. 출력 결과


스프링에서 출력한 XML이다.



그림 2. 출력 결과


BoardVO.zip

HomeController.zip



*음글(Conclsuion)


스프링 프레임워크로 Jaxb2 외 다수 라이브러리를 활용하여 XML을 생성하였다.



* 참고자료(References)


1. A Guide to JAXB Annotations - HowToDoInJava, https://howtodoinjava.com/jaxb/jaxb-annotations/, Accessed by 2020-10-11, Last Modified 2019-02.


2. [Java] JAXB 활용한 Java 객체의 XML 변환 방법, https://haenny.tistory.com/8, Accessed by 2020-10-11, Last Modified 2019-07-09.


반응형
728x90
300x250

[JSP] 28. Maven (Jaxb-runtime, activation, Jaxb Api, JSTL)을 활용한 XML 생성하기


JSP/Servlet으로도 Jaxb2와 각종 Library를 활용하여 XML을 생성할 수 있다.

일반 프로그래밍은 많이 접하였으나, XML은 잘 접해보지 않을 수도 있다.






1. XML을 JSP 파일에 수작업으로 입력하기


XML을 만드는 방법에는 수작업으로 하는 방법이 있겠다.


<xml>

<hama>

     <board>

     </board>

     <board>

     </board>

     <board>

     </board>

</hama>


예를 들면 이런 형태를 JSP에서 for문 등으로 VO를 읽어와서 뿌려주는 방법이 있겠다.

원시적인 방법이고, 자료가 3중, 4중으로 된 것을 처리하고자 했을 때는 수행빈도가 높아지는 단점이 있다.

코드도 복잡해진다.


물론 DB형태에 보관된 자료로 뿌릴 수도 있다.



<%@ page language="java" contentType="text/xml"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!-- 수작업으로 XML 규격을 만들어야 함. -->
<boardList>
 <board>
  <hello>asdf</hello>
 </board>
</boardList>


파일명: xml.jsp


[첨부(Attachments)]

xml.zip




2. JSP/Servlet - Maven Project


org.apache.maven.archetypes    |  maven-archetype-webapp    | 1.4(1.0)를 선택한다.


그림 1. JSP/XML 프로젝트 구성도




3. Java Compiler, Build Path, Project Factes


* Java Compiler - compiler compliance level 1.8
* Build Path -> JRE System Library 1.8
* Project Factes - Java : 1.8



4. Pom.xml 설정


Spring Framework에서도 <dependency>부분은 그대로 사용이 가능하다. (태스트 완료함)

pom.xml에 정의했던 라이브러리를 그대로 사용하는 것이다.

단, 출력하려고 했을 때, Jaxb에 대한 직접 출력을 정의하냐 안 하느냐 이런 차이가 있다.


 <!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
 <dependency>
     <groupId>javax.servlet</groupId>
     <artifactId>servlet-api</artifactId>
     <version>2.5</version>
     <scope>provided</scope>
 </dependency>
 
 <!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api -->
 <dependency>
     <groupId>javax.xml.bind</groupId>
     <artifactId>jaxb-api</artifactId>
     <version>2.3.0-b170201.1204</version>
 </dependency>
 
 <!-- https://mvnrepository.com/artifact/javax.activation/activation -->
 <dependency>
     <groupId>javax.activation</groupId>
     <artifactId>activation</artifactId>
     <version>1.1</version>
 </dependency>
 
 <!-- https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime -->
 <dependency>
     <groupId>org.glassfish.jaxb</groupId>
     <artifactId>jaxb-runtime</artifactId>
     <version>2.3.0-b170127.1453</version>
 </dependency>

 
 <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
 <dependency>
     <groupId>javax.servlet</groupId>
     <artifactId>jstl</artifactId>
     <version>1.2</version>
 </dependency>


파일명: pom.xml


[첨부(Attachments)]

pom.zip



5. BoardVO.java (com.website.example.vo)


package com.website.example.vo;

import java.sql.Date;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlTransient;


@XmlAccessorType(XmlAccessType.FIELD)
public class BoardVO {


        @XmlAttribute   // 보여줄 항목이다. 이런 뜻
         private int id;
         private String title;
         private String writer;
         private String content;
         private Date regDate;
 
        @XmlTransient    // 출력하지 않겠다.
         private String searchCondition;
 
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getTitle() {
  return title;
 }
 public void setTitle(String title) {
  this.title = title;
 }
 public String getWriter() {
  return writer;
 }
 public void setWriter(String writer) {
  this.writer = writer;
 }
 public String getContent() {
  return content;
 }
 public void setContent(String content) {
  this.content = content;
 }
 public Date getRegDate() {
  return regDate;
 }
 public void setRegDate(Date regDate) {
  this.regDate = regDate;
 }
 public String getSearchCondition() {
  return searchCondition;
 }
 public void setSearchCondition(String searchCondition) {
  this.searchCondition = searchCondition;
 }
 
 
 
}


파일명: BoardVO.java


[첨부(Attachments)]

BoardVO.zip


- 게시판 DB에서도 사용한다고 가정하자.



6. BoardListVO.java (com.website.example.vo)


package com.website.example.vo;

import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "boardList")
@XmlAccessorType(XmlAccessType.FIELD)
public class BoardListVO {


         @XmlElement(name = "board")
         private List<BoardVO> boardList;
 
         public List<BoardVO> getBoardList(){
               return this.boardList;
         }
 
         public void setBoardList(List<BoardVO> boardList) {
               this.boardList = boardList;
         }
 
}


파일명: BoardListVO.java


[첨부(Attachments)]

BoardListVO.zip


루트 RootElement를 정의해줘야 XML 출력을 할 수 있는데, 출력을 그냥하는 건 아니고, List 형태로 구성된 VO(Value Object)를 출력하는 것이다.




7. HomeController.java (com.website.example.controller)


밑줄 친 부분들이 중요한 부분이다.


package com.website.example.controller;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import com.website.example.vo.BoardListVO;
import com.website.example.vo.BoardVO;


public class FrontController extends HttpServlet {
 private static final long serialVersionUID = 1L;
      
 
 protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
  
            res.setContentType("text/xml;charset=utf-8");
    
            String result = setXmlData();
            PrintWriter out = res.getWriter();
  
            out.println(result);
  
            out.flush();
            out.close();

 }

 /**
  * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
  */
 protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
  
 }
 
        public String setXmlData(){
  
                 JAXBContext jc = null;
                 Marshaller marshaller = null;
   
                 List<BoardVO> boardList = new ArrayList<BoardVO>();
                 BoardListVO boardListVO = new BoardListVO();
  
                 OutputStream os = new ByteArrayOutputStream();

                 BoardVO vo = new BoardVO();
  
                 try {
                      jc = JAXBContext.newInstance(BoardListVO.class);
    
                 } catch (JAXBException e) {
                      e.printStackTrace();
                 }

                 vo.setId(1);
                 vo.setTitle("야야야1");
                 vo.setSearchCondition("하후");
                 vo.setWriter("홍길동");
                 vo.setRegDate(java.sql.Date.valueOf("2010-02-01"));
  
  boardList.add(vo);
  
  vo = new BoardVO();
  vo.setId(2);
  vo.setTitle("야야야2");
  vo.setSearchCondition("하후");
  vo.setWriter("홍길동");
  vo.setRegDate(java.sql.Date.valueOf("2010-03-01"));

               boardList.add(vo);

               boardListVO.setBoardList(boardList);
  
                try {
                       marshaller = jc.createMarshaller();
                       marshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8");
                       marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
   
                       // marshaller.marshal(boardListVO, System.out);
                       marshaller.marshal(boardListVO, os);
   
                } catch (JAXBException e) {
                       e.printStackTrace();
    
                }

  
                // System.out.println("XML출력:" + os.toString());
   
                return os.toString();

  
        }

}


파일명: FrontController.java


[첨부(Attachments)]

FrontController.zip




8. web.xml (/src/main/webapp/WEB-INF/web.xml)


<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
   <servlet-name>FrontController</servlet-name>
   <display-name>FrontController</display-name>
   <description></description>
   <servlet-class>com.website.example.controller.FrontController</servlet-class>
  </servlet>
  <servlet-mapping>
           <servlet-name>FrontController</servlet-name>
           <url-pattern>/dataTransform.do</url-pattern>
  </servlet-mapping>
</web-app>


파일명: web.java


[첨부(Attachments)]

web.zip



9. 출력 결과


완성된 결과물이다.



그림 2. XML.jsp 파일 (수작업 방법)



그림 3. Jaxb2 외 다수 라이브러리로 적



* 맺음글(Conclusion)


JSP/Servlet 기반에서 XML 출력하는 방법에 대해서 살펴보았다.

반응형
728x90
300x250
[Spring Framework] 41. Spring 방식의 파일 업로드, 다운로드(Commons-io, FileUpload) - (XML, Java)


업로드에 관한 내용이다.

방식이 두 가지가 있다. 셋팅에 있어서 다소 차이가 있을 수 있다.


수 차례 실험을 해본 결과로는 Java 방식을 사용하고자 했을 때는 CGLib를 추가로 넣어줘야 한다.


[참고]

해당 코드는 Spring Framework 내에서만 동작하는 방법이다.

JSP/Servlet 업로드, 다운로드 관련해서는 JSP 카테고리에서 살펴보면 되겠다.


[개발 환경]

* IDE: Eclipse 2020-06

* Framework:

  - Spring Framework 4.2.4 RELEASES

  - commons-fileupload (2.8)

  - commons-io (1.4)
  - CGLIB (3.3.0) - Java 환경 설정 방식만 해당 [의외로 사용 빈도가 있는 jar 파일이다.]

    (RootConfig.java 파일과 Beans 등 사용하면 필요할 때가 있음.)


  - Java Version 1.8 (OpenJDK 15)






1. 프로젝트 구성도


공통적으로 작성한 파일은 한번만 소개하고 변경된 사항들만 분리 요약해서 작성하도록 하겠다.

"FileController.java" / 공통

"HomeController.java" / 공통

"insert.jsp" / 공통


 


 

 그림 1. XML 파일 방식

 그림 2. Java 방식




2. Java Compiler, Build Path, Project Desc (공통)


* Java Compiler - compiler compliance level 1.8
* Build Path
               - Add Jar로 ojdbc.jar 파일 등록해주기

* Project Factes - Java : 1.8



3. pom.xml (XML, Java 방식)


 

 (중략)


    <properties>
         <java-version>1.8</java-version>
         <org.springframework-version>4.2.4.RELEASE</org.springframework-version>
         <org.aspectj-version>1.6.10</org.aspectj-version>
         <org.slf4j-version>1.6.6</org.slf4j-version>
    </properties>

 (중략)
 공통 - pom.xml

 
  <!-- https://search.maven.org/artifact/commons-fileupload/commons-fileupload/1.4/jar -->

  <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.8.0</version>
  </dependency>

 
  <!-- https://search.maven.org/artifact/commons-fileupload/commons-fileupload/1.4/jar -->

  <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.8.0</version>
  </dependency>
   

  <!-- 자바 방식 - FileUpload에서는 CGLIB 넣어줘야 함 -->
  <!-- https://mvnrepository.com/artifact/cglib/cglib -->
  <dependency>
      <groupId>cglib</groupId>
      <artifactId>cglib</artifactId>
      <version>3.3.0</version>
  </dependency>
  

 XML 방식 - pom.xml

 Java 방식 - pom.xml


하나 차이 밖에 없는데, cglib 라이브러리가 있느냐 없느냐 이런 차이인데, 그냥 다 써도 무방하다.

분리해서 소개한 이유는 최소의 라이브러리로 돌아가는지 태스트 해보려고 그랬다.


디버그 창에 종종 스프링 작업을 하면, 오류로 라이브러리가 필요하다고 올라오는데 그런 예기치 못한 작업들도 생각할 수 있으면 좋겠다.




4. insert.jsp (공통)


스프링을 공부하면서 연습 템플릿이 여의치 않아서 삽질을 다소 많이 하였다.


<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page session="false" %>
<html>
<head>
 <meta charset="UTF-8">
 <title>File Upload - Insert 페이지</title>
</head>
<body>
<h1>
 Hello world! 
</h1>
 
<h1>파일 업로드</h1>
<form action="fileupload" method="post" enctype="multipart/form-data">
    <input type="file" name="uploadfile" placeholder="파일 선택" /><br/>
    <input type="submit" value="업로드">
</form>

<h2>다중 파일 업로드</h2>
<form action="fileupload2" method="post" enctype="multipart/form-data">
    <input type="file" name="uploadfiles" placeholder="파일 선택" multiple/><br/>
    <input type="submit" value="업로드">
</form>

</body>
</html>


파일명: insert.jsp


[첨부(Attachments)]

insert.zip



[비고]

5, 6번(XML, Java 설정) 방식을 하는데 있어서 두 가지를 동시에 설정하면 충돌날 가능성이 있다.

주의해서 사용할 것을 권장한다.




5. 흔히 많이 알려진 XML 설정 방식


두 가지 셋팅을 해놓으면 간단하게 끝난다.

2가지 설정을 통해서 xml 셋팅이 간단하고 좋아보일 수도 있으나 라이브러리마다 셋팅의 양이 다양하고 복잡해지는 문제도 있다.

(지금 생각할 필요는 없음.)



1. root-context.xml (/src/main/webapp/WEB-INF/spring/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"
 xmlns:mvc="http://www.springframework.org/schema/mvc"
 xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
  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 -->
 <!-- MultipartResolver -->
 <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
     <property name="maxUploadSize" value="100000000"/>  <!-- 10MB-->
     <property name="maxInMemorySize" value="100000000"/> <!-- 10MB-->
  <!-- <property name="uploadTempDir" value=“0"/> -->
 </bean>
 
 
 <!-- 외부 경로를 찾는 방식은 동작하지 않음. -->
 <!--  외부 경로 찾는 방식으로 다운로드를 구현하려면, 다운로더를 하나 구현하는 것이 빠름. -->
 <!-- 다운로드 경로는 servlet-context.xml에 넣어야 함. 이중 선언이 되어서 동작 안함. -->
 <!--
 <mvc:annotation-driven />
   
    <mvc:resources mapping="/static2/**" location="file:///c:/temp/" />
 <mvc:default-servlet-handler />
 -->
 
</beans>


파일명: root-context.xml


[첨부(Attachments)]

root-context.zip




2. servlet-context.xml (/src/main/webapp/WEB-INF/spring/appServlet/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/" />
 
 <!-- 다운로드 외부 경로 -->
 <resources mapping="/static2/**" location="file:///c:/temp/" />


 <!-- 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:bean>
 
 <context:component-scan base-package="com.website.example" />
 
 
</beans:beans>


파일명: servlet-context.xml


[첨부(Attachments)]

servlet-context.zip


[Resources Mapping 관련]

밑줄 친 이 코드는 다운로드 위치(자원)를 맵핑해주는 명령어이다.

servlet-context.xml에 넣어야만 동작한다.


<mvn:resource......> 이렇게 해버리면, 돌아가지 않는다.


[유의할 점 - servlet-context.xml 이외의 파일에서 사용하고자 했을 때]

코드에 오류는 안 나는데, 동작이 안되는 당황스러운 일도 있다. 

관리차원에서 파일을 하나 별도로 xml파일을 하나 생성해서, 구현을 해버리면 되어야 하는데 파일 자체에는 오류도 안 나고,

서버에 컴파일해서 올린 후 호출하면 오류가 뜨는 경우가 있다.


servlet-context.xml 파일이 수동 셋팅에서는 중요하다.




6. Java 설정 방식


RootWebConfig.java 파일 하나만 만들어놓으면, 추가 셋팅 할 필요없이 자동으로 인식해준다.

(인식해주는 이유는 "extends WebMvcConfigurerAdapter" 이 한 줄이 추가되서 그렇다.)

별도로 셋팅해줄 필요는 없다.


package com.website.example.common;

import java.io.File;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;


@Configuration
@Import({FileConfig.class})
@ComponentScan(basePackages = {"com.website.example"})
@EnableWebMvc
//@ComponentScan(basePackages = {"com.local.example.beans", "com.local.example.advisor"})


public class RootWebConfig extends WebMvcConfigurerAdapter {

          

        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
              registry.addResourceHandler("/static/**").addResourceLocations("file:c:" + File.separator + "temp/");
        }

}


파일명: RootWebConfig.java


[첨부(Attachments)]

RootWebConfig.zip



package com.website.example.common;

import java.io.File;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;


@Configuration
public class FileConfig {
 
     @Bean
     public MultipartResolver multipartResolver() {

           org.springframework.web.multipart.commons.CommonsMultipartResolver multipartResolver = new                

                  org.springframework.web.multipart.commons.CommonsMultipartResolver();
    
                  multipartResolver.setMaxUploadSize(100000000);
                  multipartResolver.setMaxInMemorySize(100000000); // 10MB
                  return multipartResolver;
      }
 
}


파일명: FileConfig.java


[첨부(Attachments)]

FileConfig.zip



7. FileController.java (/com/website/example)


package com.website.example;

import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
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 org.springframework.web.multipart.MultipartFile;

@Controller
public class FileController {
 
         private static final Logger logger = LoggerFactory.getLogger(FileController.class);
 
         private final String UPLOAD_PATH = "c:" + File.separator + "temp" + File.separator;

         
         @RequestMapping(value = "/insert", method = RequestMethod.GET)
         public String insert(Locale locale, Model model) {
                   logger.info("Welcome home! The client locale is {}.", locale);
  
                   return "insert";
         }
 
         @RequestMapping(value = "/fileupload",method = RequestMethod.POST)
         public String upload(MultipartFile uploadfile, Model model) throws IOException{
  
                   logger.info("upload() POST 호출");
                   logger.info("파일 이름: {}", uploadfile.getOriginalFilename());
                   logger.info("파일 크기: {}", uploadfile.getSize());

              
                   String result = saveFile(uploadfile);
    
                   if(result !=null){ // 파일 저장 성공
      
                        model.addAttribute("result", result);
        
                   } else { // 파일 저장 실패
      
                        model.addAttribute("result","fail");
        
                   }
    
                   return "home";

         }
 
         @RequestMapping(value = "/fileupload2", method = RequestMethod.POST)
         public String multiupload(@RequestParam("uploadfiles") MultipartFile[] file, Model model) throws IOException {
  
                  logger.info("Welcome multi file! The client locale is {}.", "Hello");
   
                  String result = "";
    
                  for(MultipartFile f : file){
                       result += saveFile(f);
                  }
    
                  return "home";
         }
 

         private String saveFile(MultipartFile file) throws IOException{
 
                // 파일 이름 변경
                UUID uuid = UUID.randomUUID();
                String saveName = uuid + "_" + file.getOriginalFilename();
 
                logger.info("saveName: {}",saveName);

                String fileName = file.getOriginalFilename();
                String contentType = file.getContentType();
                long filesize = file.getSize();
                // byte[] bytes = file.getBytes();
       
               //System.out.println("파일명:" + fileName);
               //System.out.println("컨텐츠 타입:" + contentType);
               //System.out.println("파일크기:" + filesize);
    
               // 저장할 File 객체를 생성(껍데기 파일)ㄴ
               File saveFile = new File(UPLOAD_PATH, saveName); // 저장할 폴더 이름, 저장할 파일 이름
 
               try {
                     file.transferTo(saveFile); // 업로드 파일에 saveFile이라는 껍데기 입힘
               } catch (IOException e) {
                     e.printStackTrace();
                     return null;
               }
 
               return saveName;
       }
 
}


파일명: FileController.java


[첨부(Attachments)]

FileController.zip



8. 출력 결과


동일한 결과를 볼 수 있다. 동일한 작업이기 때문이다.

차이점은 내부적인 관점에서 셋팅을 어떻게 했느냐 이런 문제라고 보겠다.



그림 3. (결과 1) 단일 업로드 모습



그림 4. (결과 1) 단일 업로드 모습 - 실제 파일 업로드 모습



그림 5. (결과 2) 다중 업로드 모습 - 실제 파일 업로드 모습



그림 6. (결과 2) 다중 업로드 모습 - 실제 파일 업로드 모습 - 폴더 모습


FileController.zip



* 맺음글(Conclusion)


Spring Framework 방식으로 Commons-io, Commons-FileUpload, CGLIB를 활용하여 업로드 프로그램을 구현하였다.

참고로 이 방식은 Spring Framework에서만 동작하는 방법이다.



반응형
728x90
300x250
[Spring Framework] 39. Beans와 Context-XML 방식으로 DB 설정 그리고 Autowired - (Web.xml)


글 제목이 다소 길긴 하지만, 좋은 주제라고 본다.


[직접 관련 글]
1. [Spring-Framework] 38. Beans와 Context-XML 방식으로 DB 설정 - (Junit5), 2020-10-10

- https://yyman.tistory.com/1463


스프링 프레임워크의 Autowired 기능을 알게 된다면, 상당히 편하다는 것을 체감할 수 있을 것이다.

어노테이션 정의로 @Autowired 하나 적었을 뿐인데 자동으로 복잡하게 생성자 만들고, 불러오는 작업을 안 해도 되는 신기한 일들이 생긴다.


실질적인 코딩 작업할 때의 단점은 물론 오류가 잘 표기되지 않아서 적용이 되었는지 안 되었는지 모른다.

적용이 되면, 관련된 코드를 찍어보면 보이는데, 편리한 이면에는 이런 문제도 있을 수 있다.


어떤 사람은 좋다고 하고, 어떤 사람은 애매하다고 하고 관점이 워낙 다양하니깐 중략한다.


[참고]
* POM 설정, Project 설정의 (Java Compiler, Build Path, Project Factes), Oracle JDBC.jar 셋팅 작업 등 완료되어야 함.

38번 글로 가서 작업하고 오면, 작업을 따라할 수 있다.




1. 프로젝트 구성도


이전 38번 글(38. Beans와 Context-XML 방식으로 DB 설정 - (Junit5), 2020-10-10)의 내용에서 살짝 몇 가지만 해주면 끝난다.

암기가 안 되서 문제이지 셋팅 배경 원리는 똑같다.



그림 1. 프로젝트 구성도




2. root-context.xml(src/main/webapp/WEB-INF/spring/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"
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
  http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">

 <context:component-scan base-package="com.website.example" />

 <aop:aspectj-autoproxy></aop:aspectj-autoproxy>


 <!-- DataSource 설정 -->
 <context:property-placeholder location="classpath:db.properties" />


 <!-- DataSource 셋팅 -->
    <bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close">
        <property name="URL" value="${ORACLE_DB_URL}" />
        <property name="user" value="${ORACLE_DB_USERNAME}"/>
        <property name="password" value="${ORACLE_DB_PASSWORD}"/>
        <property name="connectionCachingEnabled" value="true"/>
    </bean>
   
 <!-- Spring JDBC 설정 -->
 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
  <property name="dataSource" ref="dataSource" />
 </bean>
 
 <!-- Transaction 설정 -->
 <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource"></property>
 </bean>

 
 <!-- 추후 지원 AOP 트랜젝션 구현할 때?? -->
 <tx:advice id="txAdvice" transaction-manager="txManager">
      <tx:attributes>
          <tx:method name="get*" read-only="true"/>
          <tx:method name="*"/>
     </tx:attributes>
 </tx:advice>
 
 <aop:config>
        <aop:pointcut id="txPointcut"  expression="execution(* com.website.example.service.DBService..*(..))"/>
     
        <aop:advisor pointcut-ref="txPointcut" advice-ref="txAdvice"/>
 </aop:config>
 
</beans>


파일명: root-context.xml


[첨부(Attachments)]

root-context.zip

root-context_orginal.zip (작업 따라하면서 실수 예방용 원본 파일)




3. HomeController.java(com/website/example)


package com.website.example;

import java.sql.Connection;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import javax.sql.DataSource;

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


/**
 * Handles requests for the application home page.
 */
@Controller
public class HomeController {
 
        private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
 
        @Autowired
        private DataSource dataSource;   // 이게 끝임. (root-context.xml에서 클래스 셋팅을 불러와 버림.)
  

       /**
        * 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);
  
             if ( dataSource != null ) {
                  System.out.println("야2");
             }
  
             try(Connection con = dataSource.getConnection()){
                  System.out.println("참");
   
             }catch(Exception e)
             {
                  //fail(e.getMessage());
                 System.out.println("거짓");
   
             }
  
             model.addAttribute("serverTime", formattedDate );
  
             return "home";
       }
 
}


파일명: HomeController.java


[첨부(Attachments)]

HomeController.zip



4. 결과(Result)


Autowired를 경험할 수 있도록 구현한 것을 시연하였다.



영상 1. Spring Framework의 @Autowired 시연



* 맺음글(Conclusion)


Beans와 Context-xml 방식으로 DB설정하는 방법에 대해서 소개하였다.


반응형

+ Recent posts