zoukankan      html  css  js  c++  java
  • Java Web整合开发(3) -- Servlet

    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="300px; "/> 
        <input type="submit" value="用雅虎搜索" style="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=" 350px; "> <br />
                <input type="file" name="file2" style=" 350px; "> <br />
                <input type="file" name="file3" style=" 350px; "> <br />
                <input type="file" name="file4" style=" 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)

  • 相关阅读:
    redis基本命令1
    MySQL笔记01(黑马)
    尚硅谷Java——宋红康笔记【day25-day29】
    尚硅谷Java——宋红康笔记【day19-day24】
    Java网络编程实践
    框架高频面试题
    多线程面试题
    尚硅谷Java——宋红康笔记【day11-day18】
    尚硅谷Java——宋红康笔记【day6-day10】
    尚硅谷Java——宋红康笔记【day1-day5】
  • 原文地址:https://www.cnblogs.com/thlzhf/p/3855146.html
Copyright © 2011-2022 走看看