之前一直打算写一个模拟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”+
“×tamp=”+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,该页面显示“网络可能存在问题,请您重试一下!”。重点关注请求中的algID和hashCode两个参数,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可能会有变动)
关于验证码坐标的说明:
查票模块目前不添加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 ccName;
private Vector tableHeaders;
private HashMap cityMap;
private Vector> 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();
cityMap = new HashMap();
gDatas = new Vector>();
tableHeaders = new Vector();
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 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> datas = new Vector>();
datas = (Vector>) 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> ckData = new Vector>();
for(Vector 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>) 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 row = new Vector();
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 formPair = new ArrayList();
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 formPair = new ArrayList();
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 formPair = new ArrayList();
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 formPair = new ArrayList();
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"+
"×tamp="+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 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 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 map, String value) {
for(String getKey: map.keySet()) {
if(map.get(getKey).equals(value)) {
return getKey;
}
}
return "";
}
static void setTableColumnWidth(Vector 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);
}
}
}
}