Servlert基本程序架构: (FirstServlet.java + web.xml)

FirstServlet.java

package com.helloben.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FirstServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        execute(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        execute(request, response);
    }

    @Override
    public String getServletInfo() {
        return "Short description";
    }
    
     protected void execute(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        response.setContentType("text/html;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        
        request.setCharacterEncoding("UTF-8");
        
        String requestUri = request.getRequestURI();
        String method = request.getMethod();
        String param = request.getParameter("param");
        
        try (PrintWriter out = response.getWriter()) {
           
            out.println("<!DOCTYPE html>");
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet FirstServlet</title>");            
            out.println("</head>");
            out.println("<body>");
            
            out.println("<h1>FirstServlet at " + request.getContextPath() + "</h1>");
            
            out.println("以 " + method + " 方式访问该页面。取到的 param 参数为:" + param + "<br/><br/>");
        
            out.println("<form action='" + requestUri + "' method='get'><input type='text' name='param' value=''><input type='submit' value='以 GET 方式访问 RequestServlet'></form>");
            out.println("<br/><br/>");
            out.println("<form action='" + requestUri + "' method='post'><input type='text' name='param' value=''><input type='submit' value='以 POST 方式访问 RequestServlet'></form>");
            out.println("<br/><br/>");
            
            out.println("<script>document.write('本页面最后更新时间:' + document.lastModified + '<br /><br/>'); </script>");
            out.println("<script>document.write('本页面URL:' + location + '<br/>' ); </script>");
            
            out.println("</body>");
            out.println("</html>");
        }
    }
}
View Code

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <servlet>
        <servlet-name>FirstServlet</servlet-name>
        <servlet-class>com.helloben.servlet.FirstServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>FirstServlet</servlet-name>
        <url-pattern>/FirstServlet</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
</web-app>

访问路径: http://localhost:8080/ch03servlet/FirstServlet

1. 获取request变量

        String authType = request.getAuthType();
        String localAddr = request.getLocalAddr();
        Locale locale = request.getLocale();
        String localName = request.getLocalName();
        String contextPath = request.getContextPath();
        int localPort = request.getLocalPort();
        String method = request.getMethod();
        String pathInfo = request.getPathInfo();
        String pathTranslated = request.getPathTranslated();
        String protocol = request.getProtocol();
        String queryString = request.getQueryString();
        String remoteAddr = request.getRemoteAddr();
        int port = request.getRemotePort();
        String remoteUser = request.getRemoteUser();
        String requestedSessionId = request.getRequestedSessionId();
        String requestURI = request.getRequestURI();
        StringBuffer requestURL = request.getRequestURL();
        String scheme = request.getScheme();
        String serverName = request.getServerName();
        int serverPort = request.getServerPort();
        String servletPath = request.getServletPath();
        Principal userPrincipal = request.getUserPrincipal();
        
        String accept = request.getHeader("accept");
        String referer = request.getHeader("referer");
        String userAgent = request.getHeader("user-agent");
        
        String serverInfo = this.getServletContext().getServerInfo();
View Code

2.生成图片验证码(IdentityServlet.java)

package com.helloben.servlet;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.servlet.*;
import javax.servlet.http.*;

public class IdentityServlet extends HttpServlet {
    
    public static final char[] CHARS = { '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', '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();
    
    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());
    }

    protected void execute(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        response.setContentType("image/jpeg");

        String randomString = getRandomString();
        request.getSession(true).setAttribute("randomString", randomString);

        int width = 100;
        int height = 30;

        Color color = getRandomColor();
        Color reverse = getReverseColor(color);

        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = bufferedImage.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);
        }

        // 转成JPEG格式
        ServletOutputStream out = response.getOutputStream();
        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
        encoder.encode(bufferedImage);
        out.flush();
    }
}
View Code

 3. 获取初始化变量

Enumeration params = this.getInitParameterNames();
while(params.hasMoreElements()){
    String usernameParam = (String)params.nextElement();
    String passnameParam = this.getInitParameter(usernameParam);
}

 4. 获取上下文变量

ServletContext servletContext = this.getServletConfig().getServletContext();

String uploadFolder = servletContext.getInitParameter("upload folder");
String allowedFileType = servletContext.getInitParameter("allowed file type");

5. 资源注入(InjectionServlet.java)

@Resource(name="hello")
private String hello;

@Resource(name="i")
private int i;

@Resource(name="persons")
private String persons;

web.xml

<env-entry>
    <env-entry-name>persons</env-entry-name>
    <env-entry-type>java.lang.String</env-entry-type>
    <env-entry-value>HelloBen, Tony, Rose, Alix</env-entry-value>
</env-entry>

6. 使用JNDI获取资源

Context ctx = new InitialContext();
String hello = (String)ctx.lookup("hello");
Integer i = (Integer)ctx.lookup("i");
String persons = (String)ctx.lookup("person");

7. 注射数据源

@Resource
javax.sql.DataSource datasource;

public Connection getConnection() throws SQLException{
    Connection conn = datasource.getConnection();
    return conn;
}

8. GET方式提交表单(search.jsp)

<form action='SearchServlet' method='get'>
    <input type="radio" name="type" value="web" checked/>网页
    <input type="text" name="word" value="" style="width:300px; "/> 
    <input type="submit" value="用雅虎搜索" style="width:100px; "/>
</form>

URL: http://server:8080/webapp/SearchServlet?type=web&word=wbsn

SearchServlet.java

String word = request.getParameter("word");
String type = request.getParameter("type");

9. POST方式提交表单(postPersonInfo.jsp)

<form action="PostServlet" method="POST">
    <input type="text" name="name" class="text" />
    <input type="password" name="password" class="text" />  
</form>

PostServlet.java

String name = request.getParameter("name");
String password = request.getParameter("password");
String sex = request.getParameter("sex");

int age = 0;
try {
    age = Integer.parseInt(request.getParameter("age"));
} 
catch (Exception e) {
}

Date birthday = null;
try {
    DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    birthday = format.parse(request.getParameter("birthday"));
} 
catch (Exception e) {
}

String[] interesting = request.getParameterValues("interesting");
String area = request.getParameter("area");
String description = request.getParameter("description");
String btn = request.getParameter("btn");
View Code

10. 上传文件

Web文件上传也采用POST方式。(upload.jsp)

<form action="UploadServlet" method="post" enctype="multipart/form-data">
    <input type="file" name="file1" class="text">          
</form>

上传文件时,浏览器以二进制方式发送数据。解析二进制数据需要类库,如SmartUpload与Apache Commons Fileupload。SmatUpload是商业类库,解析过程中数据存放在内存中,因此比较快,但是大文件时会内存溢出。

UploadServlet.java

File file1 = null; 
File file2 = null;
String description1 = null; 
String description2 = null;

// 使用 DiskFileUpload 对象解析 request
DiskFileUpload diskFileUpload = new DiskFileUpload();
try {
    // 将 解析的结果 放置在 List 中
    List<FileItem> list = diskFileUpload.parseRequest(request);
    out.println("遍历所有的 FileItem ... <br/>");
    // 遍历 list 中所有的 FileItem
    for(FileItem fileItem : list){
        if(fileItem.isFormField()){
            // 如果是 文本域
            if("description1".equals(fileItem.getFieldName())){
                // 如果该 FileItem 名称为 description1
                out.println("遍历到 description1 ... <br/>");
                description1 = new String(fileItem.getString().getBytes(), "UTF-8");
            }
            if("description2".equals(fileItem.getFieldName())){
                // 如果该 FileItem 名称为 description2
                out.println("遍历到 description2 ... <br/>");
                description2 = new String(fileItem.getString().getBytes(), "UTF-8");
            }
        }
        else{
            // 否则,为文件域
            if("file1".equals(fileItem.getFieldName())){
                // 客户端文件路径构建的 File 对象
                File remoteFile = new File(new String(fileItem.getName().getBytes(), "UTF-8"));
                out.println("遍历到 file1 ... <br/>");
                out.println("客户端文件位置: " + remoteFile.getAbsolutePath() + "<br/>");
                // 服务器端文件,放在 upload 文件夹下
                file1 = new File(this.getServletContext().getRealPath("attachment"), remoteFile.getName());
                file1.getParentFile().mkdirs();
                file1.createNewFile();

                // 写文件,将 FileItem 的文件内容写到文件中
                InputStream ins = fileItem.getInputStream();
                OutputStream ous = new FileOutputStream(file1);

                try{
                    byte[] buffer = new byte[1024]; 
                    int len = 0;
                    while((len=ins.read(buffer)) > -1) {
                        ous.write(buffer, 0, len);
                    }
                    out.println("已保存文件" + file1.getAbsolutePath() + "<br/>");
                }
                finally{
                    ous.close();
                    ins.close();
                }
            }
            if("file2".equals(fileItem.getFieldName())){
                // 客户端文件路径构建的 File 对象
                File remoteFile = new File(new String(fileItem.getName().getBytes(), "UTF-8"));
                out.println("遍历到 file2 ... <br/>");
                out.println("客户端文件位置: " + remoteFile.getAbsolutePath() + "<br/>");
                // 服务器端文件,放在 upload 文件夹下
                file2 = new File(this.getServletContext().getRealPath("attachment"), remoteFile.getName());
                file2.getParentFile().mkdirs();
                file2.createNewFile();

                // 写文件,将 FileItem 的文件内容写到文件中
                InputStream ins = fileItem.getInputStream();
                OutputStream ous = new FileOutputStream(file2);

                try{
                    byte[] buffer = new byte[1024]; 
                    int len = 0;
                    while((len=ins.read(buffer)) > -1) {
                        ous.write(buffer, 0, len);
                    }
                    out.println("已保存文件" + file2.getAbsolutePath() + "<br/>");
                }
                finally{
                    ous.close();
                    ins.close();
                }
            }
        }
    }
    out.println("Request 解析完毕");
} 
catch (FileUploadException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
View Code

11. 带进度条的文件上传

实时显示上传进度的原理是服务器在处理上传文件的同事,将上传进度的信息如文件总长度、已上传多少,传输速率等写入Session中。客户端浏览器利用Ajax技术再新开一个独立的线程从Session中获取上传进度信息,并实时显示。Session可以看做是服务器内存。

uploadprogress.jsp

<%@page language="java" contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>上传文件</title>
        <style type="text/css">
            body, td, div {
                font-size: 12px; 
                font-familly: 宋体; 
            }
            
            #progressBar {
                width: 400px;
                height: 12px;
                background: #FFFFFF;
                border: 1px solid #000000;
                padding: 1px;
            }
            
            #progressBarItem {
                width: 30%;
                height: 100%;
                background: #FF0000;
            }
        </style>
        <script type="text/javascript">
            var _finished = true;

            function $(obj){
                return document.getElementById(obj);
            }

            function showStatus(){
                _finished = false;
                $('status').style.display = 'block'; 
                $('progressBarItem').style.width = '1%'; 
                $('btnSubmit').disabled = true;

                setTimeout("requestStatus()", 1000); 
            }

            function requestStatus(){

                if(_finished) {
                    return;
                }

                var req = createRequest(); 

                req.open("GET", "ProgressUploadServlet");
                req.onreadystatechange = function(){
                    callback(req);
                }
                req.send(null);

                setTimeout("requestStatus()", 1000); 
            }

            function createRequest()
            {
                if(window.XMLHttpRequest)//ns
                {
                    return new XMLHttpRequest();
                }
                else//IE
                {
                    try{
                        return new ActiveXObject("Msxml2.XMLHTTP");
                    }
                    catch(e){
                        return new ActiveXObject("Microsoft.XMLHTTP");
                    }
                }
                return null;
            }
            
            function callback(req){

                if(req.readyState == 4) {
                    if(req.status != 200){
                        _debug("发生错误。 req.status: " + req.status + "");
                        return;
                    }

                    _debug("status.jsp 返回值:" + req.responseText);

                    var ss = req.responseText.split("||");

                    // 格式:百分比||已完成数(M)||文件总长度(M)||传输速率(K)||已用时间(s)||估计总时间(s)||估计剩余时间(s)||正在上传第几个文件
                    $('progressBarItem').style.width = '' + ss[0] + '%'; 
                    $('statusInfo').innerHTML = '已完成百分比: ' + ss[0] + '% <br />已完成数(M): ' + ss[1] + '<br/>文件总长度(M): ' + ss[2] + '<br/>传输速率(K): ' + ss[3] + '<br/>已用时间(s): ' + ss[4] + '<br/>估计总时间(s): ' + ss[5] + '<br/>估计剩余时间(s): ' + ss[6] + '<br/>正在上传第几个文件: ' + ss[7];

                    if(ss[1] == ss[2]){
                        _finished = true;
                        $('statusInfo').innerHTML += "<br/><br/><br/>上传已完成。";     
                        $('btnSubmit').disabled = false;
                    }
                }
            }
            
            function _debug(obj){
                var div = document.createElement("DIV");
                div.innerHTML = "[debug]: " + obj;
                document.body.appendChild(div); 
            }
        </script>
    </head>
    <body>
        <iframe name=upload_iframe width=0 height=0></iframe>
        
        <form action="ProgressUploadServlet" method="post" enctype="multipart/form-data" target="upload_iframe" onsubmit="showStatus()">
            <input type="file" name="file1" style="width: 350px; "> <br />
            <input type="file" name="file2" style="width: 350px; "> <br />
            <input type="file" name="file3" style="width: 350px; "> <br />
            <input type="file" name="file4" style="width: 350px; "> 
            <input type="submit" value=" 开始上传 " id="btnSubmit"></form>

            <div id="status" style="display: none; ">
                    上传进度条:
                    <div id="progressBar">
                        <div id="progressBarItem"></div>
                    </div>
                    <div id="statusInfo"></div>
            </div>
        </form>
    </body>
</html>
View Code

ProgressUploadServlet.java

package com.helloben.servlet.upload;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class ProgressUploadServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        response.setHeader("Cache-Control", "no-store");
        response.setHeader("Pragrma", "no-cache");
        response.setDateHeader("Expires", 0);

        UploadStatus status = (UploadStatus) request.getSession(true).getAttribute("uploadStatus");

        if (status == null) {
            response.getWriter().println("没有上传信息");
            return;
        }

        long startTime = status.getStartTime();
        long currentTime = System.currentTimeMillis();

        long time = (currentTime - startTime) / 1000 + 1;
        double velocity = ((double) status.getBytesRead()) / (double) time;
        double totalTime = status.getContentLength() / velocity;
        double timeLeft = totalTime - time;
        int percent = (int) (100 * (double) status.getBytesRead() / (double) status.getContentLength());
        double length = ((double) status.getBytesRead()) / 1024 / 1024;
        double totalLength = ((double) status.getContentLength()) / 1024 / 1024;

        // 格式:百分比||已完成数(M)||文件总长度(M)||传输速率(K)||已用时间(s)||估计总时间(s)||估计剩余时间(s)||正在上传第几个文件
        String value = percent + "||" + length + "||" + totalLength + "||"
            + velocity + "||" + time + "||" + totalTime + "||" + timeLeft + "||" + status.getItems();

        response.getWriter().println(value);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        UploadStatus status = new UploadStatus();
        UploadListener listener = new UploadListener(status);

        request.getSession(true).setAttribute("uploadStatus", status);

        // Apache 上传工具
        ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
        upload.setProgressListener(listener);

        try {
            List itemList = upload.parseRequest(request);

            for (Iterator it = itemList.iterator(); it.hasNext();) {
                FileItem item = (FileItem) it.next();
                if (item.isFormField()) {
                    System.out.println("FormField: " + item.getFieldName() + " = " + item.getString());
                } 
                else {
                    System.out.println("File: " + item.getName());

                    // 统一 Linux 与 windows 的路径分隔符
                    String fileName = item.getName().replace("/", "\\");
                    fileName = fileName.substring(fileName.lastIndexOf("\\"));

                    File saved = new File("C:\\upload_test", fileName);
                    saved.getParentFile().mkdirs();

                    InputStream ins = item.getInputStream();
                    OutputStream ous = new FileOutputStream(saved);

                    byte[] tmp = new byte[1024];
                    int len = -1;

                    while ((len = ins.read(tmp)) != -1) {
                            ous.write(tmp, 0, len);
                    }

                    ous.close();
                    ins.close();

                    response.getWriter().println("已保存文件:" + saved);
                }
            }
        } 
        catch (Exception e) {
            e.printStackTrace();
            response.getWriter().println("上传发生错误:" + e.getMessage());
        }
    }

    @Override
    public String getServletInfo() {
        return "Short description";
    }
}
View Code

UploadListener.java

package com.helloben.servlet.upload;

import org.apache.commons.fileupload.ProgressListener;

public class UploadListener implements ProgressListener {
    
    private UploadStatus status;

    public UploadListener(UploadStatus status) {
        this.status = status;
    }

    @Override
    public void update(long bytesRead, long contentLength, int items) {
        status.setBytesRead(bytesRead);
        status.setContentLength(contentLength);
        status.setItems(items);
    }   
}
View Code

UploadStatus.java

package com.helloben.servlet.upload;

class UploadStatus {
    private long bytesRead;
    private long contentLength;
    private int items;
    private long startTime = System.currentTimeMillis();

    public long getBytesRead() {
        return bytesRead;
    }
    public void setBytesRead(long bytesRead) {
        this.bytesRead = bytesRead;
    }

    public long getContentLength() {
        return contentLength;
    }
    public void setContentLength(long contentLength) {
        this.contentLength = contentLength;
    }

    public int getItems() {
        return items;
    }
    public void setItems(int items) {
        this.items = items;
    }

    public long getStartTime() {
        return startTime;
    }
    public void setStartTime(long startTime) {
        this.startTime = startTime;
    }
}
View Code

12. Servlet生命周期(init() --> service() --> destroy())

13. web.xml文件详解 (http://www.cnblogs.com/hellojava/archive/2012/12/28/2835730.html)

posted on 2014-07-19 16:15  逝者如斯(乎)  阅读(353)  评论(0编辑  收藏  举报