Java Web学习笔记 3 深入Servlet技术


第3章 深入Servlet技术

请求-响应模式就是典型的Web应用程序访问过程,Java Web应用程序中,处理请求并发送响应的过程是由一种叫做Servlet的程序来完成的。

请求request,响应response,与HTTP协议

Telnet演示HTTP协议
默认telnet关闭的,控制面板中,program and feathers,找到telnet client进行开启。

GET方式查询:常用来查询信息
HTTP头数据:
User-Ageent:Mozilla/4.0(...)   浏览器信息
Accept:text/html; */*              浏览器支持的格式
cookie: account-Helloween       记录用户当前的状态
Referer: http://www.baidu.com 指从哪个页面单击链接进入的

POST方式提交数据
GET提交数据不能超过256字符,POST提交,数据不在浏览器地址中显示,常用来提交表单数据

其他访问方式
HEAD,DELETE,TRACE,PUT,OPTIONS

Servlet概述
Java Web应用程序中所有的请求-响应都是Servlet完成的,没有main之类的方法,当用户访问服务器的时候,Tomcat通过调用Servlet的某些方法完成整个处理过程的。

Servlet工作流程
HttpServeltRequest/HttpServletResponse
Java Web学习笔记 3 深入Servlet技术_第1张图片

Servlet接口
GET/POST/HEAD/PUT/DELETE/TRACE
一般为 doGet()/doPost() .../getLastModified(request)返回文档的最后修改时间

Java Web目录结构
Web程序部署在Tomcat的/webapps下面,用 http://localhost:8080/web1

编写Servlet
javax.servlet.* javax.servlet.http.* 
一般直接继承HttpServlet,覆盖方法即可,一般只覆盖doGet(),doPost()

3.3.1 实现Servlet

编写Web Project,FirstServlet.java,覆盖常用三个方法
本书使用的是java EE5,新建项目时需要注意
新建web Project-> 新建servlet,
FirstServlet.java
/**
      * The doGet method of the servlet. 
* * This method is called when a form has its tag value method equals to get. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred * * GET方式访问页面执行该函数 执行doGet之前会执行getLastModified,如果发现返回的数值与上次访问是相同, * 则认为文档没有更新,浏览器采用缓存而不执行,如果返回 -1,则认为最新,总是执行该函数 */ public void doGet(HttpServletRequest request , HttpServletResponse response ) throws ServletException, IOException { this.log("执行doGet方法..." );// 控制台日志输出信息 this.execute(request , response );// 处理doGet } /** * The doPost method of the servlet.
* * This method is called when a form has its tag value method equals to post. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred * * 以post方式访问页面时执行该函数,执行前不会调用getLastModified */ public void doPost(HttpServletRequest request , HttpServletResponse response ) throws ServletException, IOException { this.log("执行doPost方法" ); this.execute(request , response ); } @Override protected long getLastModified(HttpServletRequest req) { // TODO Auto-generated method stub this.log("执行 getLastModified 方法" ); return -1; } // 执行方法 private void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding( "UTF-8"); request.setCharacterEncoding( "UTF-8"); String requestURI = request.getRequestURI(); String method = request.getMethod(); String param = request.getParameter("param" );// 客户端提交的参数 param值 response.setContentType( "text/html");// 文档类型为HTML类型 PrintWriter out = response.getWriter(); out.println( ""); out.println( ""); out.println( " A Servlet"); out.println( " "); out.println( " 以" + method + " 方式访问该页面。取到的param参数为:" + param + "
" ); out.println( "
" ); out.println( "
" ); //客户端浏览器读取该文档的更新时间 out.println( " " ); out.println( " "); out.println( ""); out.flush(); out.close(); }

3.3.2 配置

首先名称及类名:
 FirstServlet
servlet.FirstServlet 


     message 
     welcome to FisrtServlet 
    
     
     encoding 
     utf-8
    
配置一个初始化参数

< load-on-startup>1 
配置Servlet的加载方式。0和1,1启动加载,否则,Tomcat会在有人第一次请求加载


    FirstServlet 
    / servlet/FirstServlet
  
 配置该Servlet的访问方式:这里即http://localhost:8080/servlet /servlet/FirstServlet
如果配置为/servlet/FirstServlet.* 使用http://localhost:8080/servlet /servlet/FirstServlet.XXX访问
通配符试了好像不行,还是支持多个映射,把需要的映射加进去吧

一个完整的servlet包括servlet类,配置,配置。利用myeclipse向导自动完成配置。

???部署到Tomcat6.0系统,然后启动,发现超时,可以使用:
部署的时候出现Server Tomcat v6.0 Server at localhost was unable to start within 45 seconds. If the server requires more time, try increasing the timeout in the server editor?
我们找到当前工程的workplace目录,然后按下面的操作:
找到workspace\.metadata\.plugins\org.eclipse.wst.server.core\servers.xml文件。
把其中的start-timeout="45" 改为  start-timeout="100" 或者更长,根据不同同学的工程大小来设置。
最后重启eclipse就可以了。

3.4 请求与响应

获取request变量
客户端浏览器发出的请求被封装HttpServletRequest对象,包含所有的信息。
在servlet项目中新建servlet,
RequestServlet.java:
public class RequestServlet extends HttpServlet {

     /**
      * Constructor of the object.
      */
     public RequestServlet() {
           super();
     }

     /**
      * Destruction of the servlet. 
*/ public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } // 返回客户端浏览器接受的文件类型 private String getAccept(String accept) { StringBuffer buffer = new StringBuffer(); if (accept .contains("image/gif")) buffer.append( "GIF文件,"); if (accept .contains("image/x-xbitmap")) buffer.append( "BMP文件,"); if (accept .contains("image/jpeg")) buffer.append( "JPG文件,"); if (accept.contains("application/vnd.ms-execel" )) buffer.append( "EXCEL文件," ); if (accept.contains("application/vnd.ms-powerpoint" )) buffer.append( "PPT文件,"); if (accept .contains("application/vnd.msword")) buffer.append( "Word文件," ); return buffer .toString().replaceAll(", $", ""); } // 返回客户端的语言环境 private String getLocale(Locale locale) { if (Locale.SIMPLIFIED_CHINESE.equals(locale)) return "简体中文" ; if (Locale.TRADITIONAL_CHINESE.equals(locale)) return "繁体中文" ; if (Locale.ENGLISH.equals(locale)) return "英文" ; if (Locale.JAPANESE.equals(locale)) return "日文" ; return "未知语言环境" ; } // 返回IP地址对应的物理地址 // private String getAddress(String ip){ // return IpUtil.getIpAddress(ip); // } // 返回客户端浏览器信息 private String getNavigatior(String userAgent) { if (userAgent .indexOf("TencentTraveler") > 0) return "腾讯浏览器" ; if (userAgent .indexOf("Maxthon") > 0) return "Maxthon浏览器" ; if (userAgent .indexOf("MyIE2") > 0) return "MyIE2浏览器" ; if (userAgent .indexOf("Firefox") > 0) return "Firefox浏览器" ; if (userAgent .indexOf("MSIE") > 0) return "IE浏览器" ; return "未知浏览器" ; } // 返回客户端操作系统 private String getOS(String userAgent) { if (userAgent .indexOf("Windows NT 5.1") > 0) return "Windows XP" ; if (userAgent .indexOf("Windows 98") > 0) return "Windows 98" ; if (userAgent .indexOf("Windows NT 5.0") > 0) return "Windows 2000" ; if (userAgent .indexOf("Linux") > 0) return "Linux" ; if (userAgent .indexOf("Unix") > 0) return "Unix" ; return "未知" ; } /** * The doGet method of the servlet.
* * This method is called when a form has its tag value method equals to get. * * @param request * the request send by the client to the server * @param response * the response send by the server to the client * @throws ServletException * if an error occurred * @throws IOException * if an error occurred */ public void doGet(HttpServletRequest request , HttpServletResponse response ) throws ServletException, IOException { request.setCharacterEncoding( "UTF-8"); response.setCharacterEncoding( "UTF-8"); response.setContentType( "text/html");//文档类型为HTML String authType = request .getAuthType(); String localAddr = request .getLocalAddr();//本地IP,服务器IP String localName = request .getLocalName();//本地名称,服务器名称 int localPort = request .getLocalPort();//本地端口,Tomcat端口 Locale locale = request.getLocale(); //用户的语言环境 String contextPath = request .getContextPath(); String method = request .getMethod();//get还是post String pathInfo = request .getPathInfo(); String pathTranslated = request.getPathTranslated(); String protocol = request.getProtocol(); //协议,这里指HTTP协议 String queryString = request.getQueryString();//查询字符串,即?后面的字符串 String remoteAddr = request .getRemoteAddr();//远程IP,客户端IP int port = request .getRemotePort();//远程端口,客户端端口 String remoteUser = request .getRemoteUser();//远程用户 String requestedSessionId = request.getRequestedSessionId();//客户端session的ID String requestURI = request .getRequestURI();//用户请求的URI StringBuffer requestURL = request.getRequestURL();//用户请求的URL String scheme = request.getScheme(); //协议头,这里为 http String serverName = request .getServerName();//服务器名称 int serverPort = request .getServerPort();//服务器端口 String servletPath = request.getServletPath();// servlet的路径 Principal userPrincipal = request.getUserPrincipal(); String accept = request.getHeader( "accept");//浏览器支持的格式 String referer = request.getHeader("referer" );//从哪个页面单击到本页 //user-agent 包括操作系统类型、版本号、浏览器类型、版本号 String userAgent = request.getHeader("user-agent" ); String serverInfo = this.getServletContext().getServerInfo(); PrintWriter out = response.getWriter(); out.println( ""); out.println( ""); out.println( " Request Servlet"); out.println( " "); out.println( " "); out.println( "您的IP为" + remoteAddr + ",位于:空 " + "; 您使用" + getOS(userAgent) + "操作系统," + getNavigatior( userAgent) + ",您使用 " + getLocale(locale) + "。
"); out.println( "服务器IP为" + localAddr + ",位于:空 " + "; 服务器使用" + serverPort + "端口,您的浏览器使用了," + port + "端口访问本网页。
" ); out.println( "服务器软件为" + serverInfo + "服务器名称为 " + localName + "。
" ); out.println( "您的浏览器接受" + getAccept(accept) + "。
" ); out.println( "您从" + referer + "访问到该页面。

" ); out.println( "使用的协议为" + protocol + "。URL协议头" + scheme + ",服务器名称" + serverName + ",您访问的URI为" + requestURI + "。
" ); out.println( "该servlet的路径为" + servletPath + ", 该servlet类名为" + this.getClass().getName() + "。
"); out.println( "本应用程序在硬盘的根目录为" + this.getServletContext().getRealPath("" ) + ", 网络的相对路径为" + contextPath + "。
" ); out.println( "
"); out.println( "

单击刷新本页面" ); out.println( " "); out.println( ""); out.flush(); out.close(); } /** * Initialization of the servlet.
* * @throws ServletException * if an error occurs */ public void init() throws ServletException { // Put your code here } }

结果:
Java Web学习笔记 3 深入Servlet技术_第2张图片


3.4.2 response生成图片验证码

通过HttpServletResponese获取的PrintWrite对象只能写字符型数据。
这里使用Servlet输出图片验证码,原理:
服务器生成一个包含随机字符串的图片发给客户端,客户端提交数据时需要填写字符串作为验证。
Servlet输出图片时,需要调用getOutputStream.

IdentityServlet.java
public class IdentityServlet extends HttpServlet {

     // 随机字典 不包括男人的0,O,1,I
     public static final char[] CHARS = { '2', '3', '4', '5', '6' , '7' , '8' ,
               '9', 'A', 'B', 'C', 'D', 'D', 'E', 'F', 'G', 'H' , 'J' , 'K' , 'L' ,
               'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W' , 'X' , 'Y' , 'Z' };
     public static Random random = new Random();

     // 获取6位随机数
     public static String getRandomstring() {
          StringBuffer buffer = new StringBuffer();// 字符串缓存
           for (int i = 0; i < 6; i++) {
                buffer.append( CHARS[random .nextInt(CHARS. length)]);
          }
           return buffer .toString();
     }

     // 获取随机的颜色
     public static Color getRandomColor() {
           return new Color(random.nextInt(255), random.nextInt(255),
                    random.nextInt(255));
     }

     // 返回某颜色的反色
     public static Color getReverseColor(Color c ) {
           return new Color(255 - c.getRed(), 255 - c.getGreen(),
                   255 - c.getBlue());
     }

     /**
      * Constructor of the object.
      */
     public IdentityServlet() {
           super();
     }

     /**
      * Destruction of the servlet. 
*/ public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } /** * The doGet method of the servlet.
* * This method is called when a form has its tag value method equals to get. * * @param request * the request send by the client to the server * @param response * the response send by the server to the client * @throws ServletException * if an error occurred * @throws IOException * if an error occurred */ public void doGet(HttpServletRequest request , HttpServletResponse response ) throws ServletException, IOException { response.setContentType( "image/jpeg");// 设置输出类型 String randomString = getRandomstring(); // 放到session中 request.getSession( true).setAttribute("randomString" , randomString); // 图片高度和宽度 int width = 100; int height = 30; // 随机颜色 背景色 Color color = getRandomColor(); Color reverse = getReverseColor(color); // 创建彩色图片 BufferedImage bi = new BufferedImage(width , height, BufferedImage. TYPE_INT_RGB); // 获取绘图对象 Graphics2D g = bi.createGraphics(); g.setFont( new Font(Font.SANS_SERIF, Font.BOLD, 16)); g.setColor( color); g.fillRect(0, 0, width, height); // 绘制背景 g.setColor( reverse); // 设置颜色 g.drawString( randomString, 18, 20);// 绘制随机字符 for (int i = 0, n = random.nextInt(100); i < n; i++) { g.drawRect( random.nextInt(width ), random.nextInt(height ), 1, 1); } ServletOutputStream out = response.getOutputStream(); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); encoder.encode(bi); out.flush(); } /** * The doPost method of the servlet.
* * This method is called when a form has its tag value method equals to * post. * * @param request * the request send by the client to the server * @param response * the response send by the server to the client * @throws ServletException * if an error occurred * @throws IOException * if an error occurred */ public void doPost(HttpServletRequest request , HttpServletResponse response ) throws ServletException, IOException { response.setContentType( "text/html"); PrintWriter out = response.getWriter(); out.println( ""); out.println( ""); out.println( " A Servlet"); out.println( " "); out.print( " This is "); out.print( this.getClass()); out.println( ", using the POST method"); out.println( " "); out.println( ""); out.flush(); out.close(); } /** * Initialization of the servlet.
* * @throws ServletException * if an error occurs */ public void init() throws ServletException { // Put your code here } }

注意
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(bi);
需要导入头文件:
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

生成的结果如下:


我们可以html.文件引用这个图片,identity.html
注意html中的路径问题;

                    
                    

你可能感兴趣的:(JAVA学习[--新--])