2017년 11월 3일 금요일

11번가 자동 출첵, 2017.11.03 (casperjs)

기존에 curl 을 이용한 방식은 onclick등 자바스크립트 함수가 들어가면 매우 골치아파지는 문제가 있었다.

그래서 검색하다 'headless browser' 라는 걸 알게 됐고, casperjs 란 알게 됐다.


 

11번가 자동 출첵은 casperjs 로 만들어서 기존에 사용하고 있었는데,

9월 30일 이후로 출첵이 안된 거 보니 그 때 출석체크 페이지가 바뀐듯 하다.

 

11번가 자동 출첵은 왜 하느냐?

마일리지를 받기 위해서다. 마일리지로 뭘 할 수 있는냐?

사람들이 잘 모르는데, 11번가 마일리지로 할 수 있는게 많다.

상품쿠폰,배송비쿠폰, 핸드폰 데이터 쿠폰 그리고 상품 교환도 된다.

베스킨라빈스 레귤러 한번 먹어 봤다.

 

각설하고 11번가 자동 출체 코드는 아래와 같다.

var casper = require('casper').create({ pageSettings: { "userAgent": 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.10 (KHTML, like Gecko) Chrome/23.0.1262.0 Safari/537.10', "loadImages": true, "loadPlugins": false, "webSecurityEnabled": false, "ignoreSslErrors": true }, onWaitTimeout: function () { //throw new Error }, onStepTimeout: function () { //throw new Error }, encoding: "utf8", waitTimeout: 10000, stepTimeout: 10000, logLevel: "debug", // Only "info" level messages will be logged verbose: true // log messages will be printed out to the console }); var login_id = casper.cli.get("id"); var login_pw = casper.cli.get("pw"); var login_url = 'https://login.11st.co.kr/login/Login.tmall'; var attendance_url = 'http://www.11st.co.kr/browsing/MallPlanDetail.tmall?method=getMallPlanDetail&planDisplayNumber=935566'; //temp login_id = 'myid'; login_pw = 'mypass'; if(!login_id){ casper.echo("require id parameter"); // casper.exit(); //not working phantom.exit(); } if(!login_pw){ casper.echo("require pw parameter"); phantom.exit(1); } casper.start(login_url, function() { this.fill('form[name="login_form"]', { 'loginName' : login_id, 'passWord': login_pw }, false); this.click('#memLogin > div.save_idW > input'); this.wait(1000, function() { //this.echo("I've waited for a second."); }); }); //출석 casper.thenOpen(attendance_url, function(){ //iframe this.withFrame(1, function () { this.click('#regForm > div > div.sect03 > div.dev04 > a.get04 > img'); this.wait(1000, function() { this.setFilter("page.confirm", function(msg) { return true; }); }); }); }); //casper.run(); casper.run(function() { require('utils').dump(this.result.log); this.exit(); });

 

당연하지만 매일 자동으로 실행하려면 매일 켜져있는 pc(server)가 필요하다.

테스트용 리눅스 pc가 있어서 casperjs 설치 후 cron으로 매일 실행 되게끔 설정하였다.

 

없으신 분들은 알아서...;;

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