Java实现12306登录和查票

前言:

  之前一直打算写一个模拟12306的工具,一直拖到现在,实在忍不了了,最近艰难的一步一步开始。由于想重新学习一下Java相关的知识,所以使用Java来进行开发,目前总算是有了一点进展,已经实现了登录和查票功能,先记录一下。下单以及其他抢票设置还在开发中。。。

界面:

  本文主要是关注功能的实现,另外就是javaswing的排版也不是很擅长,所以界面比较丑陋,将就看一下就行,目前主要是主界面、登录界面以及日期选择界面,先看一下效果:
查票结果
登录界面 日期选择控件
  这里说明一下,日期选择控件是从网上找的一片文章拿过来用的,希望不要见怪。文章地址是:DateChooser日期选择器sw

车站信息:

  由于车站信息可能会有变化,包括新增车站或者车站改名之类的,所以要保证车站名称及对应的车站编号是最新的。
  static String getStationUrl = “https://kyfw.12306.cn/otn/resources/js/framework/station_name.js”;
  getStationUrl:为Get请求,没有参数。用于获取全国车站名称信息,后续的查票操作中需要将中文车站名称转换为对应的车站编号。。

登录模块:

  登录模块主要是要解决验证码部分,其他都好说。目前已经实现完整的验证码选择、提交以及验证等功能。突然好像忘了加上验证码刷新功能了(后续补上)。当前每请求一次会保存一张验证码图片在src同级的yzm目录下(目录需要自己创建),后续可以考虑用这些已有的验证码做自动识别,这是后话了。下面按请求顺序说一下登录过程中分别请求的几个URL:
  static String initUrl = “https://kyfw.12306.cn/otn/login/init”;
  string String getJsUrl = "https://kyfw.12306.cn/otn/HttpZF/GetJS
  static String getRailUrl = “https://kyfw.12306.cn/otn/HttpZF/logdevice”+
           “?algID=XWptt1kXbs”+
           “&hashCode=K7H-SogpeC4-tIYLqCXJabQWEnBXNROVnaPuQXU8Vec”+
           “&FMQw=0”+
           “&q4f3=zh-CN”+
           “&VPIf=1”+
           “&custID=133”+
           “&VEek=unknown”+
           “&dzuS=0”+
           “&yD16=0”+
           “&EOQP=89f60554e6cb588cf7dcc391a91488a1”+
           “&lEnu=176525634”+
           “&jp76=52d67b2a5aa5e031084733d5006cc664”+
           “&hAqN=Win32”+
           “&platform=WEB”+
           “&ks0Q=d22ca0b81584fbea62237b14bd04c866”+
           “&TeRS=1010x1680”+
           “&tOHY=24xx1050x1680”+
           “&Fvje=i1l1o1s1”+
           “&q5aJ=-8”+
           “&wNLf=99115dfb07133750ba677d055874de87”+
“&0aew=Mozilla/5.0%20(Windows%20NT%2010.0;%20Win64;%20x64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/76.0.3809.100%20Safari/537.36”+
           “&E3gR=c0e12f6dc8fe327988a902df0d354cec”+
           “&timestamp=”+String.valueOf(System.currentTimeMillis());
  static String getYzmUrl = “https://kyfw.12306.cn/passport/captcha/captcha-image64?”;
  static String checkYzmUrl = “https://kyfw.12306.cn/passport/captcha/captcha-check?”;
  static String loginUrl = “https://kyfw.12306.cn/passport/web/login”;

  initUrl:为Get请求,没有参数。用于获取后面请求中的一些cookie信息。
  getJsUrl:为Get请求,没有参数。用于请求获取一个js文件。
  getRailUrl:为Get请求,参数前面都列出来了。用于请求RAIL_DEVICEID和RAIL_EXPIRATION两个参数,需要将这两个参数获取到,然后添加到cookie中,不然在登录的时候会重定向到https://www.12306.cn/mormhweb/logFiles/error.html,该页面显示“网络可能存在问题,请您重试一下!”。重点关注请求中的algIDhashCode两个参数,algID可以从getJsUrl这个请求中返回的js文件中拿到,大概位置在:ab.getJSON("https://kyfw.12306.cn/otn/HttpZF/logdevice" + ("?algID\x3dXWptt1kXbs\x26hashCode\x3d" + e + a), null,hashCode这个参数应该也是冲上述js代码处获取到的,但是博主对js文件看不太懂,所以直接用fiddler工具抓了个getRailUrl请求的包,直接从里面拿出来的hashCode参数。但是这两个参数应该过一段时间会失效,失效的表现就是在登录的时候会提示重定向到https://www.12306.cn/mormhweb/logFiles/error.html这个页面,此时需要重新获取js文件,重新从js文件里面获取这两个参数,或者通过fiddler工具抓包进行获取,重新设置到cookie里面。
  getYzmUrl:为Get请求,需要携带{“login_site”:“E”, “module”:“login”, “rand”:“sjrand”, “callback”:“xxx”, "":“xxx”}这五个参数,另外还有个随机数。用于获取验证码,返回的是一张图片,图片顶部为点击验证码提示语,下部为8块区域,分别显示8张验证码。请求URL示例:https://kyfw.12306.cn/passport/captcha/captcha-image64?login_site=E&module=login&rand=sjrand&1565256427784&callback=jQuery19105951551454704869_1565256422938&=1565256422940
  checkYzmUrl:为Get请求,需要携带{“callback”:“xxx”, “answer”:“xxx”, “rand”:“sjrand”, “login_site”:“E”, “_”:“xxx”}这五个参数,用于校验验证码。其中answer参数为验证码图片座标,如:194,54,48,48。返回的字符串中result_code为4代表验证成功。(目前返回的是jQuery开头的一串字符串,其中()中间的部分为json格式,后面12306可能会有变动)
  loginUrl:为Post请求,需要携带{“username”:“xxx”, “password”:“xxx”, “appid”:“otn”, “answer”:“xxx”}这四个参数。answer参数与校验验证码中的answer参数一样。返回的json中对象中result_code为0代表登录成功。(目前返回的为json格式的数据,后面12306可能会有变动)
  关于验证码座标的说明:

  • 整张图片的大小是:293*190 单位:像素
  • 打字机这一排提示语所在行的宽度为29
  • 第一排第一张小图片的范围是(5,41)~(72,108) 长:67,宽:67 间距都是5px
  • 第二排第一张小图片的范围是(5,41+5+67)~(72,41+5+67+67) 长:67,宽:67 间距都是5px
  • 第一排第二张小图片的范围是(5+67+5,41)~(5+67+5+67,108) 长:67,宽:67 间距都是5px

查票模块:

  查票模块目前不添加cookie中的JSESSIONID、RAIL_DEVICEID、RAIL_EXPIRATION也可以查询成功,但是后续下单包括支付等操作就需要携带上述cookie参数。
  static queryTicketsUrl = “https://kyfw.12306.cn/otn/leftTicket/query?”;
  queryTicketsUrl 为Get请求,需要携带{“leftTicketDTO.train_date”:“xxx”, “leftTicketDTO.from_station”:“xxx”, “leftTicketDTO.to_station”:“xxxx”, “purpose_codes”:“xxx”}这四个参数,分别是出发日期、起始站、终到站和类型。

结尾:

  目前只是简单的实现了登录和查票功能。包括根据车次类型过滤等小功能都已实现。后续持续更新下单等其他功能模块,包括界面优化等功能。

代码:

  完整代码:Java实现12306登录和查询功能,在之前代码之前需要在工程的src同级目录下创建yzm文件夹,用来保存验证码图片,另外sign.jpg文件为30*30,可以随便替换,保证大小一致就行。代码中用到的第三方jar包主要有:
beangle-bundles-my97-4.8
commons-codec-1.12
commons-httpclient-3.1
commons-logging-1.2
fastjson-1.2.58
httpclient-4.5.5
httpcore-4.4.7
jcalendarbutton-1.4.5
ps:

package my12307;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableModel;

import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
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.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

public class My12307 extends JFrame {

	private static final long serialVersionUID = 1L;
	private JTextField cfdField;
	private JTextField mddField;
	private DateChooser dc;
	private ButtonGroup radioGroup;
	private JRadioButton adultRadioButton;
	private JRadioButton studentRadioButton;
	private JTable table;
	private JScrollPane scrollPane;
	private String[] headers = {"车次","出发站","到达站","出发时间","到达时间",
			             "历时","商务/特等座","一等座","二等座","高级软卧",
			             "软卧","动卧","硬卧","软座","硬座",
			             "无座","其他","备注"};
	private JCheckBox ck01,ck02,ck03,ck04,ck05,ck06;
	private Set<String> ccName;
	private Vector<String> tableHeaders;
	private HashMap<String, String> cityMap;
	private Vector<Vector<String>> gDatas;
	
	public My12307() throws ClientProtocolException, IOException {
		initEntity();
		initFrame();
		Utils.initLogin();
		Utils.initRail();
	}
	
	//获取车站信息
	private void getStationInfo() {
		HttpGet httpGet = new HttpGet(Utils.getStationUrl);
		try {
			CloseableHttpResponse cHttpResp = Utils.getHttpClient().execute(httpGet);
			HttpEntity entity = cHttpResp.getEntity();
			String result = EntityUtils.toString(entity,"utf-8");
			Utils.putStation2Map(result, cityMap);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private void initEntity(){
		ccName = new HashSet<String>();
		cityMap = new HashMap<String, String>();
		gDatas = new Vector<Vector<String>>();
		tableHeaders = new Vector<String>();
		for (int i = 0; i < headers.length; i++) {
			tableHeaders.add(i, headers[i]);
		}
	}
	
	private void initFrame() {
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		int width = 1000;
		int height = 660;
		Dimension d = Toolkit.getDefaultToolkit().getScreenSize();//获得屏幕尺寸
		setBounds((d.width - width)/2, (d.height - height)/2, width, height);
		getContentPane().setLayout(new BorderLayout());
		this.setTitle("12307票票");
		this.setResizable(false);
		this.setIconImage(new ImageIcon("src/icon.jpg").getImage());

		JMenuBar menubar = new JMenuBar();
		JMenu menuDL = new JMenu("登录");
		//JMenu menuTC = new JMenu("退出");
		JMenu menuQueryM = new JMenu("查询联系人");
		menubar.add(menuDL);
		//menubar.add(menuTC);
		menubar.add(menuQueryM);
		this.setJMenuBar(menubar);
		addLoginListener(My12307.this, menuDL);
		//addLogoutListener(menuTC);
		addQueryMListener(menuQueryM);

		JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 2, 5));
		topPanel.setPreferredSize(new Dimension(1000,70));
		JPanel centerPanel = new JPanel();
		centerPanel.setPreferredSize(new Dimension(1000,380));
		JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 1, 5));
		bottomPanel.setPreferredSize(new Dimension(1000,210));

		//出发地,目的地
		JLabel label1 = new JLabel("出发地:");
		JLabel label2 = new JLabel("目的地:");
		cfdField = new JTextField();
		cfdField.setPreferredSize(new Dimension(cfdField.getWidth(),25));
		cfdField.setColumns(10);
		mddField = new JTextField();
		mddField.setPreferredSize(new Dimension(mddField.getWidth(),25));
		mddField.setColumns(10);

		//成人,学生
		radioGroup = new ButtonGroup();
		adultRadioButton = new JRadioButton("成人");
		studentRadioButton = new JRadioButton("学生");
		radioGroup.add(adultRadioButton);
		radioGroup.add(studentRadioButton);
		adultRadioButton.setSelected(true);

		//出发日期
		JLabel label3 = new JLabel("出发日期:");
		dc = new DateChooser("yyyy-MM-dd");

		//查询
		JButton queryBbutton = new JButton("查询");
		addButtonListener(queryBbutton);

		//车次类型
		JLabel label4 = new JLabel("车次类型:");
		JPanel panel1 = new JPanel();
		ck01 = new JCheckBox("GC-高铁/城际");
		ck02 = new JCheckBox("D-动车");
		ck03 = new JCheckBox("Z-直达");
		ck04 = new JCheckBox("T-特快");
		ck05 = new JCheckBox("K-快速");
		ck06 = new JCheckBox("其他");
		ck01.setName("GC");
		ck02.setName("D");
		ck03.setName("Z");
		ck04.setName("T");
		ck05.setName("K");
		addCheckboxListener(ck01);
		addCheckboxListener(ck02);
		addCheckboxListener(ck03);
		addCheckboxListener(ck04);
		addCheckboxListener(ck05);
		addCheckboxListener(ck06);
		panel1.add(ck01);
		panel1.add(ck02);
		panel1.add(ck03);
		panel1.add(ck04);
		panel1.add(ck05);
		panel1.add(ck06);

		JPanel panel2 = new JPanel();
		panel2.add(label4);
		panel2.add(panel1);

		topPanel.add(label1);
		topPanel.add(cfdField);
		topPanel.add(label2);
		topPanel.add(mddField);
		topPanel.add(adultRadioButton);
		topPanel.add(studentRadioButton);
		topPanel.add(label3);
		topPanel.add(dc);
		topPanel.add(queryBbutton);
		topPanel.add(panel2);

		//查票查询table
		String[][] content = new String[0][18];
		TableModel model = new DefaultTableModel(content, tableHeaders.toArray());
		table = new JTable();
		DefaultTableCellRenderer tcr = new DefaultTableCellRenderer();
		tcr.setHorizontalAlignment(SwingConstants.CENTER);
		table.setDefaultRenderer(Object.class, tcr);
		table.setRowHeight(30);  //设置行高
		JTableHeader tableHeader = table.getTableHeader();
		tableHeader.setResizingAllowed(false);
		tableHeader.setReorderingAllowed(false);
		tableHeader.setFont(new Font("宋体", 0, 12));
		tableHeader.setForeground(new Color(255,255,255));//设置字体颜色
		tableHeader.setBackground(new Color(33,132,199)); //设置背景颜色
		tableHeader.setPreferredSize(new Dimension(tableHeader.getHeight(),40));
		table.setModel(model);
		Utils.setTableColumnWidth(tableHeaders, table);
			scrollPane = new JScrollPane(table) {
			private static final long serialVersionUID = 1L;
			public Dimension getPreferredSize() {
				return new Dimension(990, 312);
			}
		};
		centerPanel.add(scrollPane);

		//抢票条件设置区
		JPanel passengerPanel = new JPanel();
		JPanel seatTypePanel = new JPanel();
		passengerPanel.setBorder(BorderFactory.createTitledBorder("联系人"));
		seatTypePanel.setBorder(BorderFactory.createTitledBorder("席别"));
		passengerPanel.setPreferredSize(new Dimension(100,200));
		seatTypePanel.setPreferredSize(new Dimension(100,200));
		bottomPanel.add(passengerPanel);
		bottomPanel.add(seatTypePanel);

		getContentPane().add(topPanel, BorderLayout.NORTH);
		getContentPane().add(centerPanel, BorderLayout.CENTER);
		getContentPane().add(bottomPanel, BorderLayout.SOUTH);

		//获取车站信息
		getStationInfo();
	}
	
	private void addLoginListener(JFrame frame, JMenu menu) {
		menu.addMouseListener(new MouseListener() {
			@Override
			public void mouseReleased(MouseEvent e) {
			}
			@Override
			public void mousePressed(MouseEvent e) {
			}
			@Override
			public void mouseExited(MouseEvent e) {
			}
			@Override
			public void mouseEntered(MouseEvent e) {
			}
			@Override
			public void mouseClicked(MouseEvent e) {
				System.out.println("点击登录");
				LoginDialog loginDialog;
				try {
					loginDialog = new LoginDialog(My12307.this);
					loginDialog.setVisible(true);
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		});
	}
	
	private void addTableRowListener(JTable table) {
		table.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				table.setSelectionBackground(new Color(135,206,250));
				int row = table.getSelectedRow();
				int col = table.getSelectedColumn();
				System.out.println("点击第"+row+"行"+",第"+col+"列");
			}
		});
	}
	
	private void addCheckboxListener(JCheckBox checkbox) {
		checkbox.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				String chName = checkbox.getName();
				if("GC".equals(chName)) {
					if(checkbox.isSelected()) {
						ccName.add("G");
						ccName.add("C");
					}else {
						ccName.remove("G");
						ccName.remove("C");
					}
				}else {
					if(checkbox.isSelected()) {
						ccName.add(chName);
					}else {
						ccName.remove(chName);
					}
				}
				
				//过滤数据
				if(!gDatas.isEmpty()) {
					filterDataByCheckBox();
					addTableRowListener(table);
				}
			}
		});
	}
	
	private void addButtonListener(JButton button) {
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				//清空table
				((DefaultTableModel)table.getModel()).getDataVector().clear();
				table.updateUI();
				//String trainDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date()).toString();
				String trainDate = dc.showDate.getText();
				String fromStationName = cfdField.getText();
				String toStationName = mddField.getText();
				String fromStation = cityMap.get(fromStationName);
				String toStation = cityMap.get(toStationName);
				if ("".equals(fromStationName) || fromStation == null) {
					System.out.println("出发车站名有误,请重新输入。");
					return;
				}
				if ("".equals(toStationName) || toStation == null) {
					System.out.println("目的车站名有误,请重新输入。");
					return;
				}
				String type = "";
				if(radioGroup.getSelection() == adultRadioButton.getModel()) {
					type = "ADULT";
				}else {
					type = "0X00";
				}
				
				String queryTicketsUrl = Utils.queryTicketsUrl+"leftTicketDTO.train_date=" + trainDate
						   + "&leftTicketDTO.from_station=" + fromStation + "&leftTicketDTO.to_station="
						   + toStation + "&purpose_codes=" + type;
				try {
					System.out.println(queryTicketsUrl);
					sendQueryTicketRequest(queryTicketsUrl);
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		});
	}
	
	private void colloctionData(Vector<String> row, String[] resultData) {
		row.add(tableHeaders.indexOf("车次"), resultData[3]);
		row.add(tableHeaders.indexOf("出发站"), Utils.getKeyFromMap(cityMap,resultData[6]));
		row.add(tableHeaders.indexOf("到达站"), Utils.getKeyFromMap(cityMap,resultData[7]));
		row.add(tableHeaders.indexOf("出发时间"), resultData[8]);
		row.add(tableHeaders.indexOf("到达时间"), resultData[9]);
		row.add(tableHeaders.indexOf("历时"), resultData[10]);
		if(resultData[32] != "") {
			row.add(tableHeaders.indexOf("商务/特等座"), ("".equals(resultData[32]))?"--":resultData[32]);
		}else {
			row.add(tableHeaders.indexOf("商务/特等座"), ("".equals(resultData[25]))?"--":resultData[25]);
		}
		row.add(tableHeaders.indexOf("一等座"), ("".equals(resultData[31]))?"--":resultData[31]);
		row.add(tableHeaders.indexOf("二等座"), ("".equals(resultData[30]))?"--":resultData[30]);
		row.add(tableHeaders.indexOf("高级软卧"), ("".equals(resultData[21]))?"--":resultData[21]);
		row.add(tableHeaders.indexOf("软卧"), ("".equals(resultData[23]))?"--":resultData[23]);
		row.add(tableHeaders.indexOf("动卧"), ("".equals(resultData[27]))?"--":resultData[27]);
		row.add(tableHeaders.indexOf("硬卧"), ("".equals(resultData[28]))?"--":resultData[28]);
		row.add(tableHeaders.indexOf("软座"), ("".equals(resultData[24]))?"--":resultData[24]);
		row.add(tableHeaders.indexOf("硬座"), ("".equals(resultData[29]))?"--":resultData[29]);
		row.add(tableHeaders.indexOf("无座"), ("".equals(resultData[26]))?"--":resultData[26]);
		row.add(tableHeaders.indexOf("其他"), ("".equals(resultData[22]))?"--":resultData[22]);
		//row.add(tableHeaders.indexOf("备注"), resultData[1]);
		gDatas.add(row);
	}
	
	@SuppressWarnings("unchecked")
	private void fillData2Table() {
		if (!gDatas.isEmpty()) {
			Vector<Vector<String>> datas = new Vector<Vector<String>>();
			datas = (Vector<Vector<String>>) gDatas.clone();
			DefaultTableModel model = new DefaultTableModel(){
				private static final long serialVersionUID = 1L;
				@Override
				public boolean isCellEditable(int row, int column) {
					return false;
				}
			};
			model.setDataVector(datas, tableHeaders);
			table.setModel(model);
			Utils.setTableColumnWidth(tableHeaders, table);
		}
	}
	
	@SuppressWarnings("unchecked")
	private void filterDataByCheckBox() {
		Vector<Vector<String>> ckData = new Vector<Vector<String>>();
		for(Vector<String> v : gDatas) {
			if(ccName.contains(v.get(0).toString().charAt(0)+"")) {
				ckData.add(v);
			}
		}
		if (ckData.isEmpty() &&
		   (!ck01.isSelected() && !ck02.isSelected() && !ck03.isSelected() &&
			!ck04.isSelected() && !ck05.isSelected() && !ck06.isSelected())) {
			ckData = (Vector<Vector<String>>) gDatas.clone();
		}
		((DefaultTableModel)table.getModel()).getDataVector().clear();
		DefaultTableModel model = new DefaultTableModel(){
			private static final long serialVersionUID = 1L;
			@Override
			public boolean isCellEditable(int row, int column) {
				return false;
			}
		};
		model.setDataVector(ckData, tableHeaders);
		table.setModel(model);
		Utils.setTableColumnWidth(tableHeaders, table);
	}
	
	private void sendQueryTicketRequest(String url) throws HttpException, IOException {
		HttpGet get = new HttpGet(url);
		CloseableHttpResponse response = Utils.getHttpClient().execute(get);
		int statusCode = response.getStatusLine().getStatusCode();
		String result = "";
		if (statusCode == HttpStatus.SC_OK) {
            System.out.println("查票成功.");
            result = EntityUtils.toString(response.getEntity());
        }else {
            System.out.println("查票失败,url="+url+",statusCode="+statusCode);
            return;
        }
		JSONObject obj = JSON.parseObject(result);
		JSONArray array = obj.getJSONObject("data").getJSONArray("result");
		int len = array.size();
		//获取车次信息在3号位置,始发站信息在6号位置,终点站信息在7号位置,出发时间在8号位置,抵达时间在9号位置
		//经历时间在10号位置,特别注意,商务/特等座在32或25位置,一等座信息在31号位置,二等座信息在30号位置
		//高级软卧信息在21号位置,软卧信息在23号位置,动卧信息在27号位置,硬卧信息在28号位置
		//软座信息在24号位置,硬座信息在29号位置,无座信息在26号位置,其他信息在22号位置,备注信息在1号位置
		gDatas.clear();
		for(int i = 0; i < len; i++) {
			Vector<String> row = new Vector<String>();
			String[] resultData = array.get(i).toString().split("\\|");
			//收集数据
			colloctionData(row, resultData);
		}
		//填充数据
		fillData2Table();
		//根据复选框过滤数据
		if (ck01.isSelected() || ck02.isSelected() || ck03.isSelected() ||
			ck04.isSelected() || ck05.isSelected() || ck06.isSelected()) {
			filterDataByCheckBox();
		}
		//给数据添加背景色
		Utils.setBackgoundColorForTable(table);
		//添加行点击监听
		addTableRowListener(table);
		
		obj.clear();
	}
	
	private void addQueryMListener(JMenu menu) {
		menu.addMouseListener(new MouseListener() {
			@Override
			public void mouseReleased(MouseEvent e) {
			}
			@Override
			public void mousePressed(MouseEvent e) {
			}
			@Override
			public void mouseExited(MouseEvent e) {
			}
			@Override
			public void mouseEntered(MouseEvent e) {
			}
			@Override
			public void mouseClicked(MouseEvent e) {
				try {
					sendQueryPassengersRequest();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		});
	}
	
	private void sendQueryPassengersRequest() throws ClientProtocolException, IOException {
		HttpPost post = new HttpPost(Utils.queryPassengersUrl);
		List<NameValuePair> formPair = new ArrayList<NameValuePair>();
	    formPair.add(new BasicNameValuePair("pageIndex", "1"));
	    formPair.add(new BasicNameValuePair("pageSize", "15"));
	    UrlEncodedFormEntity urlEntity = new UrlEncodedFormEntity(formPair, "UTF-8");
	    post.setEntity(urlEntity);
	    Utils.setPostRequestHeaders(post);
	    CloseableHttpResponse response;
	    response = Utils.getHttpClient().execute(post);
    	int respCode = response.getStatusLine().getStatusCode();
    	if(respCode == HttpStatus.SC_OK) {
    		JSONObject obj = JSONObject.parseObject(EntityUtils.toString(response.getEntity()));
    		if(Integer.parseInt(obj.getString("httpstatus")) == 200) {
    			System.out.println("获取联系人成功");
    			System.out.println(obj.toString());
    		}else {
    			System.out.println("获取联系人失败");
    		}
    	}else {
    		System.out.println("获取联系人失败");
    	}
	}

	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					My12307 frame = new My12307();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
}
package my12307;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

import org.apache.commons.httpclient.HttpStatus;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
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.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

public class LoginDialog extends JDialog{
	
	private static final long serialVersionUID = 1L;
	private JTextField userField;
	private JPasswordField pswdField;
	private JPanel imagePanel;
	private JLabel imageLabel;
	private Icon icon;
	private int X = 10;
	private int Y = 15;
	private JLayeredPane layeredPane = new JLayeredPane();;
	private StringBuffer callback = new StringBuffer("jQuery19107521990954709705_");
	private String random = "";
	private String random2 = "";
	private String yzmAnswer;
	
	private void initFrame(JFrame parent) throws ClientProtocolException, IOException{
		
		userField = new JTextField(15);
		pswdField = new JPasswordField(15);
		JLabel userLabel = new JLabel("用户名:");
		JLabel pswdLabel = new JLabel("密    码::");
		JButton loginButton = new JButton("登录");
		JButton cancelButton = new JButton("取消");
		addLoginButtonListener(loginButton);
		addCancelButtonListener(cancelButton);
		JPanel inputPanel = new JPanel(new GridLayout(2, 2, -90, 15));
		JPanel buttonPanel = new JPanel(new GridLayout(1, 2, 10, 0));
		imagePanel = new JPanel(new GridLayout(1, 1, 10, 0));
		
		inputPanel.add(userLabel);
		inputPanel.add(userField);
		inputPanel.add(pswdLabel);
		inputPanel.add(pswdField);
		inputPanel.setBorder(BorderFactory.createEmptyBorder(X, Y, 10, 15));
		
		buttonPanel.add(loginButton);
		buttonPanel.add(cancelButton);
		buttonPanel.setBorder(BorderFactory.createEmptyBorder(X, Y, 10, 15));
		
		setLayout(new BorderLayout());
		getContentPane().add(inputPanel, BorderLayout.NORTH);
		getContentPane().add(buttonPanel, BorderLayout.CENTER);
		
		getYzmBindListener();
		
		int parentX = parent.getX();
		int parentY = parent.getY();
		int parentWidth = (int)parent.getWidth();
		int parentHeight = (int)parent.getHeight();
		
		int childWidth = 280;
		int childHight = 300;
		int childX = parentX + parentWidth/2 - childWidth/2;
		int childY = parentY + parentHeight/2 - childHight/2;
		setBounds(childX, childY, childWidth, childHight);
		setTitle("登录");
		setResizable(false);
		pack();
		
		YzmUtils.initYzm(layeredPane);
	}
	
	public LoginDialog(JFrame parent) throws ClientProtocolException, IOException {
		super(parent, true);
		setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		if(Utils.cookieStore.getCookies().size() == 0) {
			try {
				Utils.initLogin();
				Utils.initRail();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}
		initFrame(parent);
	}
	
	private void clearYzmPanel(){
		YzmUtils.yzm1 = 0;
		YzmUtils.yzm2 = 0;
		YzmUtils.yzm3 = 0;
		YzmUtils.yzm4 = 0;
		YzmUtils.yzm5 = 0;
		YzmUtils.yzm6 = 0;
		YzmUtils.yzm7 = 0;
		YzmUtils.yzm8 = 0;
		
		imagePanel.removeAll();
		layeredPane.removeAll();
	}
	
	@SuppressWarnings("deprecation")
	//获取验证码图片并绑定点击验证码事件
	private void getYzmBindListener() throws ClientProtocolException, IOException {
		clearYzmPanel();
		String image = getYzmImage();
		imageLabel = new JLabel();
		icon = new ImageIcon(image);
		imageLabel.setIcon(icon);
		addLabelListener(imageLabel);//监听验证码点击事件
		imagePanel.add(imageLabel);
		imagePanel.setBounds(0, 0, icon.getIconWidth(), icon.getIconHeight());
		
		Dimension dimension = new Dimension(icon.getIconWidth(), icon.getIconHeight());
		layeredPane.setPreferredSize(dimension);
		layeredPane.add(imagePanel, new Integer(0));
		getContentPane().add(layeredPane, BorderLayout.SOUTH);
		
		YzmUtils.initYzm(layeredPane);
	}

	private void addLabelListener(JLabel imageLbel) {
		imageLbel.addMouseListener(new MouseListener() {
			@Override
			public void mouseReleased(MouseEvent e) {
			}
			@Override
			public void mousePressed(MouseEvent e) {
			}
			@Override
			public void mouseExited(MouseEvent e) {
			}
			@Override
			public void mouseEntered(MouseEvent e) {
			}
			@Override
			public void mouseClicked(MouseEvent e) {
				YzmUtils.addSign2Yzm(e);
			}
		});
	}

	private void addCancelButtonListener(JButton cancelButton) {
		cancelButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				LoginDialog.this.dispose();
			}
		});
	}
	
	private String login12306(String username, String password) throws IOException {
		String uamtk = "";
		HttpPost post = new HttpPost(Utils.loginUrl);
		List<NameValuePair> formPair = new ArrayList<NameValuePair>();
	    formPair.add(new BasicNameValuePair("username", username));
	    formPair.add(new BasicNameValuePair("password", password));
	    formPair.add(new BasicNameValuePair("appid", "otn"));
	    formPair.add(new BasicNameValuePair("answer", yzmAnswer));
	    UrlEncodedFormEntity urlEntity = new UrlEncodedFormEntity(formPair, "UTF-8");
	    post.setEntity(urlEntity);
	    Utils.setPostRequestHeaders(post);
	    CloseableHttpResponse response;
	    
	    int respCode = 0;
	    int loop = 5;
	    while(loop > 0) {
	    	response = Utils.getHttpClient().execute(post);
	    	respCode = response.getStatusLine().getStatusCode();
	    	JSONObject obj = JSONObject.parseObject(EntityUtils.toString(response.getEntity()));
	    	if(respCode == HttpStatus.SC_OK) {
	    		if("0".equals(obj.getString("result_code"))) {
	    			System.out.println("登录成功,result_code:"+respCode+"result_message:"+
	    					obj.getString("result_message")+"uamtk:"+obj.getString("uamtk"));
	    			uamtk = obj.getString("uamtk");
	    			this.setVisible(false);
	    		    return uamtk;
	    		}else {
	    			System.out.println("登录失败,result_code="+obj.getString("result_code")+",result_message:"+obj.getString("result_message"));
		    		//getYzmBindListener();
	    			break;
	    		}
	    		
	    	}else if(respCode == HttpStatus.SC_MOVED_TEMPORARILY){
	    		System.out.println("请求登录重定向,Location:"+response.getFirstHeader("Location").getValue());
	    		//getYzmBindListener();
	    		loop--;
	    	}else {
	    		System.out.println("登录失败,respCode="+respCode+",result_message:"+obj.getString("result_message"));
	    		//getYzmBindListener();
	    		break;
	    	}
	    }
	    getYzmBindListener();
	    return uamtk;
	}
	
	private void addLoginButtonListener(JButton loginButton) {
		loginButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				
				//校验验证码url为:https://kyfw.12306.cn/passport/captcha/captcha-check
				yzmAnswer = YzmUtils.getYzmAnswer();
				if ("".equals(yzmAnswer)) {
					System.out.println("请先选择验证码后再登录");
					return;
				}
				random2 = String.valueOf(Long.parseLong(random2)+1);
				String checkYzmUrl = Utils.checkYzmUrl+"callback="+callback+
						"&answer="+yzmAnswer+"&rand=sjrand&login_site=E&_="+random2;
				System.out.println("校验验证码的url:"+checkYzmUrl);
				HttpGet get = new HttpGet(checkYzmUrl);
				Utils.setGetRequestHeaders(get);
	            // 通过请求对象获取响应对象
	            String[] res = null;
	            String result = "";
	            CloseableHttpResponse response;
				try {
					response = Utils.getHttpClient().execute(get);
					int respCode = response.getStatusLine().getStatusCode();
					HttpEntity entity = null;
		            if (respCode == HttpStatus.SC_OK) {
		            	entity = response.getEntity();
		            	result = EntityUtils.toString(entity);
		            	System.out.println("result:"+result);
		            	res = result.split("\"");
		            }else {
		            	System.out.println("验证失败,statusCode="+respCode);
		            	getYzmBindListener();
		            }
		            if ("4".contentEquals(res[7])) {
		            	System.out.println("验证成功,result_message="+res[3]);
		            	String username = userField.getText();
						String password = new String(pswdField.getPassword());
						//saveCookies();
						String uamtk = login12306(username, password);
						if(!"".equals(uamtk)) {
							sendGetUamTkRequest();
						}
		            }else {
		            	System.out.println("验证失败,result_message="+res[3]);
		            	getYzmBindListener();
		            }
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		});
	}
	
	private void sendGetUamTkRequest() throws ClientProtocolException, IOException {
		HttpPost post = new HttpPost(Utils.getUamTk);
		List<NameValuePair> formPair = new ArrayList<NameValuePair>();
	    formPair.add(new BasicNameValuePair("appid", "otn"));
	    UrlEncodedFormEntity urlEntity = new UrlEncodedFormEntity(formPair, "UTF-8");
	    post.setEntity(urlEntity);
	    Utils.setPostRequestHeaders(post);
	    CloseableHttpResponse response;
	    response = Utils.getHttpClient().execute(post);
    	int respCode = response.getStatusLine().getStatusCode();
    	JSONObject obj = JSONObject.parseObject(EntityUtils.toString(response.getEntity()));
    	if(respCode == HttpStatus.SC_OK) {
    		System.out.println("获取uamtk成功,result_code:"+respCode+"result_message:"+
    				obj.getString("result_message")+"newapptk:"+obj.getString("newapptk"));
    		String newAppTk = obj.getString("newapptk");
    		sendUamAuthClientRequest(newAppTk);
    	}else {
    		System.out.println("获取uamtk失败,respCode="+respCode+"result_message:"+obj.getString("result_message"));
    	}
	}
	
	private void sendUamAuthClientRequest(String newAppTk) throws ClientProtocolException, IOException {
		HttpPost post = new HttpPost(Utils.uamAuthClient);
		List<NameValuePair> formPair = new ArrayList<NameValuePair>();
	    formPair.add(new BasicNameValuePair("tk", newAppTk));
	    UrlEncodedFormEntity urlEntity = new UrlEncodedFormEntity(formPair, "UTF-8");
	    post.setEntity(urlEntity);
	    Utils.setPostRequestHeaders(post);
	    CloseableHttpResponse response;
	    response = Utils.getHttpClient().execute(post);
    	int respCode = response.getStatusLine().getStatusCode();
    	JSONObject obj = JSONObject.parseObject(EntityUtils.toString(response.getEntity()));
    	if(respCode == HttpStatus.SC_OK) {
    		System.out.println("uamAuth成功,result_code:"+respCode+"result_message:"+obj.getString("result_message")+
    			"newapptk:"+obj.getString("newapptk")+"username:"+obj.getString("username"));
    		//saveCookies();
    	}else {
    		System.out.println("uamAuth失败,respCode="+respCode+"result_message:"+obj.getString("result_message"));
    	}
	}
	
	private String getYzmImage() throws ClientProtocolException, IOException {
	    random = String.valueOf(System.currentTimeMillis());
	    random2 = random;
	    random2 = String.valueOf(Long.parseLong(random2)+1);
		callback.append(random);
		
		String getYzmUrl = Utils.getYzmUrl+"login_site=E&module=login&rand=sjrand&"
				+random+"callback="+callback+"&_="+random2;
		System.out.println("请求验证码的url:"+getYzmUrl);
		HttpGet getMethod = new HttpGet(getYzmUrl);
		Utils.setGetRequestHeaders(getMethod);
		CloseableHttpClient client = Utils.getHttpClient();
		Utils.printCookies();
		CloseableHttpResponse response = client.execute(getMethod);
		HttpEntity entity = null;
		int statusCode = response.getStatusLine().getStatusCode();
		if (statusCode == HttpStatus.SC_OK) {
			entity = response.getEntity();
			System.out.println("获取验证码成功.");
		}else {
			System.out.println("获取验证码失败,url="+getYzmUrl+",statusCode="+statusCode);
			return "";
		}
		
		JSONObject obj = JSON.parseObject(EntityUtils.toString(entity));
		Decoder decoder = Base64.getDecoder();
		try {  
            //Base64解码  
			byte[] b = decoder.decode(obj.getString("image"));
            for(int i = 0; i < b.length; ++i){  
                if(b[i] < 0){//调整异常数据  
                    b[i] += 256;  
                }  
            }  
            //生成jpg图片  
            String imgFilePath = "yzm/yzm_"+random+".jpg";//新生成的图片  
            OutputStream out = new FileOutputStream(imgFilePath);      
            out.write(b);  
            out.flush();  
            out.close();  
            return imgFilePath;
        } catch (Exception e){  
        }
		obj.clear();
		return "";
	}
}

package my12307;

import java.awt.Color;
import java.awt.Component;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableCellRenderer;

import org.apache.commons.httpclient.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
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.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

public class Utils {

	static CookieStore cookieStore = new BasicCookieStore();
	static CloseableHttpClient httpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();
	
	static String accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
	static String acceptEncoding = "gzip, deflate, br";
	static String acceptLanguage = "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2";
	static String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0";
	
	//url
	static String getStationUrl = "https://kyfw.12306.cn/otn/resources/js/framework/station_name.js";
	static String queryTicketsUrl = "https://kyfw.12306.cn/otn/leftTicket/query?";
	static String getRailUrl = "https://kyfw.12306.cn/otn/HttpZF/logdevice"+
			//"?algID=8iIPwpB28l"+
			"?algID=XWptt1kXbs"+
			//"&hashCode=XQTW18RSf_dOYnqpGaj_yA-WKSsKbH77QE7zN-cCdB0"+
			"&hashCode=K7H-SogpeC4-tIYLqCXJabQWEnBXNROVnaPuQXU8Vec"+
			"&FMQw=0"+
			"&q4f3=zh-CN"+
			"&VPIf=1"+
			"&custID=133"+
			"&VEek=unknown"+
			"&dzuS=0"+
			"&yD16=0"+
			"&EOQP=89f60554e6cb588cf7dcc391a91488a1"+
			"&lEnu=176525634"+
			"&jp76=52d67b2a5aa5e031084733d5006cc664"+
			"&hAqN=Win32"+
			"&platform=WEB"+
			"&ks0Q=d22ca0b81584fbea62237b14bd04c866"+
			"&TeRS=1010x1680"+
			"&tOHY=24xx1050x1680"+
			"&Fvje=i1l1o1s1"+
			"&q5aJ=-8"+
			"&wNLf=99115dfb07133750ba677d055874de87"+
			"&0aew=Mozilla/5.0%20(Windows%20NT%2010.0;%20Win64;%20x64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/76.0.3809.100%20Safari/537.36"+
			"&E3gR=a54e6d6499e595ae2cfaf80eda685cc2"+
			"&timestamp="+String.valueOf(System.currentTimeMillis());
	static String initUrl = "https://kyfw.12306.cn/otn/login/init";
	static String loginUrl = "https://kyfw.12306.cn/passport/web/login";
	static String logoutUrl = "https://kyfw.12306.cn/otn/login/conf";
	static String logoutUamtk = "https://kyfw.12306.cn/passport/web/auth/uamtk-static";
	static String getYzmUrl = "https://kyfw.12306.cn/passport/captcha/captcha-image64?";
	static String checkYzmUrl = "https://kyfw.12306.cn/passport/captcha/captcha-check?";
	static String getUamTk = "https://kyfw.12306.cn/passport/web/auth/uamtk";
	static String uamAuthClient = "https://kyfw.12306.cn/otn/uamauthclient";
	static String queryPassengersUrl = "https://kyfw.12306.cn/otn/passengers/query";
	
	static CloseableHttpClient getHttpClient() {
		return httpClient;
	}
	
	static CookieStore getCookieStore() {
		return cookieStore;
	}
	
	static void addRailCookies(String exp, String dfp) {
		BasicClientCookie expCookie = new BasicClientCookie("RAIL_EXPIRATION", exp);
        expCookie.setDomain("kyfw.12306.cn");
        expCookie.setPath("/");
        cookieStore.addCookie(expCookie);
        BasicClientCookie dfpCookie = new BasicClientCookie("RAIL_DEVICEID", dfp);
        dfpCookie.setDomain("kyfw.12306.cn");
        dfpCookie.setPath("/");
        cookieStore.addCookie(dfpCookie);
	}
	
	static void setGetRequestHeaders(HttpGet get) {
		get.addHeader("Accept",Utils.accept);
		get.addHeader("Accept-Encoding", Utils.acceptEncoding);
		get.addHeader("Accept-Language", Utils.acceptLanguage);
		get.addHeader("User-Agent",Utils.userAgent);
	}
	
	static void setPostRequestHeaders(HttpPost post) {
		post.addHeader("Accept",Utils.accept);
		post.addHeader("Accept-Encoding", Utils.acceptEncoding);
		post.addHeader("Accept-Language", Utils.acceptLanguage);
		post.addHeader("User-Agent",Utils.userAgent);
	}
	
	static void initLogin() throws ClientProtocolException, IOException {
		HttpGet getMethod = new HttpGet(Utils.initUrl);
		Utils.setGetRequestHeaders(getMethod);
		CloseableHttpResponse response = Utils.getHttpClient().execute(getMethod);
		int statusCode = response.getStatusLine().getStatusCode();
		if (statusCode == HttpStatus.SC_OK) {
            System.out.println("初始化12306成功.");
            Utils.printCookies();
        }else {
            System.out.println("初始化12306失败,url="+Utils.initUrl+",statusCode="+statusCode);
            return;
        }
	}

	static void initRail() throws ClientProtocolException, IOException {
		//获取RAIL_DEVICEID和RAIL_EXPIRATION
		//String getJsUrl = "https://kyfw.12306.cn/otn/HttpZF/GetJS";
		HttpGet get = new HttpGet(Utils.getRailUrl);
		Utils.setGetRequestHeaders(get);
		CloseableHttpResponse response = Utils.getHttpClient().execute(get);
		int statusCode = response.getStatusLine().getStatusCode();
		if (statusCode == HttpStatus.SC_OK) {
            System.out.println("GetJS成功.");
            Utils.printCookies();
            String resStr = EntityUtils.toString(response.getEntity());
            String str = resStr.substring(resStr.indexOf("{"),resStr.indexOf("}")+1);
            System.out.println(str);
            JSONObject obj = JSON.parseObject(str);
            Utils.addRailCookies(obj.getString("exp"), obj.getString("dfp"));
            obj.clear();
        }else {
            System.out.println("GetJS失败,url="+Utils.getRailUrl+",statusCode="+statusCode);
            return;
        }
	}
	
	static void printCookies() {
		System.out.println("打印cookie信息:");
		List<org.apache.http.cookie.Cookie> cs = Utils.getCookieStore().getCookies();
		for (int i = 0; i < cs.size(); i++) {
			System.out.println(cs.get(i).getName()+":"+cs.get(i).getValue());
		}
	}
	
	static void clearCookies() {
		System.out.println("清空cookie信息");
		cookieStore.clear();
	}
	
	static void putStation2Map(String result, HashMap<String, String> cityMap) {
		int startIdx = result.indexOf("'");
		int endIdx = result.length();
		String city = result.substring(startIdx, endIdx);
		String[] c = city.split("@");
		for(int i = 1; i < c.length; i++) {
			String[] cc = c[i].split("\\|");
			cityMap.put(cc[1], cc[2]);
		}
	}
	
	static String getKeyFromMap(HashMap<String, String> map, String value) {
		for(String getKey: map.keySet()) {
			if(map.get(getKey).equals(value)) {
				return getKey;
			}
		}
		return "";
	}
	
	static void setTableColumnWidth(Vector<String> tableHeaders, JTable table) {
		table.getColumn(tableHeaders.get(1)).setPreferredWidth(55);
		table.getColumn(tableHeaders.get(2)).setPreferredWidth(55);
		table.getColumn(tableHeaders.get(7)).setPreferredWidth(55);
		table.getColumn(tableHeaders.get(8)).setPreferredWidth(55);
		table.getColumn(tableHeaders.get(9)).setPreferredWidth(60);
		table.getColumn(tableHeaders.get(10)).setPreferredWidth(45);
		table.getColumn(tableHeaders.get(11)).setPreferredWidth(45);
		table.getColumn(tableHeaders.get(12)).setPreferredWidth(45);
		table.getColumn(tableHeaders.get(13)).setPreferredWidth(45);
		table.getColumn(tableHeaders.get(14)).setPreferredWidth(45);
		table.getColumn(tableHeaders.get(15)).setPreferredWidth(45);
		table.getColumn(tableHeaders.get(16)).setPreferredWidth(45);
	}
	
	static void setBackgoundColorForTable(JTable table) {
		DefaultTableCellRenderer tcr = new DefaultTableCellRenderer() {
			private static final long serialVersionUID = 1L;
			@Override
			public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
					boolean hasFocus, int row, int column) {
				//return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
				JButton button;
				JPanel panel;
				Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
				if (row % 2 == 0) {
					setBackground(Color.white); //设置奇数行底色
				}
				else if (row % 2 == 1) {
					setBackground(new Color(238,241,248)); //设置偶数行底色
				}
				//设置'有'和'无'的颜色
				if (value != null && column >= 6 && column <= 16) {
					if("--".equals(value.toString()) || "无".equals(value.toString())) {
						setForeground(new Color(153,153,153));
					}else if("有".equals(value.toString())) {
						setForeground(new Color(38,163,6));
					}else { //数字
						setForeground(Color.black);
					}
				}else {
					setForeground(Color.black);
				}
				
				//添加预定按钮
				if (column == 17) {
					Object obj6 = table.getModel().getValueAt(row, 6);
					Object obj7 = table.getModel().getValueAt(row, 7);
					Object obj8 = table.getModel().getValueAt(row, 8);
					Object obj9 = table.getModel().getValueAt(row, 9);
					Object obj10 = table.getModel().getValueAt(row, 10);
					Object obj11 = table.getModel().getValueAt(row, 11);
					Object obj12 = table.getModel().getValueAt(row, 12);
					Object obj13 = table.getModel().getValueAt(row, 13);
					Object obj14 = table.getModel().getValueAt(row, 14);
					Object obj15 = table.getModel().getValueAt(row, 15);
					
					if ( (obj6 != null) && (!"--".equals(obj6.toString())) && (!"无".equals(obj6.toString())) && 
							(("有".equals(obj6.toString())) || (Integer.parseInt(obj6.toString()) > 0)) || 
						 (obj7 != null) && (!"--".equals(obj7.toString())) && (!"无".equals(obj7.toString())) && 
							(("有".equals(obj7.toString())) || (Integer.parseInt(obj7.toString()) > 0)) || 
						 (obj8 != null) && (!"--".equals(obj8.toString())) && (!"无".equals(obj8.toString())) && 
							(("有".equals(obj8.toString())) || (Integer.parseInt(obj8.toString()) > 0)) || 
						 (obj9 != null) && (!"--".equals(obj9.toString())) && (!"无".equals(obj9.toString())) && 
							(("有".equals(obj9.toString())) || (Integer.parseInt(obj9.toString()) > 0)) ||
						 (obj10 != null) && (!"--".equals(obj10.toString())) && (!"无".equals(obj10.toString())) && 
							(("有".equals(obj10.toString())) || (Integer.parseInt(obj10.toString()) > 0)) || 
						 (obj11 != null) && (!"--".equals(obj11.toString())) && (!"无".equals(obj11.toString())) && 
							(("有".equals(obj11.toString())) || (Integer.parseInt(obj11.toString()) > 0)) || 
						 (obj12 != null) && (!"--".equals(obj12.toString())) && (!"无".equals(obj12.toString())) && 
							(("有".equals(obj12.toString())) || (Integer.parseInt(obj12.toString()) > 0)) || 
						 (obj13 != null) && (!"--".equals(obj13.toString())) && (!"无".equals(obj13.toString())) && 
							(("有".equals(obj13.toString())) || (Integer.parseInt(obj13.toString()) > 0)) || 
						 (obj14 != null) && (!"--".equals(obj14.toString())) && (!"无".equals(obj14.toString())) && 
							(("有".equals(obj14.toString())) || (Integer.parseInt(obj14.toString()) > 0)) || 
						 (obj15 != null) && (!"--".equals(obj15.toString())) && (!"无".equals(obj15.toString())) && 
							(("有".equals(obj15.toString())) || (Integer.parseInt(obj15.toString()) > 0)) ){
						panel = new JPanel();
						button = new JButton();
						button.setText("预定");
						button.setForeground(Color.white);
						button.setBackground(new Color(0,119,255));
						panel.add(button, SwingConstants.CENTER);
						return panel;
					}else {
						setForeground(new Color(153,153,153));
						setValue("预定");
					}
				}
				
				return cell;
			}
		};
		tcr.setHorizontalAlignment(SwingConstants.CENTER);
		table.setDefaultRenderer(Object.class, tcr);
	}
}

package my12307;

import java.awt.event.MouseEvent;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;

public class YzmUtils {
	
	private static String signImage = "src//sign.png";
	public static int yzm1 = 0;
	public static int yzm2 = 0;
	public static int yzm3 = 0;
	public static int yzm4 = 0;
	public static int yzm5 = 0;
	public static int yzm6 = 0;
	public static int yzm7 = 0;
	public static int yzm8 = 0;
	private final static int YZM_1 = 1;
	private final static int YZM_2 = 2;
	private final static int YZM_3 = 3;
	private final static int YZM_4 = 4;
	private final static int YZM_5 = 5;
	private final static int YZM_6 = 6;
	private final static int YZM_7 = 7;
	private final static int YZM_8 = 8;
	private static JPanel yzmPanel1;
	private static JPanel yzmPanel2;
	private static JPanel yzmPanel3;
	private static JPanel yzmPanel4;
	private static JPanel yzmPanel5;
	private static JPanel yzmPanel6;
	private static JPanel yzmPanel7;
	private static JPanel yzmPanel8;
	private static String yzm1Point = "35,72,";
	private static String yzm2Point = "111,72,";
	private static String yzm3Point = "181,72,";
	private static String yzm4Point = "250,72,";
	private static String yzm5Point = "35,148,";
	private static String yzm6Point = "111,148,";
	private static String yzm7Point = "181,148,";
	private static String yzm8Point = "250,148,";
	
	@SuppressWarnings("deprecation")
	static void initYzm(JLayeredPane layeredPane){
		yzmPanel1 = initSignImage(24, 55);
		yzmPanel2 = initSignImage(94, 55);
		yzmPanel3 = initSignImage(164, 55);
		yzmPanel4 = initSignImage(240, 55);
		yzmPanel5 = initSignImage(24, 130);
		yzmPanel6 = initSignImage(94, 130);
		yzmPanel7 = initSignImage(164, 130);
		yzmPanel8 = initSignImage(240, 130);
		
		layeredPane.add(yzmPanel1, new Integer(1));
		layeredPane.add(yzmPanel2, new Integer(1));
		layeredPane.add(yzmPanel3, new Integer(1));
		layeredPane.add(yzmPanel4, new Integer(1));
		layeredPane.add(yzmPanel5, new Integer(1));
		layeredPane.add(yzmPanel6, new Integer(1));
		layeredPane.add(yzmPanel7, new Integer(1));
		layeredPane.add(yzmPanel8, new Integer(1));
		yzmPanel1.setVisible(false);//表示验证码没有选中
		yzmPanel2.setVisible(false);
		yzmPanel3.setVisible(false);
		yzmPanel4.setVisible(false);
		yzmPanel5.setVisible(false);
		yzmPanel6.setVisible(false);
		yzmPanel7.setVisible(false);
		yzmPanel8.setVisible(false);
	}
	
	static JPanel initSignImage(int x, int y) {
		JPanel panel = new JPanel();
		JLabel signLabel = new JLabel();
		Icon signIcon = new ImageIcon(signImage);
		signLabel.setIcon(signIcon);
		
		panel.setOpaque(false);
		panel.add(signLabel);
		panel.setBounds(x, y, signIcon.getIconWidth(), signIcon.getIconHeight());
		return panel;
	}
	
	static void setYzmIndexVisiable(JPanel panel, int yzm) {
		if(yzm%2 == 0) {  //表示验证码没有选中
			panel.setVisible(true);
		} else {
			panel.setVisible(false);
		}
	}
	
	static void setYzmsVisiable(int index) {
		switch (index) {
		case YZM_1:
			setYzmIndexVisiable(yzmPanel1, yzm1);
			yzm1++;
			break;
		case YZM_2:
			setYzmIndexVisiable(yzmPanel2, yzm2);
			yzm2++;
			break;
		case YZM_3:
			setYzmIndexVisiable(yzmPanel3, yzm3);
			yzm3++;
			break;
		case YZM_4:
			setYzmIndexVisiable(yzmPanel4, yzm4);
			yzm4++;
			break;
		case YZM_5:
			setYzmIndexVisiable(yzmPanel5, yzm5);
			yzm5++;
			break;
		case YZM_6:
			setYzmIndexVisiable(yzmPanel6, yzm6);
			yzm6++;
			break;
		case YZM_7:
			setYzmIndexVisiable(yzmPanel7, yzm7);
			yzm7++;
			break;
		case YZM_8:
			setYzmIndexVisiable(yzmPanel8, yzm8);
			yzm8++;
			break;
		default:
			break;
		}
	}
	
	static String getYzmAnswer() {
		StringBuffer yzmAnswer = new StringBuffer();
		
		if (yzm1%2 == 1) { //该验证码被选中
			yzmAnswer.append(yzm1Point);
		}
		if (yzm2%2 == 1) { //该验证码被选中
			yzmAnswer.append(yzm2Point);
		}
		if (yzm3%2 == 1) { //该验证码被选中
			yzmAnswer.append(yzm3Point);
		}
		if (yzm4%2 == 1) { //该验证码被选中
			yzmAnswer.append(yzm4Point);
		}
		if (yzm5%2 == 1) { //该验证码被选中
			yzmAnswer.append(yzm5Point);
		}
		if (yzm6%2 == 1) { //该验证码被选中
			yzmAnswer.append(yzm6Point);
		}
		if (yzm7%2 == 1) { //该验证码被选中
			yzmAnswer.append(yzm7Point);
		}
		if (yzm8%2 == 1) { //该验证码被选中
			yzmAnswer.append(yzm8Point);
		}
		
		if (yzmAnswer.length() == 0) {
			System.out.println("请选择验证码");
			return "";
		}
		
		return (yzmAnswer.deleteCharAt(yzmAnswer.length() - 1)).toString();
	}
	
	static void addSign2Yzm(MouseEvent e) {
		//(5,41)  第一张验证码座标
		int top = 41;
		int gap = 5;
		int xUnit = 67;  //每一个小图宽
		int yUnit = 67;  //每一个小图宽
		int xPoint = e.getX();
		int yPoint = e.getY();
		if(gap <= xPoint && xPoint < (gap + xUnit)) {
			if ((gap + top) <= yPoint && yPoint < (gap + yUnit + top)) {
				setYzmsVisiable(YZM_1);
			}else if ((gap + yUnit + top) <= yPoint && yPoint < (2*(gap + yUnit) + top)){
				setYzmsVisiable(YZM_5);
			}
		}else if((gap + xUnit) <= xPoint && xPoint < (2*(gap + xUnit))) {
			if ((gap + top) <= yPoint && yPoint < (gap + yUnit + top)) {
				setYzmsVisiable(YZM_2);
			}else if ((gap + yUnit + top) <= yPoint && yPoint < (2*(gap + yUnit) + top)){
				setYzmsVisiable(YZM_6);
			}
		}else if((2*(gap + xUnit)) <= xPoint && xPoint < (3*(gap + xUnit))) {
			if ((gap + top) <= yPoint && yPoint < (gap + yUnit + top)) {
				setYzmsVisiable(YZM_3);
			}else if ((gap + yUnit + top) <= yPoint && yPoint < (2*(gap + yUnit) + top)){
				setYzmsVisiable(YZM_7);
			}
		}else if((3*(gap + xUnit)) <= xPoint && xPoint < (4*(gap + xUnit))){
			if ((gap + top) <= yPoint && yPoint < (gap + yUnit + top)) {
				setYzmsVisiable(YZM_4);
			}else if ((gap + yUnit + top) <= yPoint && yPoint < (2*(gap + yUnit) + top)){
				setYzmsVisiable(YZM_8);
			}
		}
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章