除了文件下载外,文件上传也是项目开发中经常用到的功能。此时需要用HttpClient类库的扩展包HttpMime中的MultipartEntity类,此类同样实现了HttpEntity接口。需要注意的是HttpClient通过POST来上传文件,而不是通过流的形式。

示例:使用HttpClient实现文件上传功能。

第一步:要求在服务器端使用fileupload组件接收客户端提交内容。新建一个JSP项目zghc,首先在WEB-INF/lib目录下加入commons-fileupload-1.2.2.jar和commons-io-2.4.jar两个jar包,然后再提供一个对用户提交数据(文本、文件)进行处理的Servlet,具体代码如下所示:

@WebServlet("/uploadServlet")
public class UploadServlet extends HttpServlet {    // 使用fileupload组件
    private static final long serialVersionUID = 1L;
    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        // 检测是不是文件上传的请求
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);
        if (isMultipart) {// 属于上传文件的请求
            // 创建磁盘工厂,该类用来配置上传组件ServletFileUpload
            DiskFileItemFactory factory = new DiskFileItemFactory();
            factory.setSizeThreshold(10 * 1024 * 1024);
            factory.setRepository(new File("D:/")); // 设置存放临时文件的目录
            // 使用磁盘工厂实例化上传组件
            ServletFileUpload upload = new ServletFileUpload(factory);
            upload.setSizeMax(10 * 1024 * 1024); // 设置允许的最大上传尺寸
            upload.setHeaderEncoding("UTF-8");// 明确指定使用UTF-8编码
            PrintWriter out = response.getWriter();
            try {    // 获取客户端提交过来的所有请求参数
                List<FileItem> items = upload.parseRequest(request); // 解析
                for (FileItem item : items) {//对用户上传的所有文件进行遍历
                    if (item.isFormField()) {// 如果是表单字段
                        System.out.println(item.getFieldName() "  " 
item.getString("UTF-8"));
                    } else {// 如果是文件
                        String path = request.getSession().getServletContext()
                                .getRealPath("/");// 站点根目录的路径
                        String name = item.getName().substring(
                                item.getName().lastIndexOf("/")   1); // ---②
                        // 保存用户上传的文件到指定目录
                        item.write(new File(path, name)); 
                        System.out.println("上传完毕");
                        response.setCharacterEncoding("UTF-8");
                        out.println("上传完毕");
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                out.println("文件超过规定大小");
            }
        }
    }
}

FileItemFactory类的setSizeThreshold()方法用来设置上传文件时用于临时存放文件的内存的大小,超出的部分将临时存放在硬盘,可以使用FileItemFactory类的 setRepository()方法设置临时文件的目录。

在调用item.write()方法写入数据到文件中时,如果文件的名称是中文,有可能会出现乱码;另外需要注意的是Windows系统中item.getName()方法的返回的值是带路径的。

提示:

如果使用tomcat6,采用传统的在web.xml方式中配置Servlet,编号②处的代码需要改为:item.getName().lastIndexOf("\")
第二步:提供一个JSP文件upload.jsp,对上面的Servlet进行测试。注意在此JSP文件中需要设置form表单的enctype的值为multipart/form-data。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <title>My JSP 'index.jsp' starting page</title>
    </head>
    <body>
        <form action="uploadServlet" method="post" enctype="multipart/form-data">
            标题:<input type="text" name="name"/>
            文件:<input type="file" name="imgFile"/>
            <input type="submit" value="提交"/>
        </form>
    </body>
</html>

为了能上传文件,必须将表单的method属性设置为POST、enctype属性设置为multipart/form-data,只有这样,浏览器才会把用户选择文件的二进制数据发送给服务器。

第四步:将上面的JSP项目部署到tomcat中,然后在打开的upload.jsp页面中输入文件名,选中要上传的文件,单击【提交】按钮,然后在tomcat下的webapps\zghc目录下确实发现上传的文件,表明文件上传成功。

第五步:新建一个Android项目,将httpmime_XXXX.jar文件添加到当前项目的classpath路径下面,然后在项目中添加一个实现上传功能的工具类,具体代码如下所示:

public class HttpClientUtil {
    public static HttpClient httpClient = new DefaultHttpClient();
    public static String sendPost(String url,HashMap<String,String> map,File file){
        String result = null;
        HttpPost post = new HttpPost(url);// 创建HttpPost对象
        // 如果传递参数个数比较多的话可以对传递的参数进行封装
        MultipartEntity entity = new MultipartEntity();
        try {
            for (String key : map.keySet()) {    // 封装请求参数
StringBody value = new StringBody(map
                        .get(key), Charset.forName("UTF-8"));//避免传递汉字出现乱码
                entity.addPart(new FormBodyPart(key,value));
            }
            if(file != null)
                entity.addPart("myfile", new FileBody(file));
            post.setEntity(entity);// 设置请求参数
            synchronized (httpClient) {
                HttpResponse response = httpClient.execute(post);// 发送POST请求
                if (response.getStatusLine().getStatusCode() == 200){
                    HttpEntity resEntity = response.getEntity();
                    result = EntityUtils.toString(resEntity, "UTF-8");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }
}

第六步:为了提高用户体验,我们提供一个线程类来实现文件文件上传的功能,具体代码如下所示:

public class UploadThread extends Thread {
    private String url;
    private HashMap<String, String> map;
    private File file;
    private Handler handler;
    public UploadThread(String url, HashMap<String, String> map, File file,
            Handler handler) {
        this.url = url;
        this.map = map;
        this.file = file;
        this.handler = handler;
    }
    @Override
    public void run() {
        String result = HttpClientUtil.sendPost(url, map, file);  //具体上传代码
        System.out.println("aaaaa"   result);
        if ("上传完毕".equals(result.trim())) {
            handler.sendEmptyMessage(1);
        } else {
            handler.sendEmptyMessage(0);
        }
    }
}

第七步:在主布局文件中提供一个onClick属性值为upload的Button,然后修改MainAcvitity类的代码如下所示:

public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    private Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            if (msg.what == 1) {
                Toast.makeText(MainActivity.this, "提交数据成功", 1).show();
            } else {
                Toast.makeText(MainActivity.this, "提交数据失败", 1).show();
            }
        }
    };
    public void upload(View view) {
        HashMap<String, String> map = new HashMap<String, String>();
        map.put("username", "music");
        File sdPath = Environment.getExternalStorageDirectory();
        File file = new File(sdPath   "/zbjbxf.mp3");
        String url = "http://10.0.2.2:8080/zghc/uploadServlet";
        UploadThread thread = new UploadThread(url, map, file, handler);
        thread.start();
    }
}

在保证第一步创建的JSP项目已经部署到tomcat中且tomcat已经启动的前提下,运行本程序,发现当点击客户端主界面中的Button按钮后,在tomcat下的webapps/zghc目录下确实看到了刚才上传的文件。

大家可以将前面章节中学到Android中制作文件管理器的知识和本示例程序结合起来,实现一个能够通过图形化方式选择文件的文件上传软件。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持Devmax。

HttpClient实现文件上传功能的更多相关文章

  1. ios – 使用MonoTouch,HttpClient和Charles Proxy时的HTTP流量监控问题

    我是HttpClient类的新手,我遇到了使用CharlesProxy监视请求的问题.基本上我需要的是监视从模拟器或实际iOS设备发出的请求.Here您可以找到有关如何配置CharlesforiOS开发的精彩教程.我正在制作简单的HttpClient请求,只是一个简单的授权代码有效,用户正在被授权,并且正在返回承载令牌.但是问题是,我在模拟器上的请求没有出现在Charleshttp流量监控列表中.

  2. 开发Swift iOS应用程序“正确的方式”

    最近,我学习了Swift和开发iOS应用程序的基础知识。现在,我想自己开发一个真正的应用程序,但我非常关心编写好的代码,所以我已经寻找“最佳实践”,“设计模式”和“正确的方式”来实现它。在我的搜索中,我发现这个greattutorial关于SwiftiOS应用程序中通常使用的所有设计模式,以及他们使用的示例。不应该将httpClient和persistencyManager声明为协议,然后HttpClient和PersistencyManager类实现该协议?我应该在哪里告诉应用程序?最后但并非最不重要的

  3. android – 用我非常简单的calabash测试用例不断得到错误“HTTPClient :: ReceiveTimeoutError”

    我是calabash-android测试自动化库的新手.我花了两天时间来理解这个问题没有成功:(我正在使用calabash-android版本0.8.0,我按照文档pre-definedsteps进行测试.我的测试很简单,只需等待登录界面(这是一个包含id为“email_field”的输入字段的活动),输入用户名和密码.这是我在功能文件中的步骤:当我使用命令calabash-android运行my

  4. Android httpclient – 获取具有抢先身份验证的文件

    我使用此示例代码获取网站的HTML代码时遇到问题.http://svn.apache.org/repos/asf/httpcomponents/httpclient/branches/4.0.x/httpclient/src/examples/org/apache/http/examples/client/ClientPreemptiveBasicAuthentication.java我必须使用上

  5. Android无法访问org.apache.http.client.HttpClient

    我正在使用androidstudio创建一个向服务器发出GET请求的应用程序.我的代码是这样的:问题是AndroidStudio标记了这一行有错误:说“无法访问org.apache.http.client.HttpClient”这是我的gradle文件:解决方法在AndroidSDK23中不推荐使用HttpClient,因为它推断,您可以在HttpURLConnection中迁移代码https:/

  6. android – 使用OkHttp或Retrofit将文件上传到AWS S3存储桶

    是否有使用Square的OkHttp库或Retrofit库将文件上传到S3存储桶的示例?我正在寻找一些示例,我可以使用预先签名的查询使用这些库上传文件.解决方法我或多或少地从一些预生产代码中复制了这个:

  7. Android HttpClient,DefaultHttpClient,HttpPost

    我如何将字符串数据(JSONObject.toString())发送到URL.我想在util类中编写一个静态方法来执行此操作.我希望方法签名如下publicstaticStringpostData(Stringurl,StringpostData)抛出SomeCustomException字符串url的格式应该是什么返回String是来自服务器的响应,作为json数据的字符串表示.编辑目前的连接工

  8. Android:HTTPClient

    我正在从svn.apache.org尝试http-cleint教程.在运行应用程序时,我在控制台中收到以下错误.我在AndroidManifest.xml中添加了android.permission.INTERNET.HalloAndroid.java中的java代码如下任何帮助深表感谢.解决方法问题解决了.AndroidManifest.xml文件中的这一行导致了麻烦.

  9. android – 同时使用多个AsyncTasks的HttpClient请求

    我正在开发一个需要同时下载多个文件的应用程序.我正在为每个文件创建一个具有自己的HttpClient的AsyncTask,但是下一个文件只有在上一个文件完成后才开始下载.可能是服务器端的问题吗?

  10. NodeJS使用formidable实现文件上传

    这篇文章主要为大家详细介绍了NodeJS使用formidable实现文件上传的相关方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部