net.GoTicketing.GoTicketing.java Source code

Java tutorial

Introduction

Here is the source code for net.GoTicketing.GoTicketing.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package net.GoTicketing;

import static java.lang.System.out;
import static net.NET_INFO.DEFAULT_PARAMS;
import static net.GoTicketing.GetNecessaryCookie.CookieMapToString;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.http.Header;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import net.NET_INFO;
import org.jsoup.select.Elements;
import ticket.RailwayTicket;

/**
 *
 * @author User
 */
public class GoTicketing {
    private static final Logger logger = Logger.getLogger(GoTicketing.class.getName());
    private static final SimpleDateFormat timeFormater = new SimpleDateFormat("HH:mm:ss.SSS");
    private static final RequestConfig ticketing_params = RequestConfig.custom().setConnectTimeout(60000)
            .setSocketTimeout(60000).build();

    //  ?
    public static final int GET_CAPTCHA_FAIL = -4;
    public static final int UNKNOW_PRASE_RESULT = -3;
    public static final int POST_TICKETING_FAIL = -2;
    public static final int PRASE_IN_EXCEPTION = -1;
    public static final int UNINITIALIZED = 0;
    public static final int RAND_OR_TIMEOUT_FAIL = 1;
    public static final int ROCID_WRONG = 2;
    public static final int TRAIN_STATION_WRONG = 3;
    public static final int TRAIN_NO_SEAT = 4;
    public static final int TICKETING_SUCCESS = 5;
    public static final int TICKETING_TO_LATE = 6;
    public static final int TRAIN_NUM_WRONG = 7;
    public static final int TICKETING_TO_EARLY = 8;

    //  
    private String TicketingErrorCode = null;
    //  ????
    private boolean postTicketPageSuccess = false;
    //  ????
    private boolean postCaptchaPageSuccess = false;

    //  ?
    private String TicketingPageHTML = null;
    //  ??
    private String FinishTicketingPageHTML = null;

    //  , , ??
    private String ImageCaptchaSrc = null;
    private String VoiceCaptchaSrc = null;
    private String FormActionSrc = null;
    private Map<String, String> FormInputData = null;

    //  , ?
    private String imgName = null;
    private String vocName = null;

    private Map<String, String> cookieMap;

    private final String host;
    private final String filePath;
    private final RailwayTicket ticket;

    public boolean isPostTicketPageSuccess() {
        return postTicketPageSuccess;
    }

    public boolean isPostCaptchaPageSuccess() {
        return postCaptchaPageSuccess;
    }

    public String getImgName() {
        return imgName;
    }

    public String getVocName() {
        return vocName;
    }

    public GoTicketing(String filePath, RailwayTicket ticket) {
        this(NET_INFO.RAILWAY_HOST_1, filePath, ticket);
    }

    /**
     * , ?
     * @param host ?
     * @param filePath ?
     * @param t 
     */
    public GoTicketing(String host, String filePath, RailwayTicket t) {
        this.filePath = filePath;
        ticket = t;

        switch (host) {
        case NET_INFO.RAILWAY_HOST_1:
            this.host = NET_INFO.RAILWAY_HOST_1;
            break;
        case NET_INFO.RAILWAY_HOST_2:
            this.host = NET_INFO.RAILWAY_HOST_2;
            break;
        default:
            this.host = NET_INFO.RAILWAY_HOST_1;
            break;
        }

        //  ?Cookie
        cookieMap = new TreeMap<>();
        //cookieMap = GetNecessaryCookie.getCookieFromHome(host);
        GetNecessaryCookie.getCookie(host, "Public/sitemap.htm", "ctno1.htm", cookieMap);
        GetNecessaryCookie.getCookie(host, "ctno1.htm", "Public/sitemap.htm", cookieMap);
        //GetNecessaryCookie.getCookie(host, "Images/title_01.jpg", "ctno1.htm", cookieMap);
        //GetNecessaryCookie.getCookie(host, "Images/ToEngButton.gif", "ctno1.htm", cookieMap);
        //GetNecessaryCookie.getCookie(host, "Images/oder_a.jpg", "ctno1.htm", cookieMap);
        //GetNecessaryCookie.getCookie(host, "Images/title_bg.jpg", "ctno1.htm", cookieMap);

        //  ??
        try {
            postTicketingPackage();
            praseImageCaptchaSrc();
            //praseVoiceCaptchaSrc();
            praseFormActionSrc();
            getImageCpatcha();
            //getVoiceCpatcha();

            //out.println(TicketingPageHTML);
            postTicketPageSuccess = true;
        } catch (Exception ex) {
            TicketingErrorCode = "In Exception : " + ex.toString();
            logger.log(Level.WARNING, TicketingErrorCode);
            ticket.setTicketingErrorCode(TicketingErrorCode);

            postTicketPageSuccess = false;
            ticket.setOrderResult(GET_CAPTCHA_FAIL);
        }

        ticket.setGetCaptchaSeccess(postTicketPageSuccess);
    }

    /**
     * 
     */
    public void startTicketing() {
        postCaptchaPageSuccess = false;
        int orderResult;
        try {
            //  ?
            sendTicketingRequest();
            //out.println(FinishTicketingPageHTML);

            postCaptchaPageSuccess = true;

            //  ??
            orderResult = praseTicketingResultPage();
        } catch (IOException ex) {
            TicketingErrorCode = "In Exception : " + ex.toString();
            logger.log(Level.WARNING, TicketingErrorCode);
            ticket.setTicketingErrorCode(TicketingErrorCode);

            if (postCaptchaPageSuccess)
                orderResult = PRASE_IN_EXCEPTION;
            else
                orderResult = POST_TICKETING_FAIL;
        }
        ticket.setOrderResult(orderResult);
        ticket.setTicketingSeccess(postCaptchaPageSuccess);
    }

    /**
     * ??
     * @throws IOException 
     */
    private void postTicketingPackage() throws IOException {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(host + "check_ctno1.jsp");
            httpPost.setConfig(DEFAULT_PARAMS);

            httpPost.addHeader("Referer", host + "ctno1.htm");
            httpPost.addHeader("Origin", host);

            //  Cookie
            String cookies = CookieMapToString(cookieMap);
            if (!cookies.equals(""))
                httpPost.setHeader("Cookie", cookies);

            //  ??
            List<NameValuePair> nvps = new ArrayList<>();
            nvps.add(new BasicNameValuePair("person_id", ticket.getId()));
            nvps.add(new BasicNameValuePair("from_station", ticket.getFrom()));
            nvps.add(new BasicNameValuePair("to_station", ticket.getTo()));
            nvps.add(new BasicNameValuePair("getin_date", ticket.getDate()));
            nvps.add(new BasicNameValuePair("train_no", ticket.getTrainCode()));
            nvps.add(new BasicNameValuePair("order_qty_str", ticket.getOrderSum()));
            nvps.add(new BasicNameValuePair("t_order_qty_str", "0"));
            nvps.add(new BasicNameValuePair("d_order_qty_str", "0"));
            nvps.add(new BasicNameValuePair("b_order_qty_str", "0"));
            nvps.add(new BasicNameValuePair("z_order_qty_str", "0"));
            nvps.add(new BasicNameValuePair("returnTicket", "0"));

            //if (ticket.isIspum()) 
            //nvps.add(new BasicNameValuePair("n_order_qty_str", ticket.getOrderSum()));
            //else
            //nvps.add(new BasicNameValuePair("n_order_qty_str", "0"));

            httpPost.setEntity(new UrlEncodedFormEntity(nvps));

            //  ??
            ticket.setRequestCaptchaTime(getTime());
            try (CloseableHttpResponse httpResponse = httpClient.execute(httpPost)) {
                //  HttpStatusCode != 200
                if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                    String ErrorCode = "Response Status : " + httpResponse.getStatusLine().getStatusCode();
                    throw new IOException(ErrorCode);
                }

                String hstr; //  cookie
                for (Header header : httpResponse.getHeaders("Set-Cookie")) {
                    hstr = header.getValue().split(";")[0];
                    cookieMap.put(hstr.split("=", 2)[0], hstr.split("=", 2)[1]);
                }

                try (InputStreamReader isr = new InputStreamReader(httpResponse.getEntity().getContent(), "big5");
                        BufferedReader reader = new BufferedReader(isr)) {
                    String line;
                    StringBuilder builder = new StringBuilder();

                    while ((line = reader.readLine()) != null) {
                        builder.append(line);
                        builder.append("\n");
                    }
                    TicketingPageHTML = builder.toString();
                }
            }
            ticket.setResponseCaptchaTime(getTime());
        }
    }

    /**
     * ??
     * @throws Exception 
     */
    private void praseImageCaptchaSrc() throws Exception {
        Document doc = Jsoup.parse(TicketingPageHTML);
        Element img = doc.getElementById("idRandomPic");
        if (img == null)
            throw new Exception("Can't get image captcha source !");

        //out.println(host + img.attr("src"));
        ImageCaptchaSrc = host + img.attr("src");
    }

    /**
     * ??
     * @throws Exception 
     */
    private void praseVoiceCaptchaSrc() throws Exception {
        Document doc = Jsoup.parse(TicketingPageHTML);
        Element voc = doc.getElementsByTag("audio").last();
        if (voc == null)
            throw new Exception("Can't get voice captcha source !");

        //out.println(host + voc.attr("src").substring(1));
        VoiceCaptchaSrc = host + voc.attr("src").substring(1);
    }

    /**
     * ???
     * @throws Exception 
     */
    private void praseFormActionSrc() throws Exception {
        Document doc = Jsoup.parse(TicketingPageHTML);
        Element form = doc.getElementsByTag("form").first();
        if (form == null)
            throw new Exception("Can't get form action source !");

        String src = form.attr("action");
        FormActionSrc = host + src.replace("/", "%2F");

        FormInputData = new TreeMap<>();
        for (Element elm : form.getElementsByTag("input")) {
            if (elm.attr("type").equals("hidden"))
                FormInputData.put(elm.attr("name"), elm.attr("value"));
        }
    }

    /**
     * ?
     * @throws IOException 
     */
    private void getImageCpatcha() throws IOException {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpGet httpGet = new HttpGet(ImageCaptchaSrc);
            httpGet.setConfig(DEFAULT_PARAMS);
            httpGet.setHeader("Referer", host + "check_ctno1.jsp");

            String cookies = CookieMapToString(cookieMap);
            if (!cookies.equals(""))
                httpGet.setHeader("Cookie", cookies);

            try (CloseableHttpResponse httpResponse = httpClient.execute(httpGet)) {

                //  HttpStatusCode != 200
                if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                    String ErrorCode = "Response Status : " + httpResponse.getStatusLine().getStatusCode();
                    throw new IOException(ErrorCode);
                }

                String hstr;
                for (Header header : httpResponse.getHeaders("Set-Cookie")) {
                    hstr = header.getValue().split(";")[0];
                    cookieMap.put(hstr.split("=", 2)[0], hstr.split("=", 2)[1]);
                }

                imgName = ticket.getTrainCode() + "_captchImg.jpg";
                //out.println(filePath + imgName);
                try (BufferedInputStream buff = new BufferedInputStream(httpResponse.getEntity().getContent());
                        FileOutputStream imgfile = new FileOutputStream(filePath + imgName)) {

                    byte[] data = new byte[1024];
                    int length;
                    while ((length = buff.read(data)) != -1) {
                        imgfile.write(data, 0, length);
                    }
                }
            }
        }
    }

    /**
     * ?
     * @throws IOException 
     */
    private void getVoiceCpatcha() throws IOException {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpGet httpGet = new HttpGet(VoiceCaptchaSrc);
            httpGet.setConfig(DEFAULT_PARAMS);
            httpGet.setHeader("Referer", host + "check_ctno1.jsp");

            String cookies = CookieMapToString(cookieMap);
            if (!cookies.equals(""))
                httpGet.setHeader("Cookie", cookies);

            try (CloseableHttpResponse httpResponse = httpClient.execute(httpGet)) {

                //  HttpStatusCode != 200
                if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                    String ErrorCode = "Response Status : " + httpResponse.getStatusLine().getStatusCode();
                    throw new IOException(ErrorCode);
                }

                String hstr;
                for (Header header : httpResponse.getHeaders("Set-Cookie")) {
                    hstr = header.getValue().split(";")[0];
                    cookieMap.put(hstr.split("=", 2)[0], hstr.split("=", 2)[1]);
                }

                vocName = ticket.getTrainCode() + "_captchVoc.wav";
                //out.println(filePath + vocName);
                try (BufferedInputStream buff = new BufferedInputStream(httpResponse.getEntity().getContent());
                        FileOutputStream imgfile = new FileOutputStream(filePath + vocName);) {

                    byte[] data = new byte[1024];
                    int length;
                    while ((length = buff.read(data)) != -1) {
                        imgfile.write(data, 0, length);
                    }
                }
            }
        }
    }

    /**
     * ?
     * @throws IOException 
     */
    private void sendTicketingRequest() throws IOException {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {

            HttpPost httpPost = new HttpPost(FormActionSrc);
            httpPost.setConfig(ticketing_params);
            httpPost.addHeader("Referer", host + "check_ctno1.jsp");
            httpPost.addHeader("Origin", host);

            //  Cookie
            String cookies = CookieMapToString(cookieMap);
            if (!cookies.equals(""))
                httpPost.setHeader("Cookie", cookies);

            FormInputData.put("randInput", ticket.getCrack_num());

            List<NameValuePair> nvps = new ArrayList<>();
            FormInputData.forEach((k, v) -> {
                nvps.add(new BasicNameValuePair(k, v));
            });

            httpPost.setEntity(new UrlEncodedFormEntity(nvps));

            //  ??
            ticket.setRequestTicketingTime(getTime());
            try (CloseableHttpResponse httpResponse = httpClient.execute(httpPost)) {
                //  HttpStatusCode != 200
                if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                    String ErrorCode = "Response Status : " + httpResponse.getStatusLine().getStatusCode();
                    throw new IOException(ErrorCode);
                }

                String htmlpath = filePath + ticket.getTrainCode() + "_result.html";
                try (InputStreamReader isr = new InputStreamReader(httpResponse.getEntity().getContent(), "big5");
                        BufferedReader reader = new BufferedReader(isr);
                        FileOutputStream htmlstream = new FileOutputStream(htmlpath)) {
                    String line;
                    StringBuilder builder = new StringBuilder();

                    while ((line = reader.readLine()) != null) {
                        builder.append(line);
                        builder.append("\n");
                    }

                    FinishTicketingPageHTML = builder.toString();
                    htmlstream.write(FinishTicketingPageHTML.getBytes("big5"));
                }
            }
            ticket.setResponseTicketingTime(getTime());
        }
    }

    /**
     * ??
     * @return ?
     */
    private int praseTicketingResultPage() {
        Document doc = Jsoup.parse(FinishTicketingPageHTML);

        Elements fonts = doc.getElementsByTag("font");
        if (fonts != null) {

            //  ?
            for (Element font : fonts) {
                if (font.text().equals(", ?"))
                    return ROCID_WRONG;
            }
        }

        Elements strongs = doc.getElementsByTag("strong");
        if (strongs != null) {

            //  ?
            for (Element strong : strongs) {
                if (strong.text().equals(""))
                    return RAND_OR_TIMEOUT_FAIL;
            }

            //  ?
            for (Element strong : strongs) {
                if (strong.text().contains(
                        "????"))
                    return TRAIN_STATION_WRONG;
            }

            //  ??
            for (Element strong : strongs) {
                if (strong.text().equals("??")
                        || strong.text().equals("????"))
                    return TRAIN_NO_SEAT;
            }

            //  ??
            for (Element strong : strongs) {
                if (strong.text().contains("?(?)?"))
                    return TICKETING_TO_LATE;
            }

            //  ?
            for (Element strong : strongs) {
                if (strong.text().contains(""))
                    return TICKETING_TO_EARLY;
            }

            //  ?
            for (Element strong : strongs) {
                if (strong.text().contains("??"))
                    return TRAIN_NUM_WRONG;
            }

            //  ??
            for (Element strong : strongs) {
                if (strong.text().equals("")) {
                    String orderCode = doc.getElementById("spanOrderCode").text();
                    ticket.setOrderCode(orderCode);

                    return TICKETING_SUCCESS;
                }
            }
        }

        //  ??
        return UNKNOW_PRASE_RESULT;
    }

    private static String getTime() {
        return timeFormater.format(new Date(NET_INFO.getCurrentMilli()));
    }
}