在这篇文章里将会谈到“Servlet 发送压缩的 web 页面”和“限制对指定的 web 页面的访问”的设计,如果已经掌握了,可以略过,谢谢。
一、Servlet 发送压缩的 web 页面
关于压缩的用意,就不去详细阐述了,用一个简单的例子:对于一个28.8kb 的调制解频率的连接,压缩平均用时不到5秒,可不压缩的则需要50秒。
在java 里实现压缩是一件比较简单的事情,因为所有的逻辑都封装到 java.util.zip 里面的类了。发送压缩的 web 页面过程大致如下:首先,首先 servlet 会检查头字段 Accept-Encoding,判断其实是否包含 gzip 的入口。如果有,则制定 gzip 为 Accept-Encoding 的值,接着使用 GZIPOutputStream 来输出页面(需要记住的是,完成输出后要关闭GZIPOutputStream )。如果没有,则使用常规的 PrintWriter 来输出页面。为了其考虑的完整性,还需要考虑到一个头字段Accept-Encoding,这个头字段可以限制内容的编码。
现在给出其具体代码的设计:
@WebServlet("/EncodePage")
public class EncodePage extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
String encodings = request.getHeader("Accept-Encoding");
String encodeFlag = request.getParameter("encoding");
String title;
PrintWriter out;
if (encodings != null && (encodings.indexOf("gzip") != -1)
&& !"none".equals(encodeFlag)) {
title = "Page encoded with Gzip";
OutputStream outTmp = response.getOutputStream();
out = new PrintWriter(new GZIPOutputStream(outTmp), false);
response.setHeader("Content-Encoding", "gzip");
} else {
title = "Unencoded Page";
out = response.getWriter();
}
out.println(""
+ title + "");
String message = "I am a student from scnu, and I love programmimg"
+ ",and what about you??";
for(int i = 0; i < 1000;i++){
out.println(message + "
");
}
out.println("");
out.close();
}
}
二、限制对指定的 web 页面的访问。
首先说明一下, 这个小东西纯粹是为了娱乐,绝不说明实际情况小会喜用这种机制来控制对指定页面的访问。使用servlet 控制表单的访问,需要程序员稍稍再付出一些,另外在一些简单的应用程序里,http 授权机制的已足矣。接着给出这个 http 授权的基本步骤:
(1)检查是否存在头字段 Authorization。如果不存在,转到第(2)步。如果存在,则跳过字段“basic”,用base64 编码的剩下的内容。这样会得到一个用户输入的 username:password的字符串,接着检出这个字符串能否与保存的数据匹配,如果匹配,转到指定 web 页面,不匹配,则转到第(2)步。
(2)返回 401(不授权)响应代码和一个如下格式的头字段:WWW-Authenticate: BASIC realm="some-name"。这个响应命令会让浏览器弹出一个对话框,让用户输入指定的账号和密码,接着就是重新连接。
先给出运行的效果图:
代码设计如下:
@WebServlet(urlPatterns = { "/ProtectedPage" },
initParams = { @WebInitParam(name = "passwordFile", value = "C:\\passwords.properties") })
public class ProtectedPage extends HttpServlet {
private Properties passwords;
private String passwordFile;
/**
* 读取配置文件,初始化passwords
*/
public void init(ServletConfig config) throws ServletException {
super.init(config);
try {
passwordFile = config.getInitParameter("passwordFile");
passwords = new Properties();
passwords.load(new FileInputStream(passwordFile));
} catch (IOException ioe) {
}
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String authorization = request.getHeader("Authorization");
if (authorization == null) {
askForPassword(response);
} else {
String userInfo = authorization.substring(6).trim();
BASE64Decoder decoder = new BASE64Decoder();
String nameAndPassword = new String(decoder.decodeBuffer(userInfo));
int index = nameAndPassword.indexOf(":");
String user = nameAndPassword.substring(0, index);
String password = nameAndPassword.substring(index + 1);
String realPassword = passwords.getProperty(user);
if ((realPassword != null) && (realPassword.equals(password))) {
String title = "Welcome to the Protected Page";
out.println("" + ""
+ title + "\n"
+ "congratulations. you have accessed a\n" + "highly proprietary company document.\n"
+ "shred or eat all hardcopies before\n" + "going to bed tonight.\n" + "");
} else {
askForPassword(response);
}
}
}
// 不存在字段 Authorization 时
private void askForPassword(HttpServletResponse response) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setHeader("WWW-Authenticate", "basic realm=\"privileged-few\"");
}
}
在这个程序里,需要读取C:\\passwords.property文件,如果没有,可以通过如下PasswordBuilder来创建。
public class PasswordBuilder {
public static void main(String[] args) throws Exception {
Properties passwords = new Properties();
passwords.put("admin", "admin");
passwords.put("user", "123456");
String passwordFile = "C:\\passwords.properties";
FileOutputStream out = new FileOutputStream(passwordFile);
passwords.store(out, "Passwords");
}
}