2017년 11월 3일 금요일

spring standalone application 에서 @service 실행

spring standalone application 에서 @service 실행

스프링 프로젝트에서 Main 함수안에서 기존에 구축된 @service 를 사용하려면

다음과 같이 하면 된다.
package xxx.xxx.www.test.console;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
import xxx.xxx.www.test.service.TestService;

@Component
public class Main {

private static final String CONFIG_PATH = "classpath*:spring/all-config.xml";

public static void main(String[] args) throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext(CONFIG_PATH);

Main p = context.getBean(Main.class);
p.start(args);
}

@Autowired
private TestService serv;
private void start(String[] args) throws Exception {
Map map = new HashMap();
map.put("docnum", "108");
List list = serv.selectList(map);
System.out.println("결과 logger:::::::::::::::: " + list);
}
}

 

한참 해맸었던 이유가 있는데, 기존에 스프링 환경은 아래와 같이 각 파트별로 구분지어 만들어진 환경이다.

spring-common.xml

spring-datasource.xml

....

이걸 부분만 적용하려니 잘 되지 않았다. 아래와 같이 한꺼번에 가져오도록 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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

<import resource="classpath*:spring/spring-*.xml"/>
</beans>

2017년 10월 24일 화요일

HTTP 헤더, soap 헤더 추가

1.HTTP 헤더 추가.
		ShoppingService ss = new ShoppingService();
ShoppingServiceSoap port = ss.getShoppingServiceSoap();

Client client = ClientProxy.getClient(port);

// Creating HTTP headers
Map<String, List<String>> headers = new HashMap<String, List<String>>();
headers.put("XXX-SOA-SERVICE-NAME", Arrays.asList("SampleService"));
headers.put("XXX-SOA-APP-NAME", Arrays.asList("SampleServiceAppv1"));

// Add HTTP headers to the web service request
client.getRequestContext().put(Message.PROTOCOL_HEADERS, headers);

 

2. soap 헤더 추가
		ShoppingService ss = new ShoppingService();
ShoppingServiceSoap port = ss.getShoppingServiceSoap();

Client client = ClientProxy.getClient(port);



List<Header> headersList = new ArrayList<Header>();

Header testSoapHeader1 = new Header(ss.SERVICE, "SOAP Header Message 1", new JAXBDataBinding(String.class));
Header testSoapHeader2 = new Header(new QName("http://naver.com", "soapheader2"), "SOAP Header Message 2", new JAXBDataBinding(String.class));
Header testSoapHeader3 = new Header(new QName("Element"), "SOAP Header Message 3", new JAXBDataBinding(String.class));

headersList.add(testSoapHeader1);
headersList.add(testSoapHeader2);
headersList.add(testSoapHeader3);

// Add SOAP headers to the web service request
client.getRequestContext().put(Header.HEADER_LIST, headersList);


/* 실제 request
...
<soap:Header>
<ShoppingService xmlns="http://www.auction.co.kr/APIv1/ShoppingService">SOAP Header Message 1</ShoppingService>
<soapheader2 xmlns="http://naver.com">SOAP Header Message 2</soapheader2>
<EncryptedTicket>SOAP Header Message 3</EncryptedTicket>
...
*/

soap 로그 출력

cxf 로 생성된 파일을 이용하여 작업 할 때, soap request나 response 가 필요한 경우가 있다.

  1. Feature를 이용하는 법


		LoggingFeature logFeat = new LoggingFeature();
logFeat.setPrettyLogging(true);
ShoppingService ss = new ShoppingService(logFeat);
ShoppingServiceSoap port = ss.getShoppingServiceSoap();

 

2. InInterceptor를 이용하는 법.
		ShoppingService ss = new ShoppingService();
ShoppingServiceSoap port = ss.getShoppingServiceSoap();

Client client = ClientProxy.getClient(port);
client.getInInterceptors().add(new LoggingInInterceptor());
client.getOutInterceptors().add(new LoggingOutInterceptor());

 

Feature를 이용한 방법이 요청이 정렬되어서 나오기 때문에 추천한다.

"Result" 속성은 이미 정의되었습니다. 를 사용하여 이 충돌을 해결하십시오.

cxf로 웹서비스 클라이언트 자동 생성시 아래와 같은 에러 발생.
"Result" 속성은 이미 정의되었습니다. &lt;jaxb:property>를 사용하여 이 충돌을 해결하십시오.

wsdl element로 java 파일을 만들때, element 명으로 java 파일명을 생성하는 데, 중복된 경우 발생하는 에러이다.

-autoNameResolution 옵션으로 자동으로 변경 된다고 하는데, 왜인지 해당 옵션이 먹지 않는다.

 

binding 수동으로 지정해서 생성하면 된다고 하는 데,  잘 안됨.

그냥 wsdl 을 xml 로 저장하고 element 명을 수정하여 처리 하였다.

 

 

참조

 

cxf 웹서비스 클라이언트 자동 생성 파일 타입 지정.

cxf 로 웹서비스 클라이언트 생성시 생성되는 파일이 EUC-KR로 생성된다.
-encoding UTF-8 를 사용하여 생성되는 파일 타입을 강제로 지정이 가능하다.
해당 옵션을 wsdl2java.bat 넣고 이클립스에서 생성시에는 해당옵션이 적용되지 않는다.
이클립스에서는 wsdl2java.bat를 사용하지 않고 org.apache.cxf.tools.wsdlto.WSDLToJava 를 바로 사용하기 때문이다.

어쩔수 없이 이클립스 console에 출력되는 wsdl2java... command를 복사해서
-encoding UTF-8 를 붙여서 수동으로 생성 후 소스에 붙여 넣었다.

2017년 8월 4일 금요일

PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification 에러 해결법

mvn clean install 명령어를 실행하려고 했더니, 에러 메시지가 난다.
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification

 

문제의 원인은 JAVA에서 인증서를 신뢰하지 않아서 발생 하는 문제.

나의 경우는 회사에서만 발생하는 에러이다.

왜냐면...

회사에서 나의 활동을 감시하기 위하여 'SSL PRISM Cerificate Installer (ARA Networks Co.,Ltd)' 프로그램을 강제로 설치하도록 했기 때문이다.

설치안하면 인터넷이 안된다.  ㅡㅡ;
쩝... 어째든 해결 방법은 다음과 같다.

아래의 경로로 가면
'C:\Program Files (x86)\ARA Networks Co.,Ltd\SSL PRISM Certificate Installer'

SSLPrism.crt 파일이 있다. 이것을 자바의 ca가 저장 되어 있는 'C:\Program Files\Java\jdk1.8.0_131\jre\lib\security'로 복사 해준다.

그래고 아래 명령어로 인증서를 추가 해준다.
C:\Program Files\Java\jdk1.8.0_131\jre\lib\security>keytool -keystore cacerts -importcert -alias sslprism -file SSLPrism.crt

 

패스워드를 물어보는데, 기본패스워드는 'changeit' 이다.

그리고 y.
mvn clean install 명령을 다시 실행하면 정상적으로 동작 한다.

 

ps.

아래 명령어로 ssl 무시하고 하려고 했지만, 안 됐다.
mvn clean install -Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true -Dmaven.wagon.http.ssl.ignore.validity.dates=true

https://stackoverflow.com/questions/21252800/how-to-tell-maven-to-disregard-ssl-errors-and-trusting-all-certs

 

참고.
https://gs.saro.me/#!m=elec&p=1&jn=772
https://docs.microsoft.com/ko-kr/azure/java-add-certificate-ca-store

2017년 7월 6일 목요일

StringUtils의 isEmpty, isBlank 분석.

자바에서 Null 포함 빈값을 체크 할 때, StringUtils의 isEmpty 나 isBlank를 사용한다.
isEmpty는 "", null 일 경우 true를 리턴한다.
isBlank는 "", null, " " 일 경우 true를 리턴한다.

해당 메소드가 어떻게 동작하는 지 알아 봤다.

소스
isEmpty가 동작하는 방식은 간단하다.
        public static boolean isEmpty(String str) {
return str == null || str.length() == 0;
}

null 이거나, length 가 0 일경우를 체크 한다.

 

 

isBlank는 조금 더 복잡하다.
        public static boolean isBlank(String str) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return true;
}
for (int i = 0; i < strLen; i++) {
if ((Character.isWhitespace(str.charAt(i)) == false)) {
return false;
}
}
return true;
}

첫번째는 isEmpty와 같지만 스페이스를 체크하기 위해 for문을 돈다.

 

 

간혹 StringUtils 라이브러리가 없고, 추가 할 수 없는 경우 참고 하면 좋을 것 같다.