2021년 10월 16일 토요일

[자바]Google Report API를 이용한 사이트 통계정보 가져오기, 성별, 페이지제목별, 연령구간대별,브라우저별,OS별,모바일디바이스 브랜드별로 페이지뷰, 접속사용자수, 접속세션수

 [자바]Google Report API를 이용한 사이트 통계정보 가져오기, 성별, 페이지제목별, 연령구간대별,브라우저별,OS별,모바일디바이스 브랜드별로 페이지뷰, 접속사용자수, 접속세션수 


원본 : http://ojc.asia/bbs/board.php?bo_table=LecJava&wr_id=774

 

[1단계]

 

구글 통계 정보를 조회해서 API를 이용해 데이터를 자지고 오려면 

 

1. https://console.cloud.google.com/identity/serviceaccounts?folder=&organizationId=&project=top-creek-300922&supportedpurview=project

에서 사용자 추가아래 이메일이 그렇게 해서 만듦그리고 키파일 생성함

키파일은 자바 프로그램에서 사용하니 잘 보관해야 함

 

54be5713875141a7eb5af4712eb16aba_1610076
 

 

2. 위 사용자에 대해 구글 애널리틱스의 관리자에서 조회권한을 줘야 함

 

54be5713875141a7eb5af4712eb16aba_1610076
 

첫화면 좌하단 관리자 클릭

보기 à 보기 사용자관리 여기서 위에서 생성한 계정의 이메일을 통해 사용자 조회 권한을 부여함

 

54be5713875141a7eb5af4712eb16aba_1610077
 

 

[2단계, 자바코드 작성하기]

 

1. 마리아DB 테이블

 

CREATE TABLE T_GA_STATS(

start_ymd VARCHAR(8) ,

             end_ymd VARCHAR(8) ,

dimension VARCHAR(50),

             dim_val   VARCHAR(900),

page_views INT ,

             users INT ,

             sessions INT, 

reg_dt DATETIME DEFAULT CURRENT_TIMESTAMP,

mdfcn_dt DATETIME DEFAULT CURRENT_TIMESTAMP,

    PRIMARY KEY(start_ymd, end_ymd, dimension, dim_val)

)ENGINE = InnoDB  CHARACTER SET utf8;

 

 

2. ga.properties

 

#VIEW ID, 구글 애놀리틱스 화면에서 좌상 단 "전체웹사이트 데이터" 선택 후 팝업화면에서 오른쪽 전체웹사이트 데이터아래 숫자 입니다.

view.id=22931XXXX

 

#Key File Location, 파일명은 사용자 마다 다릅니다. 위 1에서 사용자 등록하고 키파일 만든 바로 그것 입니다.

key.file.location=c:\\/top-creek-3030922-ca1xbabc22484.json

 

#----------------------------------- Metric(측정항목) Start

#페이지뷰 Expression

metric1.expression=ga:pageviews

 

#페이지뷰 alias

metric1.alias=pageviews

 

#사용자수 Expression

metric2.expression=ga:users

 

#사용자수 alias

metric2.alias=users

 

#세션수 Expression

metric3.expression=ga:sessions

 

#세션수 alias

metric3.alias=sessions

#----------------------------------- Metric(측정항목) End

 

 

#----------------------------------- Dimension(측정기준) Start

#성별

dim1=ga:userGender

 

#페이지 제목별

dim2=ga:pageTitle

 

#연령 구간대별

dim3=ga:userAgeBracket

 

#브라우저별

dim4=ga:browser

 

#OS별

dim5=ga:operatingSystem

 

#모바일 디바이스 브랜드별

dim6=ga:mobileDeviceBranding

 

#기기별

dim7=ga:deviceCategory

#----------------------------------- Dimension(측정기준) End

 

3. mybatis-config.xml

 

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD config 3.0//EN" 

"http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

 

<!-- DB설정 파일 로딩 -->

<properties resource="db.properties" />

 

<typeAliases>

<typeAlias alias="GaStatsVO" type="jmx.vo.GaStatsVO" /> 

</typeAliases>

 

<!-- db1 : 마리아DB 연결 -->

<environments default="development">

<environment id="development">

<transactionManager type="JDBC" />

<dataSource type="POOLED">

<property name="driver" value="${db1.driver}" />

<property name="url" value="${db1.url}" />

<property name="username" value="${db1.id}" />

<property name="password" value="${db1.password}" />

<property name="poolPingQuery" value="select 1"/> <!-- 핑쿼리 추가 -->

<property name="poolPingEnabled" value="true"/> <!-- 핑쿼리 추가 -->

<property name="poolPingConnectionsNotUsedFor" value="7200000"/> <!-- 2시간마다 -->

<property name="poolMaximumActiveConnections" value="200"/> <!-- 주어진 시간에 존재할수 있는 활성화된 커넥션 수 -->

<property name="poolMaximumIdleConnections" value="200"/> <!-- 주어진 시간에 존재할 수 있는 유휴 커넥션의 수 -->

<property name="poolTimeToWait" value="20000"/> <!-- 풀이 로그 상태를 출력하고 비정상적으로 긴경우 커넥션을 다시얻을려고 시도하는 로우 레벨 셋팅 --> 

</dataSource>

</environment>

</environments>

 

<mappers>

<mapper resource="mapper/gastats.xml" />

</mappers>

 

</configuration>


4. 

GaStatsVO.java


package jmx.vo;

 

import lombok.Data;

 

/* ----------------------------------------------------------------------------

 *  File Name : GaStatsVO.java

 *  Desc : 구글 통계정보를 저장하기 위한 VO

 * ----------------------------------------------------------------------------

 */

@Data

public class GaStatsVO {

// 통계 시작년월일

private String start_ymd;

// 통계 종료년월일

private String end_ymd;

// 측정기준(성별, 브라우저별, OS별...... 접속현황, 이때 성별 이런것이 Dimension)

private String dimension;

// 측정기준값(male, female)

private String dim_val;

// 페이지뷰

private String page_views;

// 접속사용자수

private String users;

// 접속 세션수

private String sessions;

// 등록일시

private String reg_date;

// 수정일시

private String mdfcn_dt;

}

 

5. 매퍼 인터페이스(GaStatsMapper.java)

 

package jmx.db.mapper;

 

import jmx.vo.GaStatsVO;

 

/* ----------------------------------------------------------------------------

 *  File Name : GaStatsMapper.java

 *  Desc : 구글 통계정보 저장(T_GA_STATS)용 매퍼 인터페이스 

 * ----------------------------------------------------------------------------

 */

public interface GaStatsMapper {

// T_GA_STATS 입력(구글 통계정보)

public void insertGaStats(GaStatsVO gaStatsVO);

// T_GA_STATS 삭제(구글 통계정보)

public void deleteGaStats(GaStatsVO gaStatsVO);

}



6. DAO(GaStatsDAO.java)

 

package jmx.db.dao;

 

import org.apache.ibatis.session.SqlSession;

import org.apache.ibatis.session.SqlSessionFactory;

import org.apache.log4j.LogManager;

import org.apache.log4j.Logger;

 

import jmx.db.mapper.GaStatsMapper;

import jmx.vo.GaStatsVO;

 

/* ----------------------------------------------------------------------------

 *  File Name : GaStatsDAO.java

 *  Desc : 구글 통계정보를 DB에 저장

 * ----------------------------------------------------------------------------

 */

public class GaStatsDAO {

 

final static Logger logger = LogManager.getLogger(GaStatsDAO.class);

private SqlSessionFactory sqlSessionFactory = null;

private SqlSession session = null;

 

public void getSession() {

sqlSessionFactory = DBConnectionFactory.getSqlSessionFactory();

session = sqlSessionFactory.openSession();

}

/**

 * 구글 통계정보 저장

 * @param gaStatsVO

 * @throws Exception 

 */

public void insertGaStats(GaStatsVO gaStatsVO) throws Exception {

 

getSession();

GaStatsMapper mapper = session.getMapper(GaStatsMapper.class);

try {

mapper.insertGaStats(gaStatsVO);

catch(Exception e) {

session.rollback();

logger.info(">>>> insertGaStats Insert ERROR ::: " + e);

throw new Exception("insertGaStats Insert ERROR" + e.getMessage());

}

finally {

session.commit();

session.close();

session = null;

}

}

/**

 * 구글 통계정보 삭제

 * @param gaStatsVO

 * @throws Exception 

 */

public void deleteGaStats(GaStatsVO gaStatsVO) throws Exception {

 

getSession();

GaStatsMapper mapper = session.getMapper(GaStatsMapper.class);

try {

mapper.deleteGaStats(gaStatsVO);

catch(Exception e) {

session.rollback();

logger.info(">>>> deleteGaStats Delete ERROR ::: " + e);

throw new Exception("deleteGaStats Delete ERROR" + e.getMessage());

}

finally {

session.commit();

session.close();

session = null;

}

}

 

}



7. resource 아래 mapper 아래 매퍼 XML(gastats.xml)


<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE mapper PUBLIC '-//mybatis.org//DTD Mapper 3.0//EN'

<mapper namespace='jmx.db.mapper.GaStatsMapper'>

<!-- 구글 통계정보 저장 -->
<insert id='insertGaStats' parameterType='GaStatsVO'>
INSERT INTO T_GA_STATS (
 START_YMD
,END_YMD
,DIMENSION
,DIM_VAL
,PAGE_VIEWS
,USERS
,SESSIONS
)
VALUES(
 #{start_ymd}
,#{end_ymd}
,REPLACE(#{dimension},'ga:', '')
,#{dim_val}
,CAST(#{page_views} AS UNSIGNED)
,CAST(#{users} AS UNSIGNED)
,CAST(#{sessions} AS UNSIGNED)
)
</insert>
<!-- 구글 통계정보 삭제 -->
<delete id='deleteGaStats' parameterType='GaStatsVO'>
DELETE FROM T_GA_STATS 
WHERE  START_YMD = #{start_ymd}
AND    END_YMD   = #{end_ymd}
</delete>
</mapper>


7. 구글 통계정보 읽기

package batch;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Properties;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.analyticsreporting.v4.AnalyticsReporting;
import com.google.api.services.analyticsreporting.v4.AnalyticsReportingScopes;
import com.google.api.services.analyticsreporting.v4.model.ColumnHeader;
import com.google.api.services.analyticsreporting.v4.model.DateRange;
import com.google.api.services.analyticsreporting.v4.model.DateRangeValues;
import com.google.api.services.analyticsreporting.v4.model.Dimension;
import com.google.api.services.analyticsreporting.v4.model.GetReportsRequest;
import com.google.api.services.analyticsreporting.v4.model.GetReportsResponse;
import com.google.api.services.analyticsreporting.v4.model.Metric;
import com.google.api.services.analyticsreporting.v4.model.MetricHeaderEntry;
import com.google.api.services.analyticsreporting.v4.model.Report;
import com.google.api.services.analyticsreporting.v4.model.ReportRequest;
import com.google.api.services.analyticsreporting.v4.model.ReportRow;

import jmx.db.dao.GaStatsDAO;
import jmx.vo.GaStatsVO;

/* ----------------------------------------------------------------------------
 *  File Name : GAStatistics.java
 *  Desc : 구글 통계정보 가지고 와서 DB 저장
 * ----------------------------------------------------------------------------
 */
public class GaStatistics {
// 화면 ID(22931XXXX로 고정)
private String viewId = null;
// 키파일 위치
private String keyFileLocation = null;
//----------------------------------- Metric(측정항목) Start
//측정항목1
private String metric1Expression = null;
private String metric1Alias = null;
//측정항목2
private String metric2Expression = null;
private String metric2Alias = null;
//측정항목3
private String metric3Expression = null;
private String metric3Alias = null;
//----------------------------------- Dimension Start
private String dim1 = null;
private String dim2 = null;
private String dim3 = null;
private String dim4 = null;
private String dim5 = null;
private String dim6 = null;
private String dim7 = null;

// GAStatistics 클래스가 new 될때 호출되는 초기화 블럭
{
// 구글 통뎨정보 가지고 오기 위한 설정 파일
loadProperties();
}

private String APPLICATION_NAME = "서구 Analytics Reporting";
private JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();

final static Logger logger = LogManager.getLogger(GaStatistics.class);
public static void main(String[] args) {
if (args.length < 2) {
System.out.println("기간(일별)을 입력하세요. java batch.GaStatistics 2014-01-01 2020-12-31");
System.exit(1);
}

GaStatistics ga = new GaStatistics();
//기간을 확인
logger.info("::::: " + args[0] + " 부터 " + args[1] + " 까지 구글 통계정보를 가지고 옵니다");
try {
ga.getData(args[0], args[1]);
logger.info("::::: " + args[0] + " 부터 " + args[1] + " 까지 구글 통계정보를 가지고 옵니다");
}
catch(Exception e) {
e.printStackTrace();
}
}

/**
 * Get Google Analytics Statistics Data 
 * @throws Exception
 */
public void getData(String startDate, String endDate) throws Exception {
try {
AnalyticsReporting service = initializeAnalyticsReporting();

// 입력 기간 데이터 삭제
delete(startDate, endDate);
GetReportsResponse response1 = getReport1(service, startDate, endDate);
saveResponse(response1, startDate, endDate);
GetReportsResponse response2 = getReport2(service, startDate, endDate);
saveResponse(response2, startDate, endDate);
} catch (Exception e) {
logger.error(">>>>> 구글 애널리틱스 데이터 수신 오류! ::: " + e.getMessage());
throw new Exception(e);
}
}

/**
 * Initializes an Analytics Reporting API V4 service object.
 *
 * @return An authorized Analytics Reporting API V4 service object.
 * @throws IOException
 * @throws GeneralSecurityException
 */
private AnalyticsReporting initializeAnalyticsReporting() throws GeneralSecurityException, IOException {

HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream(keyFileLocation))
.createScoped(AnalyticsReportingScopes.all());

// Construct the Analytics Reporting service object.
return new AnalyticsReporting.Builder(httpTransport, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME).build();
}

/**
 * Queries the Analytics Reporting API V4.
 * 
 * 주의 : Request의 MAX는 5개, 즉 통계정보를 받기 위한 요청은 최대5개
 *      그래서 getReport1(5개), getReport2(2개) 만듦
 *
 * @param service An authorized Analytics Reporting API V4 service object.
 * @return GetReportResponse The Analytics Reporting API V4 response.
 * @throws IOException
 */
private GetReportsResponse getReport1(AnalyticsReporting service, String startDate, String endDate) throws IOException {
// Create the DateRange object.
DateRange dateRange = new DateRange();
dateRange.setStartDate(startDate);
dateRange.setEndDate(endDate);

// Create the Metrics object.
Metric metric1 = new Metric().setExpression(metric1Expression).setAlias(metric1Alias); // 페이지뷰
Metric metric2 = new Metric().setExpression(metric2Expression).setAlias(metric2Alias); // 사용자수
Metric metric3 = new Metric().setExpression(metric3Expression).setAlias(metric3Alias); // 세션수
Metric metrics[] = new Metric[3];
metrics[0] = metric1;
metrics[1] = metric2;
metrics[2] = metric3;
Dimension dimension1 = new Dimension().setName(dim1); // 성별
Dimension dimension2 = new Dimension().setName(dim2); // 페이지제목별
Dimension dimension3 = new Dimension().setName(dim3); // 연령 구간대별
Dimension dimension4 = new Dimension().setName(dim4); // 브라우저별
Dimension dimension5 = new Dimension().setName(dim5); // OS별
//Dimension dimension6 = new Dimension().setName(dim6); // 모바일디바이스 브랜드별
//Dimension dimension7 = new Dimension().setName(dim7); // 기기(Device)별

// Create the ReportRequest object.
ReportRequest request1 = new ReportRequest().setViewId(viewId).setDateRanges(Arrays.asList(dateRange))
.setMetrics(Arrays.asList(metrics)).setDimensions(Arrays.asList(dimension1));
ReportRequest request2 = new ReportRequest().setViewId(viewId).setDateRanges(Arrays.asList(dateRange))
.setMetrics(Arrays.asList(metrics)).setDimensions(Arrays.asList(dimension2));
ReportRequest request3 = new ReportRequest().setViewId(viewId).setDateRanges(Arrays.asList(dateRange))
.setMetrics(Arrays.asList(metrics)).setDimensions(Arrays.asList(dimension3));
ReportRequest request4 = new ReportRequest().setViewId(viewId).setDateRanges(Arrays.asList(dateRange))
.setMetrics(Arrays.asList(metrics)).setDimensions(Arrays.asList(dimension4));
ReportRequest request5 = new ReportRequest().setViewId(viewId).setDateRanges(Arrays.asList(dateRange))
.setMetrics(Arrays.asList(metrics)).setDimensions(Arrays.asList(dimension5));
//ReportRequest request6 = new ReportRequest().setViewId(viewId).setDateRanges(Arrays.asList(dateRange))
// .setMetrics(Arrays.asList(metrics)).setDimensions(Arrays.asList(dimension6));
//ReportRequest request7 = new ReportRequest().setViewId(viewId).setDateRanges(Arrays.asList(dateRange))
// .setMetrics(Arrays.asList(metrics)).setDimensions(Arrays.asList(dimension7));

ArrayList<ReportRequest> requests = new ArrayList<ReportRequest>();
requests.add(request1);
requests.add(request2);
requests.add(request3);
requests.add(request4);
requests.add(request5);
//requests.add(request6);
//requests.add(request7);

// Create the GetReportsRequest object.
GetReportsRequest getReport = new GetReportsRequest().setReportRequests(requests);

// Call the batchGet method.
GetReportsResponse response = service.reports().batchGet(getReport).execute();

// Return the response.
return response;
}
/**
 * Queries the Analytics Reporting API V4.
 * 
 * 주의 : Request의 MAX는 5개, 즉 통계정보를 받기 위한 요청은 최대5개
 *      그래서 getReport1(5개), getReport2(2개) 만듦
 *
 * @param service An authorized Analytics Reporting API V4 service object.
 * @return GetReportResponse The Analytics Reporting API V4 response.
 * @throws IOException
 */
private GetReportsResponse getReport2(AnalyticsReporting service, String startDate, String endDate) throws IOException {
// Create the DateRange object.
DateRange dateRange = new DateRange();
dateRange.setStartDate(startDate);
dateRange.setEndDate(endDate);

// Create the Metrics object.
Metric metric1 = new Metric().setExpression(metric1Expression).setAlias(metric1Alias); // 페이지뷰
Metric metric2 = new Metric().setExpression(metric2Expression).setAlias(metric2Alias); // 사용자수
Metric metric3 = new Metric().setExpression(metric3Expression).setAlias(metric3Alias); // 세션수
Metric metrics[] = new Metric[3];
metrics[0] = metric1;
metrics[1] = metric2;
metrics[2] = metric3;
Dimension dimension6 = new Dimension().setName(dim6); // 모바일디바이스 브랜드별
Dimension dimension7 = new Dimension().setName(dim7); // 기기(Device)별

// Create the ReportRequest object.
ReportRequest request6 = new ReportRequest().setViewId(viewId).setDateRanges(Arrays.asList(dateRange))
.setMetrics(Arrays.asList(metrics)).setDimensions(Arrays.asList(dimension6));
ReportRequest request7 = new ReportRequest().setViewId(viewId).setDateRanges(Arrays.asList(dateRange))
.setMetrics(Arrays.asList(metrics)).setDimensions(Arrays.asList(dimension7));

ArrayList<ReportRequest> requests = new ArrayList<ReportRequest>();
requests.add(request6);
requests.add(request7);

// Create the GetReportsRequest object.
GetReportsRequest getReport = new GetReportsRequest().setReportRequests(requests);

// Call the batchGet method.
GetReportsResponse response = service.reports().batchGet(getReport).execute();

// Return the response.
return response;
}
// 기간별 삭제
private void delete(String startDate, String endDate) throws Exception {
GaStatsVO vo = new GaStatsVO();
vo.setStart_ymd(startDate.replace("-", ""));
vo.setEnd_ymd(endDate.replace("-", ""));
// DB에 Mybatis를 통해 값을 저장하기 위한 DAO
GaStatsDAO dao = new GaStatsDAO(); 
// 혹시 있담녀 그날분 삭제 
dao.deleteGaStats(vo);
}

/**
 * Parses and prints the Analytics Reporting API V4 response.
 *
 * @param response An Analytics Reporting API V4 response.
 * @throws Exception 
 */
private void saveResponse(GetReportsResponse response, String startDate, String endDate) throws Exception {

GaStatsVO vo = new GaStatsVO();
vo.setStart_ymd(startDate.replace("-", ""));
vo.setEnd_ymd(endDate.replace("-", ""));
// DB에 Mybatis를 통해 값을 저장하기 위한 DAO
GaStatsDAO dao = new GaStatsDAO(); 
for (Report report : response.getReports()) {
ColumnHeader header = report.getColumnHeader();
List<String> dimensionHeaders = header.getDimensions();
List<MetricHeaderEntry> metricHeaders = header.getMetricHeader().getMetricHeaderEntries();
List<ReportRow> rows = report.getData().getRows();

if (rows == null) {
logger.info("No data found for " + viewId);
return;
}

for (ReportRow row : rows) {
List<String> dimensions = row.getDimensions();
List<DateRangeValues> metrics = row.getMetrics();

for (int i = 0; i < dimensionHeaders.size() && i < dimensions.size(); i++) {
vo.setDimension(dimensionHeaders.get(i));
if (dimensions.get(i).contains("(상세보기)")) {
vo.setDim_val(dimensions.get(i).substring(0, dimensions.get(i).indexOf("(상세보기)")-1));
    }
else {
vo.setDim_val(dimensions.get(i));
}
if(dimensions.get(i).length() > 900) {
vo.setDim_val(dimensions.get(i).substring(0, 900));
}
}

for (int j = 0; j < metrics.size(); j++) {
DateRangeValues values = metrics.get(j);
for (int k = 0; k < values.getValues().size() && k < metricHeaders.size(); k++) {
if ("pageviews".equals(metricHeaders.get(k).getName())) {
vo.setPage_views(values.getValues().get(k));
}
else if ("users".equals(metricHeaders.get(k).getName())) {
vo.setUsers(values.getValues().get(k));
}
else if ("sessions".equals(metricHeaders.get(k).getName())) {
vo.setSessions(values.getValues().get(k));
}
}
}
try {
//VO에 있는 값을 저장
dao.insertGaStats(vo);
}
catch(Exception e) {
logger.error(">>>>> T_GA_STATS 저장 오류 ::: " + e);
e.printStackTrace();
throw new Exception("T_GA_STATS 저장 오류 ::: " + e);
}
}
}
}

/**
 * 구글 통계정보를 가지고 오기 위한 설정파일 로딩
 */
    public void loadProperties() {
InputStream input = null;
try {
input = this.getClass().getClassLoader().getResourceAsStream("ga.properties");
Properties prop = new Properties();
// load a properties file
prop.load(input);
// get the property value
viewId = prop.getProperty("view.id");
keyFileLocation = prop.getProperty("key.file.location");
metric1Expression = prop.getProperty("metric1.expression");
metric1Alias = prop.getProperty("metric1.alias");
metric2Expression = prop.getProperty("metric2.expression");
metric2Alias = prop.getProperty("metric2.alias");
metric3Expression = prop.getProperty("metric3.expression");
metric3Alias = prop.getProperty("metric3.alias");
dim1 = prop.getProperty("dim1");
dim2 = prop.getProperty("dim2");
dim3 = prop.getProperty("dim3");
dim4 = prop.getProperty("dim4");
dim5 = prop.getProperty("dim5");
dim6 = prop.getProperty("dim6");
dim7 = prop.getProperty("dim7");
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
input = null;
} catch (Exception e) {
}
}
 }
}
}

 

서블릿 필터 어노테이션(Servlet Filter Annotation) 사용법,WebFilter,WebInitParam

 서블릿 필터 어노테이션(Servlet Filter Annotation) 사용법,WebFilter,WebInitParam


서블릿 필터는 사용자의 요청을 JSP, Servlet등이 실행되기 전, 후에 가로챌 수 있는 기능이죠,
아래 예제를 참고하세요.

물론 위 처럼 어노테이션을 사용하지 않고 web.xml에서 아래와 같이 설정을 해도 가능하다.
<filter>
   <filter-name>onjFilter</filter-name>
<filter-class>filter.OnjFilter</filter-class>
</filter> <filter-mapping> <filter-name>onjFilter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping>

IE, 인터넷익스플러어에서 JSP의 errorPage 속성이 안먹는 경우

 IE, 인터넷익스플러어에서 JSP의 errorPage 속성이 안먹는 경우


IE의 경우 기본적으로 HTTP에 대한 오류메시지를 보여주는 페이지가 설정되어 있어서 JSP의 errorPage 페이지 지시자의 속성이 동작하지 않는다.

아래처럼 설정을 변경하자.

"도구" > "인터넷 옵션"  > "고급 --> HTTP오류 메시지 표시 체크 해제

[JSP, JSTL]버전별 다운로드,설치및 JSP에서사용방법

 [JSP, JSTL]버전별 다운로드,설치및 JSP에서사용방법


참고하세요.

JSTL 버전벌 설치방법
 
1. JSTL 1.2 :  JSP 2.1, Servlet 2.5이상
 
다운로드 URL : http://tomcat.apache.org/download-taglibs.cgi
 
jstl-impl-1.2.jar,  jstl-api-1.2.jar, taglibs-standard-spec-1.2.5.jar  파일을 라이브러리에 추가하여 사용
 

 
JSP에서는 다음과 같이 기술하여 사용한다.
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

 
2. JSTL 1.1 :  JSP 2.0, Servlet 2.4이상
 
다운로드 URL : http://archive.apache.org/dist/jakarta/taglibs/standard/binaries/
 
jstl.jar, standard.jar 두개의 파일을 라이브러리에 등록하여 사용
 
jsp에서 사용하는 방법은 JSTL1.2 방식과 동일

[JSP, EL예제]initParam,paramValues,pageContext

 [JSP, EL예제]initParam,paramValues,pageContext


1. MyBean.java

package java1;

public class MyBean {
String name;
String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}


2. ELTEST.jsp

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    import="java1.MyBean"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>EL TEST</title></head>
<body>
<%
MyBean myBean = new MyBean();
myBean.setName("홍길동");
myBean.setAge("12");
session.setAttribute("myBean", myBean);
%>
name : ${myBean.name} <br>    age  : ${myBean.age} <br>
</body></html>


-----------------------------------------------------


1. input.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>EL Example1</title></head><body>
<form action="result.jsp" method="post">
좋아하는 과일을 선택하세요<br><br>
이름 : <input type="text" name=name/>
<br>
<input type="checkbox" name="fruits" value="사과">사과
<input type="checkbox" name="fruits" value="딸기">딸기
<input type="checkbox" name="fruits" value="참외">참외
<input type="checkbox" name="fruits" value="수박">수박
<input type="checkbox" name="fruits" value="귤">귤
<br>
<br>
<input type="submit"><input type="reset">
</form></body></html>


2. web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<context-param>
<description>초기파라미터1</description>
<param-name>was</param-name>
<param-value>tomcat</param-value>
</context-param>

<context-param>
<description>초기파라미터2</description>
<param-name>version</param-name>
<param-value>8.0</param-value>
</context-param>
</web-app>


3. result.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<% request.setCharacterEncoding("UTF-8"); %>
<% request.setAttribute("name", "홍길동");   %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>표현 언어</title></head>
<body>
WAS : ${ initParam.was }<br>
VERSION : ${ initParam.version }
<hr>
요청 URI : ${ pageContext.request.requestURI }
<hr>
 이름 : ${ requestScope.name }
<hr>
선택한 과일 : ${ paramValues.fruits[0] }    ${ paramValues.fruits[1] }   ${ paramValues.fruits[2] }    ${ paramValues.fruits[3] }    ${ paramValues.fruits[4] }
</body></html>

[서블릿 리스너, 어노테이션예제, listener annotation]

[서블릿 리스너, 어노테이션예제, listener annotation]


- 어노테이션으로 할 경우


package ojc;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

@WebServletContextListener
public class MyListener implements ServletContextListener {
private ServletContext ctx = null;
// Tomcat Shutdown 시키면 아래 메시지 확인

public void contextDestroyed(ServletContextEvent event) {

System.out.println(">>> onjweb Webapp destroyed!!");
this.ctx = null;
}

// Tomcat시작시 아래 메시지 출력

public void contextInitialized(ServletContextEvent event) {
this.ctx = event.getServletContext();
System.out.println(">>> onjweb Webapp start!!");
}
}


- web.xml에 XML 설정으로 하는 경우

<listener>
    <listener-class>java1.MyListener</listener-class>
</listener>

오라클PLSQL, 저장 함수(Stored Function)

오라클PLSQL, 저장 함수(Stored Function)

15.2. 저장 함수(Stored Function)


자신을 호출한 곳으로 반드시 하나의 값을 리턴해 줘야되는 PL/SQL Stored Program 입니다. 함수 자체가 오라클 서버에 저장 되므로 Stored Function or User Function or User-Defined Function 이라고 합니다. 


자신의 스키마 계정에 함수를 작성하려면 CREATE PROCEDURE 시스템 권한이 있어야 하며 다른 사용자 계정에서 함수를 만들려면 CREATE ANY PROCEDURE 시스템 권한이 있어야 합니다.


함수를 정의할 때  Header에 리턴되는 데이터 타입을 기술하고 Header의 끝에는 IS[AS]가

와야하며 IS[AS]와 BEGIN사이에 BEGIN ~  END에서 사용할 변수를 선언 합니다.


<기본형식>

CREATE [OR REPLACE] FUNCTION function_name [parameters]

RETURN return_type 

IS[or AS] 

    declaration_section 

BEGIN 

    execution_section

    RETURN return_variable; 

EXCEPTION 

     exception_section 

     RETURN exception_return_variable; 

END [function_name];

/


  • function_name : 생성하고자 하는 함수의 이름.

  • parameters: 함수에 전달할 파라미터 목록.

  • return_type :함수가 리턴할 값의 데이터 타입.

  • declaration_section : 변수나 커서, 타입등을 선언 하는 영역

  • execution_section : 실제 비지니스 로직처리, PL/SQL 제어문, 반복문, DML등

  • RETURN return_variable : 호출한 곳으로 값을 리턴.

  • exception_section : 오류가 발생했을 때의 처리.

  • RETURN exception_return_variable : 오류가 발생했을때 리턴하는 값

  • / : SQL*Plus에서 실행기호. SQL*Plus에서 함수를 생성하는 경우에는 반드시 기술해야 합니다.


저장 함수를 만들고 호출하는 실습을 해보겠습니다.

15.2.1. 저장 함수 작성 실습 : CREATE OR REPLACE FUNCTION


EMP 테이블에서 사번을 인자로 입력받아 해당 사원의 이름을 리턴하는 저장 함수를 F_GET_ENAME 이라는 이름으로 작성하세요.


-- 이미 F_GET_ENAME 함수가 있다면 대체 합니다. 리턴 타입은 VARCHAR2 입니다.

-- 함수를 호출할 때는 숫자형으로 사번을 던져줘야 합니다.

CREATE OR REPLACE  FUNCTION F_GET_ENAME(P_EMPNO  IN  NUMBER)          

RETURN  VARCHAR2

IS        

   /* IS ~ BEGIN사이는 이름없는 블럭을 만들때의 DECLARE ~ BEGIN과 

   동일하게 변수를 선언하는 선언부 입니다.

   V_EANE 변수는 EMP 테이블의 ENAME과 타입이 같습니다. */

   V_ENAME  EMP.ENAME%TYPE;

BEGIN


      /* BEGIN ~ END 사이의 SELECT절은 반드시 한건만 SELECT 되야 하며 

      INTO절이 반드시 필요합니다.

      WHERE절의 사원이 없다면 EXCEPTION절의 

      WHEN NO_DATA_FOUND THEN 절로 이동합니다. */


      SELECT   ENAME

      INTO        V_ENAME

      FROM      EMP

      WHERE   EMPNO  =  P_EMPNO;

      

      -- V_ENAME 변수값을 리턴 합니다.

      RETURN V_ENAME;


-- 예외처리 절 입니다.

EXCEPTION


      /* NO_DATA_FOUND는 PL/SQL에 사전에 정의되어 있는 예외 입니다.             

      ORA-01403 오류 코드이며  SELECT시 데이터를 찾을 수 없을때 발생하는 예외 입니다. 

      WHEN 절에서 일일이 예외를 처리하기가 번거러우면  

      모든 예외를 다 처리할 수 있는 WHEN OTHERS THEN만 사용해도 무방 합니다. */

      WHEN NO_DATA_FOUND THEN

         DBMS_OUTPUT.PUT_LINE('해당 사원은 없습니다.');   

      WHEN OTHERS THEN

         -- 기타 오류인 경우 SQL 에러코드와 에러 메시지를 출력 합니다.

         DBMS_OUTPUT.PUT_LINE(SQLCODE || ':' || SQLERRM);

END F_GET_ENAME;


<실행결과>

Function F_GET_ENME이(가) 컴파일되었습니다.


SQL Developer에서 실행할 경우 END F_GET_ENME; 다음에 슬래시(‘/’)를 하지 않아도 실행 되지만 SQL*Plus에서 실행을 하는 경우에는 반드시 ‘/’를 뒷부분에 표시 해야만 실행이 됩니다. 아래 그림을 참조하세요.


gn-vf8J1KS6698q6l1VIw9ra1ZvHtt3yiI0FWIzi


작성한 함수를 SELECT절에서 호출하는 실습 입니다.


F_GET_ENME 함수를 SELECT 쿼리에서 호출 하세요.


SELECT ❶F_GET_ENAME(7369) FROM DUAL;


<실행결과>

 

  F_GET_ENAME(7369)

1

  SMITH


❶ 오라클에서 제공하는 수많은 함수를 SELECT 쿼리에서 사용하듯이 우리가 작성한 함수도 같은 형태로 사용 가능 합니다.



SELECT F_GET_ENAME(7777) FROM DUAL;


<실행결과>

ORA-06503: PL/SQL: 함수가 값을 리턴하지 못했습니다

해당 사원은 없습니다.


작성한 함수를 EXECUTE 명령으로 호출하는 실습 입니다. 아래 실습의 실행은 SQL*Deveoper 또는 SQL*PLUS 모두 가능 합니다.


F_GET_ENME 함수를 EXECUTE 명령으로 호출 하세요.


-- 변수를 선언 합니다. 이렇게 선언한 변수를 참조할 때는 앞에 ‘:’을 표시해야 합니다.

VARIABLE ENAME VARCHAR2(50);


-- F_GET_ENAME 함수를 호출하면서 7369 사번을 인자로 전달하고 

-- EXEC[UTE] 명령으로 함수를 호출하고 그 결과를 ENAME 변수로 받습니다.

-- ENAME 변수는 반드시 앞에 콜론(‘:’)을 기술해야 합니다.

EXEC :ENAME := F_GET_ENAME(7369);


-- ENAME 변수를 출력합니다.

PRINT ENAME;


<실행결과>


ENAME

--------------------------------------------------------------------------------

SMITH

(C#교육동영상)C# ADO.NET 실습 ODP.NET/ODAC 설치 오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원

  (C#교육동영상)C# ADO.NET 실습  ODP.NET/ODAC 설치  오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원 https://www.youtube.com/watch?v=qIPU85yAlzc&list=PLxU-i...