java输出字符串到多个输出流 同时输出到console终端,网页,文本

网上有不少大牛做了一些比较高级的,例如重写stream类,加入多个输出流。

但其实很多时候我们没必要用到这么复杂。

例如我的应用,我只是想把错误信息输出到网页的同时,简单加几句话,可以把网页上的信息也写一份到数据库或者文本。

之前使用了重定向System.out的做法。

但最近做自定义错误页面的时候,发现一个高手更好的办法。之前都没试过这样用~~~

首先定义一个内存输出流:

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PrintStream printStream = new PrintStream(byteArrayOutputStream);

然后过程中,不要用System.out,全部用printStream

到最后,想要输出到哪,就再建立一个PrintStream对象(例如封装FileOutputStream),使用print方法,把byteArrayOutputStream输出。

FileOutputStream fileOutputStream = new FileOutputStream(new File(dir.getAbsolutePath() + File.separatorChar + "error-" + timeStamp + ".txt"));
new PrintStream(fileOutputStream).print(byteArrayOutputStream); //写到文件

最后,贴上完整的error.jsp代码,大家慢慢分析。如果有什么问题,欢迎大家提出指正。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@page isErrorPage="true" %>
<%@page import="java.text.SimpleDateFormat"%>
<%@ page import="java.io.*"%>
<%
    response.setStatus(HttpServletResponse.SC_OK);
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
    <head>
        <title>错误页面</title>
        <script type="text/javascript" src="./javascript/jquery-1.5.1.min.js"></script>
        <script>
            function showErrorMessage(){
                $("#errorMessageDiv").toggle();
            }
            $(document).ready(showErrorMessage);
        </script>
    </head>
    <body>
        <table width="100%">
            <tr>
                <td style="border-bottom:dotted 1px Gray;" colspan="2" >
                    <img src="images/error_title_icon.gif" id="img1" />&nbsp;&nbsp;错误提示                               
                </td><td></td>
            </tr>
            <tr>
                <td style="width: 130px" >
                    <img src="images/sorry.gif" id="error_img" />
                </td>
                <td>尊敬的用户:<br />系统出现了异常,请重试。
                    <br />如果问题重复出现,请向系统管理员反馈。<br /><br />
                    <a id="showErrorMessageButton" href="javascript:showErrorMessage();">详细错误信息</a>
                </td>
            </tr>
        </table>
        <div id="errorMessageDiv" >
            <pre>
                <%
                    try {
                        //全部内容先写到内存,然后分别从两个输出流再输出到页面和文件
                        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                        PrintStream printStream = new PrintStream(byteArrayOutputStream);

                        printStream.println();
                        printStream.println("用户信息");
                        printStream.println("账号:" + request.getSession().getAttribute("userName"));
                        printStream.println("访问的路径: " + request.getAttribute("javax.servlet.forward.request_uri"));
                        printStream.println();

                        printStream.println("异常信息");
                        printStream.println(exception.getClass() + " : " + exception.getMessage());
                        printStream.println();

                        Enumeration<String> e = request.getParameterNames();
                        if (e.hasMoreElements()) {
                            printStream.println("请求中的Parameter包括:");
                            while (e.hasMoreElements()) {
                                String key = e.nextElement();
                                printStream.println(key + "=" + request.getParameter(key));
                            }
                            printStream.println();
                        }

                        printStream.println("堆栈信息");
                        exception.printStackTrace(printStream);
                        printStream.println();

                        out.print(byteArrayOutputStream);    //输出到网页

                        File dir = new File(request.getRealPath("/errorLog"));
                        if (!dir.exists()) {
                            dir.mkdir();
                        }
                        String timeStamp = new SimpleDateFormat("yyyyMMddhhmmssS").format(new Date());
                        FileOutputStream fileOutputStream = new FileOutputStream(new File(dir.getAbsolutePath() + File.separatorChar + "error-" + timeStamp + ".txt"));
                        new PrintStream(fileOutputStream).print(byteArrayOutputStream); //写到文件

                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                %>
            </pre>
        </div>
    </body>
</html>

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java架构

一线互联网常见的 14 个 Java 面试题,你颤抖了吗程序员

跳槽不算频繁,但参加过不少面试(电话面试、face to face 面试),面过大 / 小公司、互联网 / 传统软件公司,面糊过(眼高手低,缺乏实战经验,挂掉)...

844
来自专栏Java技术栈

跟我学 Java 8 新特性之 Stream 流(二)关键知识点

我们的第一篇文章,主要是通过一个Demo,让大家体验了一下使用流API的那种酣畅淋漓的感觉。如果你没有实践,我还是再次呼吁你动手敲一敲,自己实实在跑一遍上一篇的...

1064
来自专栏C/C++基础

CVTE2016春季实习校招技术一面回忆(C++后台开发岗)

2016.3.15,参加了CVTE的技术面,很不幸,我和我的两位小伙伴均跪在了一面。先将当日的面试内容汇总如下,供后来者参考。我们三人各自也都总结了失败的原因,...

301
来自专栏移动开发的那些事儿

BlockCanary源码解析

如上代码中的loop()方法是Looper中的,我们的目的是监测主线程的卡顿问题,因为UI更新界面都是在主线程中进行的,所以在主线程中做耗时操作可能会造成界面卡...

632
来自专栏程序猿DD

Spring框架中的设计模式(四)​

本文是Spring框架中使用的设计模式第四篇。本文将在此呈现出新的3种模式。一开始,我们会讨论2种结构模式:适配器和装饰器。在第三部分和最后一部分,我们将讨论单...

3416
来自专栏JetpropelledSnake

Python Web学习笔记之GIL机制下的鸡肋多线程

1546
来自专栏mySoul

JavaScript设计模式入坑

570
来自专栏Java与Android技术栈

RxJava处理业务异常的几种方式关于异常处理业务异常总结

运行时异常: RuntimeException类及其子类都被称为运行时异常,这种异常的特点是Java编译器不去检查它,也就是说,当程序中可能出现这类异常时,即...

1333
来自专栏为数不多的Android技巧

[译]厌倦了NullPointException?Optional拯救你!

有人说,当你处理过了空指针异常才真正成为一个Java开发者。抛开玩笑话不谈,空指针确实是很多bug的根源。Java SE 8引入了一个新的叫做java.util...

662
来自专栏java技术学习之道

Java设计模式透析之 —— 单例(Singleton)

882

扫码关注云+社区