HttpClient 공통 Util을 소개합니다.

 

package x.util;

import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Map;

/**
 * packageName    : x.util;
 */
public class HttpClientUtil {

    private static final HttpClient httpClient = HttpClient.newHttpClient();

    private static final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * Get t.
     *
     * @param <T>          the type parameter
     * @param url          the url
     * @param headers      the headers
     * @param responseType the response type
     * @return the t
     * @throws IOException          the io exception
     * @throws InterruptedException the interrupted exception
     */
    public static <T> T get(String url, Map<String, String> headers, Class<T> responseType) throws IOException, InterruptedException {
        HttpRequest.Builder builder = HttpRequest.newBuilder().uri(URI.create(url)).GET();
        addHeaders(builder, headers);
        HttpResponse<String> response = httpClient.send(builder.build(), HttpResponse.BodyHandlers.ofString());
        return objectMapper.readValue(response.body(), responseType);
    }

    /**
     * Post t.
     *
     * @param <T>          the type parameter
     * @param url          the url
     * @param requestBody  the request body
     * @param headers      the headers
     * @param responseType the response type
     * @return the t
     * @throws IOException          the io exception
     * @throws InterruptedException the interrupted exception
     */
    public static <T> T post(String url, Object requestBody, Map<String, String> headers, Class<T> responseType) throws IOException, InterruptedException {
        String json = objectMapper.writeValueAsString(requestBody);
        HttpRequest.Builder builder = HttpRequest.newBuilder().uri(URI.create(url)).POST(HttpRequest.BodyPublishers.ofString(json));
        addHeaders(builder, headers);
        HttpResponse<String> response = httpClient.send(builder.build(), HttpResponse.BodyHandlers.ofString());
        return objectMapper.readValue(response.body(), responseType);
    }

    /**
     * Put t.
     *
     * @param <T>          the type parameter
     * @param url          the url
     * @param requestBody  the request body
     * @param headers      the headers
     * @param responseType the response type
     * @return the t
     * @throws IOException          the io exception
     * @throws InterruptedException the interrupted exception
     */
    public static <T> T put(String url, Object requestBody, Map<String, String> headers, Class<T> responseType) throws IOException, InterruptedException {
        String json = objectMapper.writeValueAsString(requestBody);
        HttpRequest.Builder builder = HttpRequest.newBuilder().uri(URI.create(url)).PUT(HttpRequest.BodyPublishers.ofString(json));
        addHeaders(builder, headers);
        HttpResponse<String> response = httpClient.send(builder.build(), HttpResponse.BodyHandlers.ofString());
        return objectMapper.readValue(response.body(), responseType);
    }

    /**
     * Delete t.
     *
     * @param <T>          the type parameter
     * @param url          the url
     * @param headers      the headers
     * @param responseType the response type
     * @return the t
     * @throws IOException          the io exception
     * @throws InterruptedException the interrupted exception
     */
    public static <T> T delete(String url, Map<String, String> headers, Class<T> responseType) throws IOException, InterruptedException {
        HttpRequest.Builder builder = HttpRequest.newBuilder().uri(URI.create(url)).DELETE();
        addHeaders(builder, headers);
        HttpResponse<String> response = httpClient.send(builder.build(), HttpResponse.BodyHandlers.ofString());
        return objectMapper.readValue(response.body(), responseType);
    }

    private static void addHeaders(HttpRequest.Builder builder, Map<String, String> headers) {
        if (headers != null) {
            headers.forEach(builder::header);
        }
    }
}

 

Map<String, String> headers 은 Header

Object requestBody 는 parameter 

Class<T>의 responseType은 응답값을 받고자하는 class 타입을지정

   

 

사용법은 아래와 같음

public Map<String, Object> httpClientTest(@PathVariable String method) throws IOException, InterruptedException {
        Map<String, Object> response;
        if ("get".equals(method)) {
            response = HttpClientUtil.get(
            "https://jsonplaceholder.typicode.com/posts/1",
                Map.of("Content-type", "application/json; charset=UTF-8"),
                Map.class
            );
        } else
        if ("post".equals(method)) {
            Map<String, Object> map = new HashMap<>();
            map.put("title", "foo");
            map.put("body", "bar");
            map.put("userId", 1);
            response = HttpClientUtil.post(
                "https://jsonplaceholder.typicode.com/posts",
                map,
                Map.of("Content-type", "application/json; charset=UTF-8"),
                Map.class
            );
        } else
        if ("put".equals(method)) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", 1);
            map.put("title", "foo");
            map.put("body", "bar");
            map.put("userId", 1);
            response = HttpClientUtil.put(
                "https://jsonplaceholder.typicode.com/posts/1",
                map,
                Map.of("Content-type", "application/json; charset=UTF-8"),
                Map.class
            );
        } else {
            Map<String, String> map = new HashMap<>();
            response = HttpClientUtil.delete(
            "https://jsonplaceholder.typicode.com/posts/1",
                map,
                Map.class
            );
        }
        return null;
    }

 

 

Gradle 기준 아래 의존성 추가

dependencies {
    implementation("com.fasterxml.jackson.core:jackson-databind:2.17.0")
}

 

 

https://jsonplaceholder.typicode.com

 

JSONPlaceholder - Free Fake REST API

{JSON} Placeholder Free fake and reliable API for testing and prototyping. Powered by JSON Server + LowDB. Serving ~3 billion requests each month.

jsonplaceholder.typicode.com

 

위 사이트는 REST API 테스트를 제공해주는 사이트입니다.

호출 이후 결과도 HTTP Method 에 따라 가이드가 있으니 이용하세요!  

이건 저만의 설정인데요

^^.. 설명은 생략해볼게요

 

 

log4jdbc.log4j2.properties

log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
log4jdbc.dump.sql.maxlinelength=0


pom.xml

<!-- Custom maven :S -->
	<dependency>
		<groupId>org.bgee.log4jdbc-log4j2</groupId>
		<artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
		<version>1.16</version>
	</dependency>
<!-- Custom maven :E -->


datasource

driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
jdbc-url: jdbc:log4jdbc:mariadb


log4j.xml

<configuration>
	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		<encoder>
			<pattern>%green(%d{yyyyMMdd HH:mm:ss.SSS}) %cyan([%thread]) %highlight(%-3level) %yellow(%logger{5}) - %white(%msg) %n</pattern>
		</encoder>
	</appender>

	<logger name="jdbc" level="OFF"/>
	<logger name="jdbc.sqlonly" level="INFO"/>
	<logger name="jdbc.sqltiming" level="INFO"/>
	<logger name="jdbc.audit" level="OFF"/>
	<logger name="jdbc.resultset" level="OFF"/>
	<logger name="jdbc.resultsettable" level="INFO"/>
	<logger name="jdbc.connection" level="OFF"/>

	<root level="INFO">
		<appender-ref ref="STDOUT" />
	</root>
</configuration>


sqlSessionFactory

/* Custom DataSource : S */
	Log4jdbcProxyDataSource log4jdbcProxyDataSource = new Log4jdbcProxyDataSource(dataSource);
	Log4JdbcCustomFormatter log4JdbcCustomFormatter = new Log4JdbcCustomFormatter();
	log4JdbcCustomFormatter.setLoggingType(LoggingType.MULTI_LINE);
	log4JdbcCustomFormatter.setSqlPrefix("\nSQL ::::: ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ\n");
	log4jdbcProxyDataSource.setLogFormatter(log4JdbcCustomFormatter);
	final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
	sessionFactory.setDataSource(dataSource);
	sessionFactory.setDataSource(log4jdbcProxyDataSource);

/* Custom DataSource : E */

SSL 인증서 만료일이 도래하여 교체작업을 하였다.
 
서버는 Apache 였으며 총4개의 파일을 교체하고, Apache의 설정파일에 경로를 변경하는 작업이었다.

cert_domain.crt
domain.key
rootca_domain.crt
subca_domain.crt

 
모두 변경을 완료한 이후 apache를 재시작하였으나, Error 발생 !!
 
로그를 확인해보니 아래와 같이 기록이 되있었다.

AH02241: Init: Unable to read server certificate from file /xxx/domain.key
SSL Library Error: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
SSL Library Error: error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error (Type=X509)
AH02312: Fatal error initialising mod_ssl, exiting.

 
Key 파일을 열어보니 

key 파일

 
위와 같이 암호화된 문자로 시작되었으며 이는 SSL 인증서를 적용하는 정상적인 상태가 아니었다.
해당 파일의 문자열은 복호화가 된 상태로 있어야 한다.
 
복호화방법은 아래와 같다.

openssl rsa -in [복호화 할 파일명(암호화 된 파일명)] -out [복호화 될 파일명]
Enter pass pharse for xxxx: 비밀번호 입력

 
위와 같이 복호화 이후 Apache를 재시작 하니 정상 작동 하였다.

USE [DBNAME]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE PROCEDURENAME
(
	@IN_PARAMETER1 NVARCHAR(10),
	@IN_PARAMETER2 BIGINT
)
AS
	DECLARE @SQL NVARCHAR(4000) = '';
	DECLARE @PARAMDEFINITION NVARCHAR(4000);
    
BEGIN
	SET NOCOUNT ON;
    
	SET @SQL = 
            N'
                SELECT 	* 
                    FROM 	TABLE 
                    WHERE 	IN_PARAMETER1 = @IN_PARAMETER1
                    AND	IN_PARAMETER2 = @IN_PARAMETER2		
            '
        ;

	SET @PARAMDEFINITION = N'@IN_PARAMETER1 NVARCHAR(10), @IN_PARAMETER2 BIGINT';

	EXEC SP_EXECUTESQL @SQL, @PARAMDEFINITION, 
		@IN_PARAMETER1 = @IN_PARAMETER1, @IN_PARAMETER2 = @IN_PARAMETER2
    ;
END

 

동적 쿼리(Dynamic SQL) 생성 예제

 

 

가그린 제로 구강청결제, 100ml, 1개

COUPANG

www.coupang.com

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."

'Database > MSSQL' 카테고리의 다른 글

[MSSQL] 테이블 생성 및 커멘트 추가  (0) 2023.07.10
[MSSQL] 재귀 SQL 호출  (0) 2023.02.22
[MSSQL] Oracle Migration  (0) 2022.12.26
[MSSQL] - PROCEDURE CURSOR 사용 (커서)  (0) 2020.07.28
[MSSQL] - PROCEDURE IF 사용 ( 조건문 )  (0) 2019.01.15

+ Recent posts