千里冰封
JAVA 浓香四溢
posts - 151,comments - 2801,trackbacks - 0

有些网页是屏蔽了鼠标右键的,不让我们查看它的源代码或者不让我们点击鼠标右键,在此我们可以写一个程序,让它获得这个网页的流,然后我们不就什么都能看到了吗?此程序就是这样写的,先获得网页的输入流,然后得到这个输入流的一些参数,比如这个流的长度,这个流所使用的编码.然后根据这些参数来进行获取,并根据不同的情况提供不同的进度条,比如有些网页它的长度返回的是-1,这个时候就用一个无状态的进度条来表示,如果长度大于0的话,那就用可以实时显示目前读取网页的进度.正好借这个机会又把swing复习了一下.呵呵.

运行时的图片如下:

下面是代码.

/*
 * Test4.java
 *
 * Created on 2007年9月27日, 下午3:05
 
*/

package test2;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;

/**
 *
 * 
@author  hadeslee
 
*/
public class Test4 extends javax.swing.JFrame {

    
private Task task; //只存在的一个方法

    
/** Creates new form Test4 */
    
public Test4() {
        
try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } 
catch (Exception exe) {
            exe.printStackTrace();
        }
        initComponents();
        jpb.setStringPainted(
true);
        jpb.setVisible(
false);
        
this.setLocationRelativeTo(null);
    }

    
/** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     
*/
    
// <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jLabel1 
= new javax.swing.JLabel();
        input 
= new javax.swing.JTextField();
        jButton1 
= new javax.swing.JButton();
        jScrollPane1 
= new javax.swing.JScrollPane();
        output 
= new javax.swing.JTextArea();
        jButton2 
= new javax.swing.JButton();
        jButton3 
= new javax.swing.JButton();
        jpb 
= new javax.swing.JProgressBar();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle(
"查看网页源文件");
        setResizable(
false);

        jLabel1.setForeground(
new java.awt.Color(5151255));
        jLabel1.setText(
"地址");

        input.setForeground(
new java.awt.Color(5151255));
        input.addActionListener(
new java.awt.event.ActionListener() {
            
public void actionPerformed(java.awt.event.ActionEvent evt) {
                inputActionPerformed(evt);
            }
        });

        jButton1.setForeground(
new java.awt.Color(5151255));
        jButton1.setText(
"查看");
        jButton1.addActionListener(
new java.awt.event.ActionListener() {
            
public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jScrollPane1.setBorder(javax.swing.BorderFactory.createTitledBorder(
"源文件"));

        output.setColumns(
20);
        output.setEditable(
false);
        output.setLineWrap(
true);
        output.setRows(
5);
        output.setWrapStyleWord(
true);
        jScrollPane1.setViewportView(output);

        jButton2.setText(
"保存");
        jButton2.addActionListener(
new java.awt.event.ActionListener() {
            
public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        jButton3.setText(
"退出");
        jButton3.addActionListener(
new java.awt.event.ActionListener() {
            
public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton3ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout 
= new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 
450, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(input, javax.swing.GroupLayout.DEFAULT_SIZE, 
359, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton1))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(
101010)
                        .addComponent(jButton2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButton3)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jpb, javax.swing.GroupLayout.DEFAULT_SIZE, 
314, Short.MAX_VALUE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(jButton1)
                    .addComponent(input, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 
223, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jButton2)
                        .addComponent(jButton3))
                    .addComponent(jpb, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

        pack();
    }
// </editor-fold>

    
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
        
// TODO add your handling code here:
        if (task != null) {
            task.cancel();
        }
        task 
= new Task(input.getText());
        
new Thread(task).start();
    }

    
private void inputActionPerformed(java.awt.event.ActionEvent evt) {
        
// TODO add your handling code here:
        if (task != null) {
            task.cancel();
        }
        task 
= new Task(input.getText());
        
new Thread(task).start();
    }

    
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
        
// TODO add your handling code here:
        System.exit(0);
    }

    
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
        
// TODO add your handling code here:
        doSave();
    }

//用于保存的方法
    private void doSave() {
        String s 
= output.getText();
        
if (s == null || s.equals("")) {
            JOptionPane.showMessageDialog(
this"当前没有东西可保存!!");
            
return;
        }
        JFileChooser jfc 
= new JFileChooser(".");
        FileNameExtensionFilter txt 
= new FileNameExtensionFilter("文本文档(*.txt)""txt");
        FileNameExtensionFilter html 
= new FileNameExtensionFilter("网页文档(*.html)""html""htm");
        jfc.addChoosableFileFilter(html);
        jfc.addChoosableFileFilter(txt);
        
int i = jfc.showSaveDialog(this);
        
if (JFileChooser.APPROVE_OPTION == i) {
            BufferedWriter bw 
= null;
            
try {
                File f 
= jfc.getSelectedFile();
                FileFilter filter 
= jfc.getFileFilter();
                FileNameExtensionFilter ff 
= null;
                
//如果是可以匹配的,则匹配,否则的话,只能用户输入什么
                
//就是什么了,即使他不输入后缀名那也没办法了
                if (filter instanceof FileNameExtensionFilter) {
                    ff 
= (FileNameExtensionFilter) filter;
                    String[] exts 
= ff.getExtensions();
                    
boolean match = false;
                    
for (String ext : exts) {
                        
if (f.toString().toLowerCase().endsWith(ext.toLowerCase())) {
                            match 
= true;
                            
break;
                        }
                    }
                    
//如果没有匹配,则说明输入的时候,没有输入后缀名,我们要人工加上去
                    if (!match) {
                        f 
= new File(f.toString() + "." + exts[0]);
                    }
                }
                bw 
= new BufferedWriter(new FileWriter(f));
                bw.write(s);
                JOptionPane.showMessageDialog(
this"保存成功!!");
            } 
catch (IOException ex) {
                Logger.getLogger(Test4.
class.getName()).log(Level.SEVERE, null, ex);
            } 
finally {
                
try {
                    
if (bw != null) {
                        bw.close();
                    }
                } 
catch (IOException ex) {
                    Logger.getLogger(Test4.
class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }

//用于取源码的线程
    private class Task implements Runnable {

        
//此任务是否已经取消了
        private volatile boolean isCanceled;
        
private String s;
        
private int done; //已经完成的字节
        private InputStream is; //连上的输入流,如果长时间没有动作,则流也要被强制关闭
        private long time; //最新一次读流的时间

        
public Task(String s) {
            
this.s = s;
            time 
= System.currentTimeMillis(); //初始化第一次的时间
            new Thread() {

                
public void run() {
                    
while (!isCanceled) {
                        
try {
                            Thread.sleep(
1000);
                            
long now = System.currentTimeMillis();
                            
//如果最后一次读成功字节到现在已经过了30秒钟了,则强行断之
                            if (now - time > 30000) {
                                isCanceled 
= true;
                                jpb.setIndeterminate(
false);
                                jpb.setVisible(
false);
                                is.close();
                            }
                        } 
catch (Exception ex) {
                            Logger.getLogger(Test4.
class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                }
            }.start();
        }

        
public void run() {
            validate(s);
        }

        
//验证传入的字符串是否合法
        private void validate(String s) {
            
try {
                
if (s == null || s.equals("")) {
                    JOptionPane.showMessageDialog(Test4.
this"网址不能为空!!");
                    input.requestFocus();
                    
return;
                } 
else if (s.startsWith("http://")) {
                    
//什么都不要做
                } else {
                    
//如果没有加上http的前缀的话,我们帮他加上
                    s = "http://" + s;
                }
                
if (isCanceled) {
                    
return;
                }
                URL url 
= new URL(s);
                viewSource(url);
            } 
catch (MalformedURLException ex) {
                Logger.getLogger(Test4.
class.getName()).log(Level.SEVERE, null, ex);
                JOptionPane.showMessageDialog(Test4.
this"域名解析出错!!");
            }
        }

        
//执行查看网页源文件的动作
        private void viewSource(URL url) {
            
try {
                jpb.setVisible(
true);
                jpb.setValue(
0);
                jpb.setString(
"");
                HttpURLConnection http 
= (HttpURLConnection) url.openConnection();
                
//得到网页的内容长度,可能为-1
                int length = http.getContentLength();
                
if (length != -1) {
                    jpb.setIndeterminate(
false);
                    jpb.setMaximum(length);
                    jpb.setValue(
0);
                } 
else {
                    jpb.setString(
"");
                    jpb.setIndeterminate(
true);
                }
                
//中间再检查一下是否取消了本次任务,以免做无谓的功
                if (isCanceled) {
                    
return;
                }
                
//得到网页的编码,可能没有指定,如果没有指定,就用默认的系统编码了
                String contentType = http.getContentType();
                String encoding 
= null//将要使用的编码,它将从contentType里面去取
                if (contentType != null) {
                    
int index = contentType.indexOf("charset=");
                    
if (index != -1) {
                        encoding 
= contentType.substring(index + 8).trim();
                    }
                }
                is 
= http.getInputStream();
                
//如果得到的长度是-1,则不知道什么时候会读完
                
//这个时候就可以边读边显示出来
                if (length == -1) {

                    BufferedReader br 
= new BufferedReader(new InputStreamReader(is));
                    String temp 
= null;
                    output.setText(
null);
                    
while (br.ready()) {
                        time 
= System.currentTimeMillis();
                        temp 
= br.readLine();
                        
if (isCanceled) {
                            
return;
                        }
                        output.append(temp 
+ "\r\n");
                    }
                    System.out.println(
"读到底了");
                    isCanceled 
= true;
                    jpb.setIndeterminate(
false);
                    jpb.setVisible(
false);
                } 
else {
                    
//如果知道长度多长,就可以显示一个进度条,等所有的字节都读完再显示
                    ByteArrayOutputStream bout = new ByteArrayOutputStream();
                    
int data = -1;
                    
while ((data = is.read()) != -1) {
                        
if (isCanceled) {
                            
return;
                        }
                        time 
= System.currentTimeMillis();
                        
if (length > 0) {
                            done
++;
                            jpb.setValue(done);
                            
int rate = done * 100 / length;
                            jpb.setString(
"" + rate + "%");
                        }
                        bout.write(data);
                        
//如果长度不为-1,并且已经读了这么多长度以后,就要断线了
                        if (done == length) {
                            String text 
= null;
                            
byte[] b = bout.toByteArray();
                            
if (encoding == null) {
                                text 
= new String(b);
                            } 
else {
                                text 
= new String(b, encoding);
                            }
                            
if (!isCanceled) {
                                output.setText(text);
                            }
                            isCanceled 
= true;
                            jpb.setVisible(
false);
                            
return;
                        }
                    }
                }
            } 
catch (IOException ex) {
                Logger.getLogger(Test4.
class.getName()).log(Level.SEVERE, null, ex);
                
if (isCanceled) {
                    
return;
                } 
else {
                    JOptionPane.showMessageDialog(Test4.
this"打开网页失败!!");
                }
            } 
catch (Exception exe) {
                
if (isCanceled) {
                    
return;
                } 
else {
                    JOptionPane.showMessageDialog(Test4.
this"打开网页失败!!");
                }
            } 
finally {
                
try {
                    
if (is != null) {
                        is.close();
                    }
                    jpb.setVisible(
false);
                } 
catch (IOException ex) {
                    Logger.getLogger(Test4.
class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }

        
public void cancel() {
            isCanceled 
= true;
        }
    }

    
/**
     * 
@param args the command line arguments
     
*/
    
public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(
new Runnable() {

            
public void run() {
                
new Test4().setVisible(true);
            }
        });
    }
    
// Variables declaration - do not modify
    private javax.swing.JTextField input;
    
private javax.swing.JButton jButton1;
    
private javax.swing.JButton jButton2;
    
private javax.swing.JButton jButton3;
    
private javax.swing.JLabel jLabel1;
    
private javax.swing.JScrollPane jScrollPane1;
    
private javax.swing.JProgressBar jpb;
    
private javax.swing.JTextArea output;
    
// End of variables declaration
}



我是用NetBeans写的,程序部份都有注释,界面部份是拖出来的,以前我很不喜欢拖控件的,所有的界面都是自己手写代码,后来发现NetBeans的拖控件功能确实很强,应该说是JAVA IDE里面最强的了.所以忍不住就用了一下,感觉不错,所以向大家推荐一下.可执行的JAR文件也一并附上,点击这里下载.欢迎大家提出问题.

JAVA运行环境是JDK6.0:)




尽管千里冰封
依然拥有晴空

你我共同品味JAVA的浓香.
posted on 2007-09-28 11:33 千里冰封 阅读(3048) 评论(8)  编辑  收藏 所属分类: JAVASE

FeedBack:
# re: 网页源文件查看器
2007-09-28 12:45 | BeanSoft
思路好. 不过, 用 Firefox 的时候选择禁用 JavaScript 就行了, 还可以装个 NoScript 插件, 呵呵.

也可以用 IE 把页面另存为到硬盘上来打开.

IE 还可以安装 Instant Source, 再屏蔽也没用, 参考:
Instant Source 实时 IE HTML 源码查看(视频讲解)
http://www.blogjava.net/beansoft/archive/2007/09/24/147645.html  回复  更多评论
  
# re: 网页源文件查看器
2007-09-28 12:55 | sswhsz
在IE中也是只要在安全页把站点加入“受限制的站点”中就行了,还可以屏蔽掉那些飘来飘去的广告。  回复  更多评论
  
# re: 网页源文件查看器
2007-09-28 13:26 | 千里冰封
呵呵,方法都不错  回复  更多评论
  
# re: 网页源文件查看器
2007-09-28 13:26 | 千里冰封
写这个主要是练练手,线程,SWING,NET等的复习  回复  更多评论
  
# re: 网页源文件查看器
2007-09-28 15:59 | kangxm
恩!思路很好!学习了!

另外也推荐一下 Instant Source

很不错的IE插件,做WEB开发的必备浏览器插件!  回复  更多评论
  
# re: 网页源文件查看器[未登录]
2007-09-28 20:55 | -274°C
netbeans 的开发swing,的确很不方便。 以前我的网名叫冰峰,后叫过冰封 ,看来有点缘哦。  回复  更多评论
  
# re: 网页源文件查看器[未登录]
2007-09-28 21:09 | -274°C
我想说的确很强的,结果手误“netbeans 的开发swing,的确很不方便”哈哈。  回复  更多评论
  
# re: 网页源文件查看器
2007-09-29 09:45 | 千里冰封
@-274&#176;C
呵呵,的确有缘哦。  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: