Servlet利用base64和json向客户端传输图片

博客讨论了在Servlet中使用base64编码传输图片导致的内存溢出问题,提到了错误的实现方式(如预分配完整文件大小的byte数组)。提供了两个解决方案:一是参考StackOverflow上的内存优化建议,二是改为传输图片URL而非base64编码。文章包含服务器端和客户端的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里写图片描述

更新:这种方法出毛病了!jvm堆溢出了!

原因:byte[] bytes = new byte[fileForInput.available()]这句话在遇到比较大的图片时,开的内存就大,压根就不能这么写!

解决方法一:http://stackoverflow.com/questions/9579874/out-of-memory-when-encoding-file-to-base64
解决方法二:不要传图片了!直接传URL吧!!

—————————————————————————————

其实跟上一篇blog差不多,客户端还是用HttpURLConnection。

服务器端Servlet在传输图片时,先将图片编码为base64格式(也就是一个字符串),然后放在JSONObject里,顺带着其他数据一起传给客户端。

客户端在收到JSONObject后,将base64格式字符串取出来,再解码写入到一个文件里,得到图片。

OK,下面上代码,服务器端:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        JSONObject json = new JSONObject();
        //图片路径
        String picPath = getServletContext().getRealPath("")+"/images/XXX.jpg";
        String content = ProcessClientData.getPicBASE64(picPath);
        json.put("content",content);
        json.put("name", "XXX.jpg");
        sendJson(json, response);

    }
    //base64编码函数
    public  String getPicBASE64(String picPath) {  
            String content = "";  
            try {  
                FileInputStream fileForInput = new FileInputStream(picPath);  
                byte[] bytes = new byte[fileForInput.available()];  
                fileForInput.read(bytes);  
                content = new sun.misc.BASE64Encoder().encode(bytes);   
                fileForInput.close();  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
            return content;  
        }  
        //发送json函数
        public void sendJson(JSONObject json,HttpServletResponse response){
            try{
                response.setCharacterEncoding("UTF-8");  
               response.setContentType("application/json;charset=UTF-8"); 
                PrintWriter out = response.getWriter();
                out.write(json.toString());
                out.flush();
                out.close();
            }catch(Exception e){

            }
        }

客户端:

        JSONObject jsonRec = new JSONObject();
        try {
            JSONObject  obj = new JSONObject();
            //要向服务器发的json
            obj.put("xxx", "XXX");
            // 创建url资源
            URL url = new URL("http://localhost/Test/XXXServlet");
            // 建立http连接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            // 设置允许输出
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 设置不用缓存
            conn.setUseCaches(false);
            // 设置传递方式
            conn.setRequestMethod("POST");
            // 设置维持长连接
            conn.setRequestProperty("Connection", "Keep-Alive");
            // 设置文件字符集:
            conn.setRequestProperty("Charset", "UTF-8");
            // 设置文件类型:
            conn.setRequestProperty("contentType", "application/json");


            // 开始连接请求
            conn.connect();
            OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
            // 写入请求的字符串
            writer.write(obj.toString());
            writer.flush();
            writer.close();


            //接收服务器返回的json
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8")) ;
            String line;
            StringBuilder sb = new StringBuilder();
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }     
            br.close();
            conn.disconnect();
            jsonRec = JSONObject.fromObject(sb.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
        //处理json
        String content = jsonRec.getString("content");
        String name = jsonRec.getString("name");

        BASE64Decoder decoder = new BASE64Decoder();  
        try {  
            // Base64解码  
            byte[] bytes = decoder.decodeBuffer(content);  
            for (int i = 0; i < bytes.length; ++i) {  
                if (bytes[i] < 0) {// 调整异常数据  
                    bytes[i] += 256;  
                }  
            }  
            // 生成图片  
            OutputStream outs = new FileOutputStream("C:/users/XXX/Desktop/"+name);  
            outs.write(bytes);  
            outs.flush();  
            outs.close();  

        } catch (Exception e) {  
            e.printStackTrace();
        }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值