本文档集中了用户在使用FineReport报表过程中最常见的一些问题及回答,包含了log输出级别、session问题集锦,Session赋值并获取,是否支持C++,.Net等,自定义出错页面等。如果您刚刚接触此款报表软件,此文档值得一看。 Log输出级别分为三种:SERVER,WARNING和INFO,SERVER是导出服务器的报错日志,WARNING 输出执行报表时的错误或警告信息,INFO则是导出所有报错信息。设计器默认的服务器log级别为WARNING。 1. 默认log查看 FineReport安装后会有自己的日志文件生成,不需要手动设置位置,也不可以改变其位置,可以直接查看相关信息。主要的两个就是设计器log:designer_error.log和服务器log:server_error.log,分别保存了设计器的执行信息和服务器的执行信息。
![]() 2. 设计器log配置 点击菜单栏中的窗口|选项,点击
![]() ![]() 3. 服务器log配置 打开FR管理平台,在服务器配置>基本界面中,有服务器log级别设置下拉框,选择不同级别输出不同信息。
![]() 服务器日志输出的位置就是在默认log位置中,输出到server_error.log中。 4. Log级别输出分别如下 4.1 设计器默认的服务器log级别WARNING: 输出执行报表时的错误或警告信息
![]() 警告信息(Scheduler 已经启动了,可以直接调用):
![]() 警告报错:
![]() 4.2 log级别Info 输出所有信息如登陆用户信息、报表执行的sql、报表执行时间、报表执行过程等,如下图为访问报表后台输出信息
![]() 4.3 log级别Server Server: 只输出服务器端的信息,报表相关的信息都不会显示出来。
FAQ >> session问题集锦 一般session问题在我们报表里面主要存在于如下几个方面:参数传递、权限、并发、集群。 1. FineReport中创建与关闭session机制 正常情况下,当客户端浏览器访问报表服务器端的某张报表时,便会产生一个session会话,当用户关闭浏览器的时候就会通知报表服务器关闭这个session。若用户的机器由于某种原因如非正常关机等等导致浏览器非正常关闭时,服务器没有收到关闭这个session的信息,会一直保存这个不必要的session。为了解决这个问题,我们软件中提供了这样一种机制,浏览器每隔40秒向服务器发送一个“i am alive”信息,若服务器一分钟没有收到这个信息便会自动关闭这个session。当浏览器遇到非正常停止时,便不会发送“i am alive”信息,相应的session会在一分钟以内被关闭。 2. 应用session与报表session 可能客户会有一个疑问就是系统应用和报表应用在一个web服务器下,那系统session和报表session是不是一个session,如果不是那会不会有冲突呢?答案是:不是一个session也不会起冲突,因为应用的session存放的是request请求等一些共享信息,而报表session存放的是访问报表的相关信息,比如访问的是不是同一个模板等,两者是完全独立的东西,所以不会冲突。 3. session中传递参数 session 中可以保存key-value这样的属性对,在同一个session中,可以拿到session中key与其值。如果我们报表中定义了参数a, 而session中保存了key a ,其值为123,那么在我们报表中使用=$a就能直接在session中获取到a的值。Session中赋值与取值如下:具体操作可以参考文档Session赋值并获取 HttpSession session = request.getSession(); // 获取Session对象 session.setAttribute(String key, Object value); // 设置Session中的属性 session.getAttribute(String key); // 获取Session属性 4. 权限 由于session中能够保存key对,因此在权限中如果报表工程与自己的工程在一个应用下面,即session相同,此时就能将用户名与密码存放于session中,在浏览器端将外界输入的用户名和密码保存至session中,报表服务便可以获得用户名与密码,去相应的地址匹配,匹配成功,通过权限关卡;匹配失败,跳转登录页面。 5. 并发 由 1可知,打开一个浏览器访问一张报表就会产生一个session,那么如果访问的用户多,每个用户都产生>=1个session的话,可以看到 session将会很多。如果session设置的为100个,session保持时间为3分钟,那么如果3分钟有105个session,超过的5个session就进入等待状态,若在3分钟后服务器还没有接受请求,这5个访问报表的页面就会返回session time out ,在6.5版本中已经将session超时时间默认设置为无穷大了。 6. 集群 集群的每台服务器间必须创建通信,即session粘滞,否则也会出现session time out。如若有3台服务器进行集群,用户发出一请求被分配至服务器A,保存了一些信息在session中,该用户再次发送请求被分配到服务器B,要用之前保存的信息,若服务器A和B之间没有session粘滞,那么服务器B就拿不到之前的信息,就返回session time out。 7. session基本概念 session机制本身并不复杂,然而其实现和配置上的灵活性却使得具体情况复杂多变。这也要求我们不能把仅仅某一次的经验或者某一个浏览器,服务器的经验当作普遍适用的经验,而是始终需要具体情况具体分析。 通俗的说:客户端浏览器访问某个地址,发送了一个请求,就产生一个session会话,现在的浏览器都可以打开多个tab窗口,打开的都属于一个 session,当该浏览器关闭的时候session就关闭了。若不关闭该浏览器,再次打开一个浏览器,会重新创建一个session。 7.1 session在何时被创建 一个常见的误解是以为session在有客户端访问时就被创建,然而事实是直到某server端程序调用HttpServletRequest.getSession(true)这样的语句时才被创建,注意如果JSP没有显示的使用 关闭session,则JSP文件在编译成Servlet时将会自动加上这样一条语句HttpSession session = HttpServletRequest.getSession(true),这也是JSP中隐含的session对象的来历。 由于session会消耗内存资源,因此,如果不打算使用session,应该在所有的JSP中关闭它。 7.2 session何时被删除 综合前面的讨论,session在下列情况下被删除a.程序调用HttpSession.invalidate();或b.距离上一次收到客户端发送的session id时间间隔超过了session的超时设置;或c.服务器进程被停止(非持久session)。 7.3 如何做到在浏览器关闭时删除session 严格的讲,做不到这一点。可以做一点努力的办法是在所有的客户端页面里使用javascript代码window.oncolose来监视浏览器的关闭动作,然后向服务器发送一个请求来删除session。但是对于浏览器崩溃或者强行杀死进程这些非常规手段仍然无能为力。 由上一章节可知,session中可以保存key-value这样的属性对,在同一个session中,可以拿到session中的key与其值。如果我们报表中定义了参数a,而session中保存了key a,其值为123,那么在我们报表中使用=$a就能直接在session中获取到a的值。Session中赋值与取值如下: HttpSession session = request.getSession(); //获取Session对象 session.setAttribute(String key, Object value); //设置Session中的属性 session.getAttribute(String key); //获取Session属性 访问报表时,若其参数名称在session中有对应的key而且在同一个应用环境下面,那么就能自动获取到值。以下我们以一个具体的例子说明如何将值保存在session中及报表如何获取。 1. 实现步骤 1.1 模板准备 新建工作薄,定义一个报表参数country 模板设计如下,在单元格中引用参数的值
![]() 保存模板如sessiongetpara.cpt。这边我们仅作原理说明,故模板制作简单一些。 在java系统比如某个jsp页面中,您可以通过session.setAttribute(String key, Object value);来设置key-value属性对。如下面这个sessionsetpara.jsp代码如下: 1. <%@ page language="java" contentType="text/html; charset="gb2312" pageEncoding="gb2312"%> 2. <% 3. session.setAttribute("country","China"); 4. %> 5. <html> 6. <body> 7. <p> 8. 已经将country参数保存进session,值为China! 9. </p> 10. </body> 11. </html> 1.3 参数值的获取 启动服务器(内置服务器无法解析jsp页面,请使用其他Web服务器进行测试),调用上述sessionsetpara.jsp页面时,便会将country的值保存至session中,在同一个浏览器中新打开一个窗口(使用的为同一个session),访问我们之前做的模板sessiongetpara.cpt 您就会发现,模板中自动获取到了country的值。 1. request对象: 该对象封装了用户提交的信息,通过调用该对象相应的方法可以获取封装的信息,即使用该对象可以获取用户提交信息。 request.getAttribute("key")可得到JSP页面存入Value。在实际的存储中,key和value是存放在一个哈希表中的,所以在这里给出String的Key会到哈希表中找出对应他的value。 而不同页面间传值使用request.setAttribute(key, value)时,只会从a.jsp到b.jsp一次请求,之后如果有第二次请求,这个request就会失去它的作用范围,再传就要再设置一次 request.setAttribute(key,value)或者使用request的forward()方法跳转也可以(因为它是一次请求)。而使用session.setAttribute()会在一个过程中始终保有这个值。 2. response对象: 包含了响应客户请求的有关信息,但在JSP中很少直接用到它。它是HttpServletResponse类的实例。response对象用于动态响应客户端请示,控制发送给用户的信息,并将动态生成响应。在响应客户端请求之前,一般可以先设置客户端响应的编码格式,以防客户端出现乱码。response.setCharacterEncoding("GBK"); response既可以在本网站跳转,也可以跳转到其他网站中;在跳转过程中,相当于在URL地址栏中重新输入URL,是第二次请求,所以在request和response保存的数据就不存在了。 3. session对象 指的是客户端与服务器的一次会话,从客户连到服务器的一个WebApplication开始,直到客户端与服务器断开连接为止。它是HttpSession类的实例. Session:用于保存每个用户的专用信息。Session中的信息保存在Web服务器的内存中,保存的数据量可大可小。当Session超时或被关闭时将自动释放保存的数据信息。对于小量的数据Session对象保存还是一个不错的选择。具体的session对象刻意参考其他章节:Session问题集锦和Session赋值并获取。 我们的报表软件是纯java编写的,对于java系统,我们能够很好的进行集成,那对于不是java开发的系统,比如C++开发的,那报表能够集成吗?以及该如何集成呢?有如下四种情况: 1. BS端将报表嵌在页面中,如asp页面,此时通过直接url便可以了,就像在页面中嵌入一个谷歌页面一样。 2. BS端直接跳转至报表页面,如页面中有个标签,点击的时候可以打开我们的报表,此时就是iis集成。 3. CS系统中查看报表内容,与java一样,C++等中也可以装浏览器插件,可以直接在CS系统中浏览报表页面。 4. CS系统中嵌入我们报表的格子控件,比如用户自己有一个CS系统,工具栏和菜单等等都自己定义,只需要把我们设计器中格子控件集成到他们系统中,用来编辑内容,这个我们不支持。 1. 问题描述 报表自带的抛错页面色调和整个应用的色调不一致如下图,项目里有自己统一的出错页面,因此需要使用自定义出错页面。
![]() 2. 解决方案 在服务器>服务器配置>出错模板定义直接调用自定义的出错页面如:/error.html,页面中可以通过模板出错参数message、charset、exception获取到报错信息。 3. 实现步骤 3.1 自定义出错页面 在使用自定义出错页面的时候可以调用报表系统错误页面的参数,下面简单的列出参数以及说明。
如上的参数可以通过${参数名}的形式调用。如在定义的error.html页面中调用参数message将提示错误信息显示在表格中,如下: 1. <html> 2. <body> 3. <table> 4. <tr> 5. <td> 6. ${message} 7. </td> 8. </tr> 9. </table> 10. </body> 11. </html> 3.2 调用自定义出错页面 定义好的出错页面在服务器>服务器配置>出错模板定义的模板路径中调用,可以通过相对路径或绝对路径进行调用: 相对路径:自定义的出错页面error.html放在当前Web应用下,如WebReport目录下,通过相对路径进行调用,模板路径为:/error.html; 绝对路径:自定义的出错页面error.html放在其他应用下,通过绝对路径进行调用,模板路径为:http://www./error.html。 注:通过绝对路径调用时为防止浏览器不自动识别传输协议,路径前须加上http://。
![]() |
|