1.3.5 方法
方法(类似于其他语言中的函数)可以看做是与类相关的小型程序。在某些示例中,程序员可能想获取某类输入、对该输入执行特定的操作并以特定的格式输出结果。方法的概念是为需要重复执行的操作而提出的。一个程序往往包含了多个方法,可以调用每个方法来执行数据操作。它们还要携带特定数目的参数,并返回一个输出值。
例1-15是携带整型参数并返回阶乘结果的方法实例。
例1-15 阶乘方法
1 int Factorial( int num ){
2 for( i = (num – 1) ; i > 0 ; i-- ){
3 num *= i; // shorthand for: num = num * i
4 }
5 return num;
6 }
在第1行中,Factorial是方法名;Factorial之前的int指出该函数返回一个整数;int num指出该方法携带一个名称为num的整型参数。return语句的作用是指定方法的输出值。
1.3.6 类
面向对象的程序是以类的形式组织的。和函数一样,类是具有某些特性的离散的程序单元。类是某类变量和函数的聚合体。类通常要创建一个用于定义类实例(称为对象)的构造函数。类还包含其他函数,用于对对象的实例进行操作。
比如,程序员为飞机厂商开发一个飞行模拟器,用于协助制定设计方案。在这种情形下,使用面向对象技术是很理想的。其设计思想是,创建一个plane类来封装评估飞机飞行的属性和函数。创建多个plane类的实例,每个实例都包含其惟一的数据。
plane类包含以下4个变量。
● weight
● speed
● maneuverability
● position
在模拟环境中,程序员可能要测试飞机在某种场景下的飞行情况。要修改对象的属性,还需要编写下面几个辅助函数。
● SetWeight( int )
● SetSpeed( int )
● SetManeuverability( int )
● SetPosition( [ ] )
● MoveToPosition( [ ] )
下面给出该对象的类的代码,如例1-16所示。
例1-16 plane类
1 public class plane{
2 int weight;
3 int speed;
4 int maneuverability
5 Location position /* The Location type defined elsewhere as an (x, y,
z) coordinate */
6
7 plane( int W, int S, int M, Location P ){
8 weight = W;
9 speed = S;
10 maneuverability = M;
11 position = P;
12 }
13
14 SetWeight( plane current, int W ){
15 current.weight = W;
16 }
17
18 /* Additional Methods for SetSpeed, SetWeight, SetPosition,
SetManeuverability, SetPosition defined here */
19 }
这些代码用于初始化一个plane对象。调用方法必须指定plane对象所需的各个选项:weight、speed、maneuverability和position。例如,SetWeight函数就指出了该对象可以执行的操作。
模拟程序可能要创建plane类的多个实例,并运行一个test flights集。也可能要创建多个实例来测试飞机的特性。例如,plane1可能重5000英磅、飞行时速500、可操作级别为10,而plane2可能重6000英磅、飞行时速600、可操作级别为8。在Java中,类的实例都是以同样的方式作为新的变量来创建的。plane1可以用下述代码来创建。
1 plane plane1;
2 Location p;
3 p = new Location( 3, 4, 5 );
4 plane1 = new plane( 5000, 500, 10, p );
类层次也可以通过继承来协助程序员。类通常是以树状结构来组织的,每个类都有父类和可能的子类。一个继承的类可以访问其父类或超类的函数。比如,如果plane类是vehicle类的子类,那么plane对象就可以访问所有vehicle对象的执行函数。
类带来了其他语言所不具备的优点。它们能有效地将程序组织成可以被继承的模块。还可以创建抽象类(abstract class)用来作为接口。接口只是定义函数,并不实现函数,其实现的细节留给子类来处理。类也可以指定为private类型,以保证除了特定的函数外,类内部的内容都不被外界访问。
1.3.7 获取HTTP报头
在编写网络和安全程序的时候,要充分利用程序设计语言的内部联网功能。例1-17是从URL上获取HTTP报头的程序。
例1-17 获取HTTP报头
1 import java.net.URL;
2 import java.net.URLConnection;
3 import java.io.*;
4 import java.util.*;
5
6 public class HTTPGET{
7 public static void main (String [] Args){
8 try{
9 FileWriter file = new FileWriter( "OutFile" );
10 PrintWriter OutputFile = new PrintWriter( file );
11
12 URL url = new URL( "http://www.google.com" );
13 URLConnection urlConnection = url.openConnection();
14 InputStream IS = urlConnection.getInputStream();
15
16 IS.close();
17 OutputFile.print( IS );
18 } catch (Exception e) { System.out.println("Error"); }
19 }
20 }
这个程序说明如何用Java完成网络设计和实现中的两种很有用的任务,即执行HTTP GET命令和将结果打印到文件中。第1行到第4行引入了URL链接和输入/输出必需的库。第9行和第10行初始化FileWriter对象来指定输出文件,然后创建一个PrintWriter对象,用于执行第17行的文件写操作。
使用Java.net.URLConnection类来创建连接需要几个步骤。首先,利用OpenConnection( )方法创建连接对象。在设置参数和选项后,再用Connect()方法建立真正的连接。只要连接已建立,信息就会返回到InputStream对象的IS中,第16行关闭字节流,第17行将其发送到文件中。
在可能出现异常的地方,Java使用try和catch块(第8行和第18行)把可能出现问题的代码包含起来。在第18行,程序员指定了异常的类型和名称以及异常出现时执行的操作。
Java还为底层的套接字控制提供了其他网络连接类,如下所示。
java.net.socket
java.net.serversocket
java.net.datagramsocket
java.net.multicastsocket
值得一提的是,虽然提供了这些类,但是它们并不能直接访问原始的套接字连接。如果要访问原始的套接字连接,就要考虑使用C、C++或C#。
Web站点用户经常被骗而把一些敏感的数据如信用卡和社会安全号码等公开给黑客。黑客把网站的界面映射到自己的服务器上来发动攻击,访问该网站的用户还以为在访问合法的站点。一种发起这种攻击的方法是,使用站点的公告栏来传送一个合法的外表,但是,其链接是恶意的。比如,合法用户可能会相信单击公告栏上的http://www.google.com/?news=story1.html可以访问一个新的故事页面。
恶意用户可能会用类似http://www.google.com/story= %40%77%77%77%2E% 79%61%68% 6F%6F%2E%63%6F%6D的链接来重定向访问地址。
那么如果不单击该链接,它会链接到哪里?它会链接到http://www.yahoo.com。该重定向过程是通过URL尾部的字符序列来完成的。这些字符是经过hex编码的,表示字符串@www.yahoo.com。
这种欺骗方法利用了早期的Web认证方案。用户通过输入类似http://user@site 格式的URL来访问一个站点。浏览器会访问 @ 后面的站点。黑客可以使用(ASCII)- to-HEX转换工具(如http://d21c.com/sookietex/ ASCII2HEX.html)来快速创建这种格式的恶意链接。
防范:
可以直接从公告栏来防范这种攻击:创建一个过滤脚本,来确保用户粘贴的链接的域名后缀都有/标记。例如,如果过滤脚本分析并编辑了先前的恶意链接,则其结果就会是:http://www.google.com/story=%40%77%77%77%2E%79%61%68% 6F% 6F%2E% 63%6F%6D。
该链接会生成一个错误,从而有效阻止攻击。注意,现在许多浏览器都针对这种攻击技术采取了保护措施,Firefox浏览器还会提醒用户。






