├── DefaultText.java ├── Gui.java ├── Http.java ├── Main.java ├── README.md ├── Re.java ├── TxtFile.java └── pom.xml /DefaultText.java: -------------------------------------------------------------------------------- 1 | package com.webRequest; 2 | 3 | import javax.swing.*; 4 | import java.awt.*; 5 | import java.awt.event.FocusEvent; 6 | import java.awt.event.FocusListener; 7 | 8 | // 默认显示文本 9 | public class DefaultText implements FocusListener { 10 | private String defaultText; 11 | private JTextField defaultField; 12 | 13 | public DefaultText(String Text, JTextField textField){ 14 | this.defaultText = Text; 15 | this.defaultField = textField; 16 | textField.setText(Text); 17 | textField.setForeground(Color.GRAY); 18 | } 19 | 20 | @Override 21 | public void focusGained(FocusEvent e) { 22 | String temp = defaultField.getText(); 23 | if (temp.equals(defaultText)){ 24 | defaultField.setText(""); 25 | defaultField.setForeground(Color.BLACK); 26 | } 27 | } 28 | 29 | @Override 30 | public void focusLost(FocusEvent e) { 31 | String temp = defaultField.getText(); 32 | if (temp.equals("")){ 33 | defaultField.setForeground(Color.GRAY); 34 | defaultField.setText(defaultText); 35 | } 36 | } 37 | } 38 | 39 | class DefaultTextarea implements FocusListener{ 40 | private String defaultText; 41 | private JTextArea defaultTextarea; 42 | 43 | public DefaultTextarea(String Text, JTextArea TextArea){ 44 | this.defaultText = Text; 45 | this.defaultTextarea = TextArea; 46 | defaultTextarea.setText(Text); 47 | defaultTextarea.setForeground(Color.GRAY); 48 | } 49 | 50 | @Override 51 | public void focusGained(FocusEvent e) { 52 | String temp = defaultTextarea.getText(); 53 | if (temp.equals(defaultText)){ 54 | defaultTextarea.setText(""); 55 | defaultTextarea.setForeground(Color.BLACK); 56 | } 57 | } 58 | 59 | @Override 60 | public void focusLost(FocusEvent e) { 61 | String temp = defaultTextarea.getText(); 62 | if (temp.equals("")){ 63 | defaultTextarea.setForeground(Color.GRAY); 64 | defaultTextarea.setText(defaultText); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Gui.java: -------------------------------------------------------------------------------- 1 | package com.webRequest; 2 | 3 | import javax.swing.*; 4 | import javax.swing.filechooser.FileNameExtensionFilter; 5 | import javax.swing.table.DefaultTableModel; 6 | import javax.swing.table.TableColumn; 7 | import javax.swing.table.TableModel; 8 | import java.awt.*; 9 | import java.awt.FlowLayout; 10 | import java.awt.datatransfer.Clipboard; 11 | import java.awt.datatransfer.StringSelection; 12 | import java.awt.event.*; 13 | import java.io.*; 14 | import java.util.*; 15 | import java.util.List; 16 | import java.util.concurrent.ExecutionException; 17 | import java.util.concurrent.ExecutorService; 18 | import java.util.concurrent.Executors; 19 | 20 | public class Gui extends JFrame { 21 | private JTextField uaText,dataText, targetsPathText; 22 | private JMenuBar fileMenu,helpMenu,proxyMenu; 23 | private JMenuItem importTargetsMenuItem,exportMenuItem,aboutMenuItem,httpMenuItem; 24 | private JPanel topPanel, westPanel, eastPanel; 25 | private JLabel targetsLabel, pathLabel,cookiesLabel,uaLabel,dataLabel,headLabel,countLabel; 26 | private JButton runButton,stopButton,clearButton; 27 | private JComboBox threadBox,enctypeBox; 28 | private JTextArea targetsTextArea,headTextArea,cookiesTextArea; 29 | private JScrollPane targetsScroll,tableScroll; 30 | private JTable table; 31 | private Vector columnNames; 32 | private DefaultTableModel dataModel; 33 | private ButtonGroup requestsButtonGroup; 34 | private JRadioButton getRadio,postRadio,headRadio; 35 | private JCheckBox followBox; 36 | private ExecutorService pool; 37 | private int total,doneCount; 38 | private JPopupMenu rightMenu; 39 | private String targetUrl,host,portString; 40 | private int port; 41 | private boolean proxyPower; 42 | private JMenu file,help,proxy; 43 | private HashMap bodyData; 44 | 45 | public Gui() 46 | { 47 | JFrame.setDefaultLookAndFeelDecorated(true); 48 | this.setTitle("WEB批量请求器"); //设置显示窗口标题 49 | this.setBounds(400,300,1210,720); 50 | // 屏幕中央 51 | setLocationRelativeTo(null); 52 | 53 | 54 | // 头部面板内容 55 | fileMenu = new JMenuBar(); 56 | file = fileMenu.add(new JMenu("文件")); 57 | importTargetsMenuItem = new JMenuItem("导入目标"); 58 | exportMenuItem = new JMenuItem("导出结果"); 59 | file.add(importTargetsMenuItem); 60 | file.add(exportMenuItem); 61 | helpMenu=new JMenuBar(); 62 | 63 | help = helpMenu.add(new JMenu("帮助")); 64 | aboutMenuItem = new JMenuItem("关于"); 65 | help.add(aboutMenuItem); 66 | 67 | proxyMenu=new JMenuBar(); 68 | proxy = proxyMenu.add(new JMenu("代理设置")); 69 | httpMenuItem = new JMenuItem("添加HTTP代理"); 70 | proxy.add(httpMenuItem); 71 | 72 | // 头部面板 73 | topPanel = new JPanel(); 74 | topPanel.add(fileMenu); 75 | topPanel.add(proxyMenu); 76 | topPanel.add(helpMenu); 77 | topPanel.setLayout(new FlowLayout(FlowLayout.LEFT)); 78 | 79 | 80 | 81 | // 左部面板(西) 82 | westPanel = new JPanel(); 83 | // GridBagLayout gridBagLayout=new GridBagLayout(); 84 | // GridBagConstraints gridBagConstraints=new GridBagConstraints(); 85 | // gridBagConstraints.fill=GridBagConstraints.BOTH; 86 | // 流式布局 87 | westPanel.setLayout(new FlowLayout(FlowLayout.LEFT,5,5)); 88 | 89 | // 左部面板组件 90 | targetsLabel = new JLabel("targets: "); 91 | pathLabel = new JLabel("/"); 92 | headLabel = new JLabel("自定义Header:"); 93 | cookiesLabel = new JLabel("自定义Cookies:"); 94 | uaLabel = new JLabel("自定义User-Agent:"); 95 | 96 | runButton = new JButton("Run"); 97 | runButton.setEnabled(true); 98 | runButton.setBorderPainted(true); 99 | 100 | stopButton = new JButton("Stop"); 101 | stopButton.setEnabled(true); 102 | stopButton.setBorderPainted(true); 103 | 104 | clearButton = new JButton("Clear"); 105 | clearButton.setEnabled(true); 106 | clearButton.setBorderPainted(true); 107 | 108 | countLabel = new JLabel("0/5"); 109 | 110 | threadBox = new JComboBox(); 111 | threadBox.addItem("--请选择线程--"); 112 | threadBox.addItem("1"); 113 | threadBox.addItem("5"); 114 | threadBox.addItem("25"); 115 | threadBox.addItem("50"); 116 | threadBox.addItem("75"); 117 | threadBox.addItem("100"); 118 | targetsTextArea = new JTextArea(8,40); 119 | targetsTextArea.addFocusListener(new DefaultTextarea("https://www.baidu.com\nhttps://www.qq.com\nhttps://www.sina.com.cn/\nhttp://weather.sina.com.cn\nhttps://www.nday.top\n",targetsTextArea)); 120 | targetsScroll = new JScrollPane(targetsTextArea); 121 | 122 | targetsPathText = new JTextField(9); 123 | targetsPathText.addFocusListener(new DefaultText("默认为空", targetsPathText)); 124 | 125 | headTextArea = new JTextArea(2,51); 126 | headTextArea.addFocusListener(new DefaultTextarea("X-Forwarded-for: 127.0.0.1\nReferer: ...",headTextArea)); 127 | 128 | cookiesTextArea = new JTextArea(2,51); 129 | cookiesTextArea.addFocusListener(new DefaultTextarea("SESSION=A202106084F2...",cookiesTextArea)); 130 | 131 | uaText = new JTextField("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36(KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36",51); 132 | //自动换行 133 | targetsTextArea.setLineWrap(true); 134 | cookiesTextArea.setLineWrap(true); 135 | headTextArea.setLineWrap(true); 136 | 137 | requestsButtonGroup = new ButtonGroup(); 138 | getRadio = new JRadioButton("get", true); 139 | postRadio = new JRadioButton("post"); 140 | headRadio = new JRadioButton("head"); 141 | requestsButtonGroup.add(getRadio); 142 | requestsButtonGroup.add(postRadio); 143 | requestsButtonGroup.add(headRadio); 144 | 145 | followBox = new JCheckBox("是否跟随302跳转"); 146 | 147 | dataLabel=new JLabel("post_data:"); 148 | dataText = new JTextField("",51); 149 | 150 | dataText.setEditable(false); 151 | 152 | enctypeBox = new JComboBox(); 153 | enctypeBox.addItem("application/x-www-form-urlencoded"); 154 | enctypeBox.addItem("application/json"); 155 | enctypeBox.addItem("multipart/form-data"); 156 | enctypeBox.setEnabled (false); 157 | 158 | // 填充换行保持布局 159 | // JButton padding=new JButton(" " 160 | // +" "+" "); 161 | // padding.setContentAreaFilled(false); 162 | // padding.setBorderPainted(false); 163 | // padding.setEnabled(false); 164 | // 组件添加到左部面板中 165 | westPanel.add(targetsLabel); 166 | westPanel.add(targetsScroll); 167 | westPanel.add(pathLabel); 168 | westPanel.add(targetsPathText); 169 | 170 | westPanel.add(headLabel); 171 | westPanel.add(headTextArea); 172 | 173 | westPanel.add(cookiesLabel); 174 | westPanel.add(cookiesTextArea); 175 | 176 | westPanel.add(uaLabel); 177 | westPanel.add(uaText); 178 | westPanel.add(dataLabel); 179 | westPanel.add(dataText); 180 | 181 | westPanel.add(enctypeBox); 182 | 183 | westPanel.add(getRadio); 184 | westPanel.add(postRadio); 185 | westPanel.add(headRadio); 186 | 187 | westPanel.add(followBox); 188 | 189 | westPanel.add(threadBox); 190 | westPanel.add(runButton); 191 | westPanel.add(stopButton); 192 | westPanel.add(clearButton); 193 | westPanel.add(countLabel); 194 | 195 | // 右部面板(东) 196 | eastPanel = new JPanel(); 197 | eastPanel.setLayout(new BorderLayout(0, 0)); 198 | 199 | // 表头(列名) 200 | columnNames = new Vector(); 201 | columnNames.add("target"); 202 | columnNames.add("status"); 203 | columnNames.add("title"); 204 | columnNames.add("banner"); 205 | columnNames.add("contentLength"); 206 | // 创建表格模型 207 | dataModel = new DefaultTableModel(columnNames, 0); 208 | // 创建JTable表格组件 209 | table = new JTable(dataModel); 210 | // JTable内容居中 211 | // DefaultTableCellRenderer cr = new DefaultTableCellRenderer(); 212 | // cr.setHorizontalAlignment(JLabel.CENTER); 213 | // table.setDefaultRenderer(Object.class, cr); 214 | // table.setRowHeight(30); 215 | // 设置列表可排序 216 | table.setAutoCreateRowSorter(true); 217 | // 设置target列的宽度 218 | TableColumn targetsColumn = table.getColumnModel().getColumn(0); 219 | targetsColumn.setPreferredWidth(130); 220 | 221 | // 创建带滚动条的面板,并将表格添加到带滚动条的面板中 222 | tableScroll = new JScrollPane(table); 223 | // 将表头添加到面板中(布局的上方) 224 | eastPanel.add(table.getTableHeader(), BorderLayout.NORTH); 225 | // 将带滚动条的面板添加到布局中(布局的中间) 226 | eastPanel.add(tableScroll, BorderLayout.CENTER); 227 | 228 | // 添加到JFrame 229 | getContentPane().add(topPanel, BorderLayout.NORTH); 230 | getContentPane().add(westPanel,BorderLayout.WEST); 231 | getContentPane().add(eastPanel, BorderLayout.EAST); 232 | //设置区域面板大小 233 | westPanel.setPreferredSize(new Dimension(588,510)); 234 | eastPanel.setPreferredSize(new Dimension(600,510)); 235 | 236 | //窗口显示 237 | setVisible(true); 238 | // 用户是否可随意改窗口大小 239 | // setResizable(false); 240 | // 点击x直接结束当前程序 241 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 242 | 243 | 244 | // ---------------------事件处理--------------------------- 245 | 246 | // 单选框get/post事件 247 | ActionListener requests_Listener = new ActionListener() { 248 | public void actionPerformed(ActionEvent e) { 249 | switch (e.getActionCommand()){ 250 | case "post": 251 | dataText.setEditable(true); 252 | enctypeBox.setEnabled (true); 253 | break; 254 | default: 255 | dataText.setEditable(false); 256 | enctypeBox.setEnabled (false); 257 | dataText.setText(""); 258 | break; 259 | } 260 | } 261 | }; 262 | getRadio.addActionListener(requests_Listener); 263 | postRadio.addActionListener(requests_Listener); 264 | headRadio.addActionListener(requests_Listener); 265 | 266 | 267 | // run按钮点击事件 268 | runButton.addActionListener(new ActionListener() { 269 | public void actionPerformed(ActionEvent e) { 270 | //点击后不可点击 271 | runButton.setEnabled(false); 272 | // 预览body的Map集合 273 | bodyData = new HashMap(); 274 | 275 | // 获取输入值 276 | String targetsBody = targetsTextArea.getText(); 277 | String cookiesBody = cookiesTextArea.getText(); 278 | String uaBody = uaText.getText(); 279 | String[] str = targetsBody.split("\n"); 280 | String headBody = headTextArea.getText(); 281 | String targetsPathBody = targetsPathText.getText(); 282 | // String targetsBody3 = targetsBody2 == "默认为空" ? "":targetsBody2; 283 | // System.out.println(targetsBody3); 284 | 285 | // 数据处理 看用户是否输入的只是域名 286 | ArrayList str2 = new ArrayList<>(); 287 | // for (String target : str) { 288 | // if (target.startsWith("http://") || target.startsWith("https://")) 289 | // { if (targetsPathBody.equals("默认为空")){ 290 | // str2.add(target); 291 | // }else { 292 | // str2.add(target+"/"+targetsPathBody); 293 | // } 294 | // }else { 295 | // if (targetsPathBody.equals("默认为空")){ 296 | // str2.add("https://"+target); 297 | // str2.add("http://"+target); 298 | // } else { 299 | // str2.add("https://"+target+"/"+targetsPathBody); 300 | // str2.add("http://"+target+"/"+targetsPathBody); 301 | // } 302 | // } 303 | // } 304 | if (targetsPathBody.equals("默认为空")){ 305 | for (String target : str) { 306 | if (target.startsWith("http://") || target.startsWith("https://")) 307 | { 308 | str2.add(target); 309 | } 310 | else { 311 | str2.add("https://"+target); 312 | str2.add("http://"+target); 313 | } 314 | } 315 | }else { 316 | for (String target : str) { 317 | if (target.startsWith("http://") || target.startsWith("https://")) 318 | { 319 | str2.add(target+"/"+targetsPathBody); 320 | } 321 | else { 322 | str2.add("https://"+target+"/"+targetsPathBody); 323 | str2.add("http://"+target+"/"+targetsPathBody); 324 | } 325 | } } 326 | // 多少个目标 327 | total = str2.size(); 328 | 329 | // 判断用什么方式请求 330 | if (postRadio.isSelected()){ 331 | String dataBody = dataText.getText(); 332 | Object enctypeBody = enctypeBox.getSelectedItem(); 333 | httpData(str2,cookiesBody,uaBody,headBody,"post",dataBody,enctypeBody.toString()); 334 | } 335 | if (headRadio.isSelected()){ 336 | httpData(str2,cookiesBody,uaBody,headBody,"head",null,null); 337 | } 338 | if (getRadio.isSelected()){ 339 | httpData(str2,cookiesBody,uaBody,headBody,"get",null,null); 340 | } 341 | 342 | //重置完成数以列表内容 343 | doneCount = 0; 344 | dataModel.setRowCount(0); 345 | } 346 | }); 347 | 348 | // stop 按钮事件 349 | stopButton.addActionListener(new ActionListener() { 350 | @Override 351 | public void actionPerformed(ActionEvent e) { 352 | pool.shutdownNow(); 353 | runButton.setEnabled(true); 354 | } 355 | }); 356 | 357 | // clear 按钮事件 358 | clearButton.addActionListener(new ActionListener() { 359 | @Override 360 | public void actionPerformed(ActionEvent e) { 361 | dataModel.setRowCount(0); 362 | countLabel.setText(0+"/"+total); 363 | } 364 | }); 365 | 366 | // 导入文件事件 367 | importTargetsMenuItem.addActionListener(new ActionListener() { 368 | @Override 369 | public void actionPerformed(ActionEvent e) { 370 | JFileChooser fileChooser = new JFileChooser(); 371 | fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); 372 | String ext[] = {"txt"}; 373 | FileNameExtensionFilter extFilter = new FileNameExtensionFilter("txt", ext); 374 | fileChooser.setFileFilter(extFilter); // 设置文件过滤器 375 | fileChooser.showOpenDialog(null); 376 | File selectFile = fileChooser.getSelectedFile(); 377 | if (selectFile != null) { 378 | // 获取文件路径 379 | String filepath = selectFile.getPath().trim(); 380 | // 调用文件读取TextFile 381 | List strings = TxtFile.readTxtFile(filepath); 382 | if (strings != null && !strings.isEmpty()){ 383 | total = strings.size(); 384 | countLabel.setText("0/"+total); 385 | targetsTextArea.setText(""); 386 | for (String string : strings) { 387 | targetsTextArea.append(string+"\n");} 388 | }else { 389 | // 警告框 390 | JOptionPane.showMessageDialog(null, "选择文件有误,请选择txt文件导入", "error",JOptionPane.WARNING_MESSAGE); 391 | // targetsTextArea.setText("#error#选择文件有误,请选择txt文件导入"); 392 | } 393 | } 394 | } 395 | }); 396 | 397 | // 导出结果事件 398 | exportMenuItem.addActionListener(new ActionListener() { 399 | @Override 400 | public void actionPerformed(ActionEvent e) { 401 | JFileChooser fileChooser = new JFileChooser(); 402 | // 设置默认导出文件名 403 | String defaultFileName = "results.csv"; 404 | fileChooser.setDialogTitle("保存文件"); 405 | 406 | fileChooser.setSelectedFile(new File(defaultFileName)); 407 | int saveDialog = fileChooser.showDialog(null, "保存文件"); 408 | 409 | // 判断用户是否点击保存文件 410 | if (saveDialog == fileChooser.APPROVE_OPTION) { 411 | // 获取文件名 412 | String filename = fileChooser.getSelectedFile().toString(); 413 | // 判断文件是否为csv结尾 414 | if (!filename.endsWith(".csv")) { 415 | filename = filename + ".csv"; 416 | } 417 | File file = new File(filename); 418 | // 判断文件是否存在 419 | if (file.exists()) { 420 | int i = JOptionPane.showConfirmDialog(null, "该文件已经存在,确定要覆盖吗?"); 421 | if (i != JOptionPane.YES_OPTION) { 422 | return; 423 | } 424 | } 425 | try { 426 | // 调用exportTable方法写入csv 427 | exportTable(table, file); 428 | } catch (IOException ex) { 429 | // System.out.println(ex.getMessage()); 430 | ex.printStackTrace(); 431 | JOptionPane.showMessageDialog(null, ex.getMessage(), "error",JOptionPane.WARNING_MESSAGE); 432 | } 433 | } 434 | } 435 | }); 436 | 437 | // 关于事件 438 | aboutMenuItem.addActionListener(new about()); 439 | 440 | // 代理设置事件 441 | httpMenuItem.addActionListener(new proxy()); 442 | 443 | // table事件 右键事件 444 | table.addMouseListener(new MouseAdapter() { 445 | public void mousePressed(MouseEvent e) { 446 | 447 | rightMenu = new JPopupMenu(); 448 | // 复制目标地址 449 | JMenuItem copyMenItem = new JMenuItem(); 450 | copyMenItem.setText(" 复制目标地址 "); 451 | //设置快捷键 452 | // copyMenItem.setAccelerator(KeyStroke.getKeyStroke('C', InputEvent.CTRL_MASK)); 453 | copyMenItem.addActionListener(new java.awt.event.ActionListener() { 454 | public void actionPerformed(java.awt.event.ActionEvent evt) { 455 | // 获取系统剪切板 456 | Clipboard clipboard=Toolkit.getDefaultToolkit().getSystemClipboard(); 457 | // 构建String类型 458 | StringSelection selection = new StringSelection(targetUrl); 459 | // 添加文本到系统剪切板 460 | clipboard.setContents(selection,selection); 461 | } 462 | }); 463 | 464 | // 使用默认浏览器打开 465 | JMenuItem browserMenItem = new JMenuItem(); 466 | browserMenItem.setText(" 使用默认浏览器打开 "); 467 | browserMenItem.addActionListener(new java.awt.event.ActionListener() { 468 | public void actionPerformed(java.awt.event.ActionEvent evt) { 469 | //该操作需要做的事 470 | try { 471 | java.net.URI uri = java.net.URI.create(targetUrl); 472 | // 获取当前系统桌面扩展 473 | java.awt.Desktop dp = java.awt.Desktop.getDesktop(); 474 | // 判断系统桌面是否支持要执行的功能 475 | if (dp.isSupported(java.awt.Desktop.Action.BROWSE)) { 476 | dp.browse(uri); 477 | // 获取系统默认浏览器打开链接 478 | } 479 | } catch (java.lang.NullPointerException e1) { 480 | // 此为uri为空时抛出异常 481 | e1.printStackTrace(); 482 | } catch (java.io.IOException e1) { 483 | // 此为无法获取系统默认浏览器 484 | e1.printStackTrace(); 485 | } 486 | } 487 | }); 488 | 489 | // 预览Body 490 | JMenuItem viewMenItem = new JMenuItem(); 491 | viewMenItem.setText(" 预览Body "); 492 | viewMenItem.addActionListener(new java.awt.event.ActionListener() { 493 | public void actionPerformed(java.awt.event.ActionEvent evt) { 494 | // 新建一个frame 495 | JDialog viewBodyFrame = new JDialog(); 496 | viewBodyFrame.setBounds(795,350,500,500); 497 | viewBodyFrame.setLayout(new FlowLayout(FlowLayout.LEFT,10,5)); 498 | // 设置未关闭该窗口无法操作其他窗口 499 | viewBodyFrame.setModalityType(Dialog.ModalityType.APPLICATION_MODAL); 500 | viewBodyFrame.setTitle(targetUrl); 501 | 502 | JTextArea bodyTextArea= new JTextArea(bodyData.get(targetUrl)); 503 | JScrollPane bodyScroll = new JScrollPane(bodyTextArea); 504 | bodyScroll.setPreferredSize(new Dimension(450, 430)); 505 | // 设置一直显示滚动条 506 | bodyScroll.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 507 | 508 | viewBodyFrame.add(bodyScroll); 509 | viewBodyFrame.setVisible(true); 510 | // 511 | // 512 | } 513 | }); 514 | // 添加到右键菜单 515 | rightMenu.add(browserMenItem); 516 | rightMenu.add(copyMenItem); 517 | rightMenu.add(viewMenItem); 518 | 519 | // 右键显示菜单栏 520 | if (e.getButton() == java.awt.event.MouseEvent.BUTTON3) { 521 | //通过点击位置找到点击为表格中的行 522 | int focusedRowIndex = table.rowAtPoint(e.getPoint()); 523 | if (focusedRowIndex == -1) { 524 | return; 525 | } 526 | //将表格所选项设为当前右键点击的行 527 | table.setRowSelectionInterval(focusedRowIndex, focusedRowIndex); 528 | targetUrl = (String) table.getValueAt(focusedRowIndex,0); 529 | //弹出菜单 530 | rightMenu.show(table, e.getX(), e.getY());} 531 | 532 | // 双击默认浏览器打开 533 | if (e.getClickCount() == 2){ 534 | int focusedRowIndex = table.rowAtPoint(e.getPoint()); 535 | if (focusedRowIndex == -1) { 536 | return; 537 | } 538 | table.setRowSelectionInterval(focusedRowIndex, focusedRowIndex); 539 | targetUrl = (String) table.getValueAt(focusedRowIndex,0); 540 | try { 541 | java.net.URI uri = java.net.URI.create(targetUrl); 542 | // 获取当前系统桌面扩展 543 | java.awt.Desktop dp = java.awt.Desktop.getDesktop(); 544 | // 判断系统桌面是否支持要执行的功能 545 | if (dp.isSupported(java.awt.Desktop.Action.BROWSE)) { 546 | dp.browse(uri); 547 | // 获取系统默认浏览器打开链接 548 | } 549 | } catch (java.lang.NullPointerException e1) { 550 | // 此为uri为空时抛出异常 551 | e1.printStackTrace(); 552 | } catch (java.io.IOException e1) { 553 | // 此为无法获取系统默认浏览器 554 | e1.printStackTrace(); 555 | } 556 | } 557 | } 558 | }); 559 | }; 560 | 561 | 562 | 563 | public void httpData(ArrayList str, final String cookiesBody, final String uaBody, final String headBody, final String methods, final String dataBody, final String enctypeBody){ 564 | // 获取线程池数量 565 | if (threadBox.getSelectedItem() == "--请选择线程--"){ 566 | pool = Executors.newFixedThreadPool(1); 567 | }else { 568 | pool = Executors.newFixedThreadPool(Integer.valueOf(threadBox.getSelectedItem().toString())); 569 | } 570 | // 是否跟随302跳转 571 | final boolean follow = followBox.isSelected(); 572 | 573 | for (String s : str) { 574 | final String target = s; 575 | // SwingWorker线程 576 | SwingWorker worker = new SwingWorker() { 577 | @Override 578 | protected Vector doInBackground() throws Exception { 579 | Vector list = new Vector<>(); 580 | ArrayList responseData = new ArrayList(); 581 | // System.out.println(responseData); 582 | String responseTitle; 583 | try { 584 | // if (target.startsWith("http://") || target.startsWith("https://")) { 585 | if (proxyPower == false){ 586 | responseData = Http.Response(target, cookiesBody, uaBody, headBody, methods, dataBody, enctypeBody,follow); 587 | }else { 588 | System.out.println(host); 589 | System.out.println(port); 590 | responseData = Http.Response(target, cookiesBody, uaBody, headBody, methods, dataBody, enctypeBody,follow,host,port); 591 | } 592 | responseTitle = Re.Title(responseData.get(1)); 593 | list.addElement(target); 594 | list.addElement(responseData.get(0)); 595 | list.addElement(responseTitle); 596 | list.addElement(responseData.get(2)); 597 | list.addElement(responseData.get(3)); 598 | // list.addElement(responseData.get(1)); 599 | 600 | bodyData.put(target,responseData.get(1)); 601 | if (responseData == null) { 602 | synchronized (this) { 603 | System.out.println("异常"); 604 | total +=1; 605 | } 606 | } 607 | 608 | System.out.println("[1]" + Thread.currentThread().getName()); 609 | } catch (Exception e) { 610 | e.printStackTrace(); 611 | list.addElement(target); 612 | // list.addElement("无法访问"); 613 | list.addElement(""+"无法访问"+""); 614 | list.addElement(e.getMessage()); 615 | bodyData.put(target,""); 616 | } 617 | return list; 618 | } 619 | 620 | @Override 621 | protected void done() { 622 | Vector list = new Vector<>(); 623 | try { 624 | list = get(); 625 | } catch (InterruptedException e) { 626 | e.printStackTrace(); 627 | } catch (ExecutionException e) { 628 | e.printStackTrace(); 629 | } 630 | dataModel.addRow(list); 631 | doneCount += 1; 632 | countLabel.setText(doneCount + "/" + total); 633 | if (doneCount == total){ 634 | // 完成时开启run按钮 635 | runButton.setEnabled(true); 636 | } 637 | } 638 | }; 639 | //线程执行 640 | pool.execute(worker); 641 | 642 | } 643 | } 644 | 645 | public void exportTable(JTable table, File file) throws IOException { 646 | TableModel model = table.getModel(); 647 | BufferedWriter bWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),"GBK")); 648 | for(int i=0; i < model.getColumnCount(); i++) { 649 | bWriter.write(model.getColumnName(i)); 650 | bWriter.write(","); 651 | } 652 | bWriter.newLine(); 653 | for(int i=0; i< model.getRowCount(); i++) { 654 | for(int j=0; j < model.getColumnCount(); j++) { 655 | //解决Java导出csv文件数据中包含逗号导致乱行的问题 656 | System.out.println(model.getValueAt(i,j)); 657 | String value; 658 | if (model.getValueAt(i,j) != null){ 659 | value = model.getValueAt(i,j).toString(); 660 | }else{ 661 | value = ""; 662 | } 663 | if (value.contains(",")){ 664 | value = "\""+value+"\""; 665 | } 666 | bWriter.write(value); 667 | bWriter.write(","); 668 | } 669 | bWriter.newLine(); 670 | } 671 | bWriter.close(); 672 | System.out.println("write out to: " + file); 673 | } 674 | 675 | // 关于事件 676 | class about implements ActionListener{ 677 | @Override 678 | public void actionPerformed(ActionEvent e){ 679 | JOptionPane.showMessageDialog(null, "WEB批量请求器 \nVersion 1.3\nAuthor:@xiaowei\nGithub: https://github.com/ScriptKid-Beta/WebBatchRequest\nCopyright 2021", "关于",JOptionPane.WARNING_MESSAGE);//弹框提示 680 | } 681 | } 682 | 683 | class proxy implements ActionListener{ 684 | public void actionPerformed(ActionEvent e){ 685 | final JDialog proxyFrame = new JDialog(); 686 | proxyFrame.setBounds(795,350,335,118); 687 | proxyFrame.setLayout(new FlowLayout(FlowLayout.LEFT,10,5)); 688 | proxyFrame.setModalityType(Dialog.ModalityType.APPLICATION_MODAL); 689 | 690 | proxyFrame.setTitle("代理设置"); 691 | 692 | final JLabel hostJLabel = new JLabel(); 693 | hostJLabel.setText("地址:"); 694 | final JTextField hostJText = new JTextField(11); 695 | 696 | JLabel portJLabel = new JLabel(); 697 | portJLabel.setText("端口:"); 698 | final JTextField portJText = new JTextField(5); 699 | 700 | final JButton defineJButton = new JButton("确定"); 701 | JButton cancelJButton = new JButton("取消"); 702 | 703 | proxyFrame.add(hostJLabel); 704 | proxyFrame.add(hostJText); 705 | 706 | proxyFrame.add(portJLabel); 707 | proxyFrame.add(portJText); 708 | 709 | proxyFrame.add(defineJButton); 710 | proxyFrame.add(cancelJButton); 711 | // 确认按钮事件 712 | defineJButton.addActionListener(new ActionListener() { 713 | @Override 714 | public void actionPerformed(ActionEvent e) { 715 | host = hostJText.getText(); 716 | portString = portJText.getText(); 717 | 718 | if (!"".equals(host) && "".equals(portString)){ 719 | JOptionPane.showMessageDialog(defineJButton, "端口不能为空", "error",JOptionPane.WARNING_MESSAGE); 720 | } 721 | if (!"".equals(portString) && "".equals(host)){ 722 | JOptionPane.showMessageDialog(defineJButton, "代理服务器不能为空", "error",JOptionPane.WARNING_MESSAGE); 723 | } 724 | if ("".equals(host) && "".equals(portString)){ 725 | proxyPower = false; 726 | proxyFrame.dispose(); 727 | } 728 | if (!"".equals(host) && !"".equals(portString)){ 729 | proxyPower = true; 730 | port = Integer.valueOf(portString); 731 | proxyFrame.dispose();} 732 | 733 | } 734 | }); 735 | hostJText.setText(host); 736 | portJText.setText(portString); 737 | 738 | // 取消按钮事件 739 | cancelJButton.addActionListener(new ActionListener() { 740 | @Override 741 | public void actionPerformed(ActionEvent e) { 742 | proxyFrame.dispose(); 743 | } 744 | }); 745 | proxyFrame.setVisible(true); 746 | } 747 | 748 | } 749 | 750 | 751 | } 752 | 753 | -------------------------------------------------------------------------------- /Http.java: -------------------------------------------------------------------------------- 1 | package com.webRequest; 2 | 3 | import com.github.kevinsawicki.http.HttpRequest; 4 | 5 | import java.io.UnsupportedEncodingException; 6 | import java.util.ArrayList; 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | public class Http { 11 | 12 | public static ArrayList Response (String str,String cookie, String ua,String xHeaders,String methods,String dataBody,String enctypeBody,boolean follow){ 13 | ArrayList responseList = new ArrayList(); 14 | int code,contentLength; 15 | String body,banner; 16 | HttpRequest response = null; 17 | Map headers = new HashMap(); 18 | if (ua.equals("")){ 19 | ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" + 20 | " (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"; 21 | } 22 | if (!"SESSION=A202106084F2...".equals(cookie)){ 23 | headers.put("cookie",cookie); 24 | } 25 | 26 | 27 | 28 | headers.put("User-Agent",ua); 29 | if (!xHeaders.equals("X-Forwarded-for: 127.0.0.1\nReferer: ...") && !xHeaders.equals("")) { 30 | System.out.println(xHeaders); 31 | try { 32 | String[] split1 = xHeaders.split("\n"); 33 | for (String s : split1) { 34 | String[] split2 = s.split(": "); 35 | headers.put(split2[0], split2[1]); 36 | } 37 | }catch (Exception e){ 38 | e.printStackTrace(); 39 | } 40 | } 41 | 42 | if (methods == "post") 43 | { headers.put("Content-type",enctypeBody); 44 | response = HttpRequest.post(str).headers(headers).trustAllHosts().trustAllCerts().send(dataBody).followRedirects(follow); 45 | } 46 | if (methods == "head"){ 47 | response = HttpRequest.head(str).headers(headers).trustAllCerts().trustAllHosts().followRedirects(follow); 48 | } 49 | if(methods == "get"){ 50 | response = HttpRequest.get(str).headers(headers).trustAllHosts().trustAllCerts().followRedirects(follow); 51 | } 52 | code = response.code(); 53 | body = response.body(); 54 | banner = response.header("server"); 55 | contentLength = response.contentLength(); 56 | if (contentLength == -1) { 57 | try { 58 | contentLength = body.getBytes("UTF-8").length; 59 | } catch (UnsupportedEncodingException e) { 60 | e.printStackTrace(); 61 | } 62 | } 63 | responseList.add(code); 64 | responseList.add(body); 65 | responseList.add(banner); 66 | responseList.add(contentLength); 67 | return responseList; 68 | } 69 | 70 | // 重载方法 71 | public static ArrayList Response (String str,String cookie, String ua,String xHeaders,String methods,String dataBody,String enctypeBody,boolean follow,String host,int port){ 72 | ArrayList responseList = new ArrayList(); 73 | int code,contentLength; 74 | String body,banner; 75 | Map headers = new HashMap(); 76 | HttpRequest response = null; 77 | if (ua.equals("")){ 78 | ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" + 79 | " (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"; 80 | } 81 | // System.out.println(!"SESSION=A202106084F2...".equals(cookie)); 82 | if (!"SESSION=A202106084F2...".equals(cookie)){ 83 | headers.put("cookie",cookie); 84 | } 85 | 86 | headers.put("User-Agent",ua); 87 | if (!xHeaders.equals("X-Forwarded-for: 127.0.0.1\nReferer: ...") && !xHeaders.equals("")){ 88 | System.out.println(xHeaders); 89 | try { 90 | String[] split1 = xHeaders.split("\n"); 91 | for (String s : split1) { 92 | String[] split2 = s.split(": "); 93 | headers.put(split2[0], split2[1]); 94 | } 95 | }catch (Exception e){ 96 | e.printStackTrace(); 97 | } 98 | } 99 | 100 | if (methods == "post") 101 | { headers.put("Content-type",enctypeBody); 102 | response = HttpRequest.post(str).useProxy(host, port).headers(headers).trustAllHosts().trustAllCerts().send(dataBody).followRedirects(follow); 103 | } 104 | if (methods == "head"){ 105 | response = HttpRequest.head(str).useProxy(host, port).headers(headers).trustAllCerts().trustAllHosts().followRedirects(follow); 106 | } 107 | if(methods == "get"){ 108 | response = HttpRequest.get(str).useProxy(host, port).headers(headers).trustAllHosts().trustAllCerts().followRedirects(follow); 109 | } 110 | code = response.code(); 111 | body = response.body(); 112 | banner = response.header("server"); 113 | contentLength = response.contentLength(); 114 | if (contentLength == -1) { 115 | try { 116 | contentLength = body.getBytes("UTF-8").length; 117 | } catch (UnsupportedEncodingException e) { 118 | e.printStackTrace(); 119 | } 120 | } 121 | responseList.add(code); 122 | responseList.add(body); 123 | responseList.add(banner); 124 | responseList.add(contentLength); 125 | return responseList; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /Main.java: -------------------------------------------------------------------------------- 1 | package com.webRequest; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | new Gui(); 6 | } 7 | 8 | } 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 本工具仅限技术研究与测试,严禁用于非法用途,否则产生的一切后果自行承担。 2 | #### 介绍 3 | 4 | WEB批量请求器(WebBatchRequest)是对目标地址批量进行快速的存活探测、Title获取,简单的banner识别,支持HTTP代理以及可自定义HTTP请求用于批量的漏洞验证等的一款基于JAVA编写的轻量工具。 5 | 6 | ##### 支持功能 7 | 8 | - [x] 支持数据的导入、导出 9 | - [x] GET、POST、HEAD请求 10 | - [x] HTTP代理 11 | - [x] 自定义Header(可Host头碰撞等) 12 | - [x] 自定义Cookies 13 | - [x] 自定义User-Agent 14 | - [x] 跟随302跳转 15 | - [x] 进度条功能 16 | - [x] 自定义线程数 17 | - [x] 默认浏览器打开 18 | - [x] 列表结果排序 19 | - [x] 如果有什么建议需求可以在ISSUES提出来 20 | 21 | #### 效果 22 | ![image](https://user-images.githubusercontent.com/62375108/122643486-9f901a00-d142-11eb-8cf3-cd735e8a36be.png) 23 | ![image](https://user-images.githubusercontent.com/62375108/122658947-3f7e8f80-d1a5-11eb-9f87-4510131907ea.png) 24 | ![image](https://user-images.githubusercontent.com/62375108/122643506-ba628e80-d142-11eb-9315-9efc8445d203.png) 25 | ##### v1.3 26 | ![image](https://user-images.githubusercontent.com/62375108/126460021-a7bd55ff-6b6e-4c2b-8e07-cae0261a1c83.png) 27 | ##### v1.4 28 | ![image](https://user-images.githubusercontent.com/62375108/141076363-7b07b391-83b5-45cd-85c0-cc074ec87028.png) 29 | 30 | 31 | #### 项目地址 32 | 33 | ``` 34 | https://github.com/ScriptKid-Beta/WebBatchRequest 35 | ``` 36 | #### Jar文件 37 | ``` 38 | https://github.com/ScriptKid-Beta/WebBatchRequest/releases 39 | ``` 40 | #### 最后 41 | 42 | 欢迎师傅star,最重要的是如果师傅们有什么建议或者Bug,请在ISSUES里提出来~ 43 | -------------------------------------------------------------------------------- /Re.java: -------------------------------------------------------------------------------- 1 | package com.webRequest; 2 | 3 | import java.util.regex.Matcher; 4 | import java.util.regex.Pattern; 5 | 6 | public class Re { 7 | public static String Title (String str){ 8 | String is_title = "(.*)"; 9 | Matcher matcher = Pattern.compile(is_title).matcher(str); 10 | if (matcher.find()){ 11 | return matcher.group(1); 12 | }else{ 13 | return ("未获取到title"); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /TxtFile.java: -------------------------------------------------------------------------------- 1 | package com.webRequest; 2 | import java.io.BufferedReader; 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.InputStreamReader; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class TxtFile { 10 | public static List readTxtFile(String filePath) { 11 | List urList=new ArrayList(); 12 | try { 13 | String encoding = "GBK"; 14 | File file = new File(filePath); 15 | String filename = file.getPath(); 16 | if (file.isFile() && file.exists() && filename.endsWith(".txt")) { //判断文件是否存在,是否为TXT文件 17 | InputStreamReader read = new InputStreamReader( 18 | new FileInputStream(file), encoding);//考虑到编码格式 19 | BufferedReader bufferedReader = new BufferedReader(read); 20 | String lineTxt = null; 21 | while ((lineTxt = bufferedReader.readLine()) != null) { 22 | // System.out.println(lineTxt); 23 | urList.add(lineTxt); 24 | } 25 | read.close(); 26 | } else { 27 | System.out.println("找不到指定的TXT文件"); 28 | return null; 29 | } 30 | } catch (Exception e) { 31 | System.out.println("读取文件内容出错"); 32 | e.printStackTrace(); 33 | return null; 34 | } 35 | return urList; 36 | } 37 | } -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.example 8 | LogsScan 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | org.apache.maven.plugins 14 | maven-compiler-plugin 15 | 16 | 7 17 | 7 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | com.github.kevinsawicki 27 | http-request 28 | 6.0 29 | 30 | 31 | 32 | --------------------------------------------------------------------------------