사용자 목록 조회(Sample) 작성
JaserAssistant 사용 방법 매뉴얼에서 예제로 만든 사용자 목록 조회 디자인 파일을 이용하여
Sample Web Application 상에서 Reporting 결과를 조회해보도록 한다.
이 매뉴얼상에 언급된 소스 코드들은 모두 Eclipse에 Import한 anyframe-sample-web 프로젝트에 예제로 들어있다.
Spring MVC Integration
JasperReports를 활용한 Sample Application은 Spring MVC와 통합된 형태로 개발되었다. Spring MVC를 통해서 JasperReports 뷰 기능이 호출되어
사용되고 있다. Spring MVC에 대한 자세한 설명은 Spring MVC 매뉴얼을 참고하도록 하고, 여기서는 JasperReports와 연계되어 작성한 내역을
중심으로 기술하고 있다.
아래 그림은 URL 요청에 따른 Spring MVC의 워크플로우를 나타낸 것이다.
- Front Controller - web.xml에 정의한 DispatcherServlet이 Front Controller 역할을 수행하며 URL 요청에 대한 처리를 담당한다
- Controller - Spring MVC에서 제공하는 ActionController를 상속받아서 개발자가 만들어야 하는 클래스로
이 예제에서는 ReportController 클래스가 이것으로 Model 객체를 생성하며, 뷰 이름을 결정짓게 된다. 해당 클래스 생성 후, jasperaction-servlet.xml 파일에 reportController 빈을 정의하도록 한다.
- View Template - JasperReports를 사용하여 HTML, Excel, PDF 등 여러가지의 형태로 사용자 목록 조회 결과를 Reporting할 것이므로
JasperReportsMultiFormatView 클래스를 사용한다. 이는 jasperaction-servlet.xml 파일에 정의되어 있다.
Configuration
Sample Application을 통해 JasperReports 예제를 실행시키기 위해서는 다음과 같이 2가지 XML 파일에 대해서
설정해야 한다.
JasperReports 예제가 Spring MVC를 통해서 호출되도록 구현되었기 때문에 여기에는 Spring MVC 관련 설정도 포함되어 있다.
- web.xml 작성
- jasperaction-servlet.xml 작성
Step 1 : web.xml
anyframe-sample-web/src/webapp/WEB-INF 폴더 하위의 web.xml에 아래 내용을 추가해 넣는다. 기존의 Anyframe Web 관련 설정은 그대로 두고
JasperReports 관련한 설정만 더 추가한 것이다.
jasperaction 서블릿의 클래스인 DispatcherServlet은 Spring MVC 클래스로 url이 /reports/ pattern으로 요청되면
모두 jasperaction 서블릿을 통해 서비스 되도록 설정하고 있다.
image 서블릿은 HTML 형태로 Reporting 하는 경우 image 파일을 처리해주기 위해서 필요한 서블릿이다. HTML 형태로 Reporting
하지 않는다면 설정할 필요가 없다.
<servlet>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/config/springmvc/action-servlet-*.xml, /WEB-INF/jasperaction-servlet.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>image</servlet-name>
<servlet-class>
net.sf.jasperreports.j2ee.servlets.ImageServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>/reports/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>image</servlet-name>
<url-pattern>/reports/image</url-pattern>
</servlet-mapping>
Step 2 : jasperaction-servlet.xml
action 서블릿의 클래스인 DispatcherServlet이 사용하는 빈 설정파일에 jasperaction-servlet.xml 파일을 등록해주도록 한다.
- urlMappingJasper - 예를 들어 /userlistreport.html, /userlistreport.pdf 등등의 형태로 URL 요청 시 reportController 빈을 호출한다.
- reportController - reportController 빈 클래스가 수행될 때 methodNameResolver를 사용한다.
- resolver - /userlistreport.* 형태로 URL이 요청된 경우 해당 Controller 클래스의 viewReport 메소드를 수행시킨다.
- reportView - 가장 핵심이 되는 빈으로 Controller로부터 뷰 이름을 알아낸 결과 reportView인 경우, ExtendedJasperReportsMultiFormatView 클래스를 실행시킨다.
reportView 빈의 Property 설명은 다음과 같다.
| Property |
Value |
설명 |
| url |
/WEB-INF/reports/userList.jasper |
jrxml 파일을 JasperAssistant Preview를 이용하여 컴파일한 결과 파일 |
| jdbcDataSource |
dataSource |
현재 HSQL DB를 사용하는 dataSource 빈 사용 |
| exporterParameters - ...IMAGES_URI |
image?image= |
HTML Reporting 시 이미지 파일을 출력하기 위해서 web.xml에 정의한 image 서블릿을 사용하도록 설정 |
| exporterParameters - ...CHARACTER_ENCODING |
euc-kr |
Reporting 시 한글 깨짐을 방지하기 위해서 설정 |
<bean id="urlMappingJasper" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>
**/userlistreport.* = reportController
</value>
</property>
</bean>
<bean id="reportController" class="com.sds.emp.user.springmvc.ReportController">
<property name="methodNameResolver" ref="resolver"/>
</bean>
<bean id="resolver" class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
<property name="mappings">
<props>
<prop key="/**/userlistreport.*">viewReport</prop>
</props>
</property>
</bean>
<bean id="reportView" class="anyframe.web.springmvc.common.jasperreports.ExtendedJasperReportsMultiFormatView">
<property name="url" value="/WEB-INF/reports/userList.jasper"/>
<property name="jdbcDataSource" ref="dataSource"/>
<property name="exporterParameters">
<map>
<entry key="net.sf.jasperreports.engine.export.JRHtmlExporterParameter.IMAGES_URI" value="image?image="/>
<entry key="net.sf.jasperreports.engine.JRExporterParameter.CHARACTER_ENCODING" value="euc-kr"/>
</map>
</property>
</bean>
JasperReports Extension
Anyframe Web에서 제공하는 Reporting 기능은 기본적으로 JasperReports 기능을 모두 제공하나 Spring MVC와 통합된 형태로
기능이 제공되고 있기 때문에 Spring MVC를 통해서 제공되지 않은 JasperReports 일부 기능이 있다.
아래와 같이 2가지 경우에 대해서 확장하여 제공하므로 추후 필요 시 참고하도록 한다. 확장된 공통 코드에 대해서는 Anyframe Web 라이브러리를 통해서 제공되므로
개발자가 추가 작업할 필요가 없다.
- HTML Reporting - 개발자 추가 작업 일부 필요
- Excel Reporting - 개발자 추가 작업 불필요
HTML Reporting
이미지 파일을 html 내에서 디스플레이 해주기 위해서 Spring MVC에서 제공해주는 뷰 클래스를 확장하고, Controller 클래스에
부가 작업을 해줘야 한다.
Spring MVC에서 제공해주는 뷰 클래스를 확장한 것은 Anyframe Web을 통해 제공될 것이므로, 개발자는
신경쓸 필요가 없다.
그러나 Controller 클래스에 부가 작업을 해야 하는 것은 개발자가 개발할 Controller내에 request 정보를 Model 객체 내에 저장시켜주는
작업으로 아래에 보여지는 코드와 같이 작성하도록 한다.
- JasperReportsMultiFormatView 확장 - renderReport 메소드 내에서 아래와 같이 request로부터 세션 객체를 얻어낸 후,
객체 내 어트리뷰트로 populatedReport 값을 저장한다. 이는 후에 HTML Reporting 시 이미지 파일을 디스플레이하기
위해 필요하다.(내용을 참고만 한다. 실제 개발자가 할 일은 없다.)
protected void renderReport(JasperPrint populatedReport, Map model,\
HttpServletResponse response) throws Exception {
// Check for request object and set image servlet
if (model.containsKey("requestObject")) {
HttpServletRequest request = (HttpServletRequest) model
.get("requestObject");
request.getSession().setAttribute(
ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE,
populatedReport);
}
- Controller 추가 작업 - 위에서와 같이 model 객채 내에서 "requestObject" 값을 얻어오기 위해서는 Controller 클래스의 Model 객체에
request 객체를 저장해주는 작업이 필요하다. 사용자 목록 조회 결과 Reporting을 위한 ReportContoller 클래스의 예는 다음과 같다.
public class ReportController extends MultiActionController {
public ModelAndView viewReport(HttpServletRequest request,
HttpServletResponse response)
throws Exception {
... 중략
Map model = new HashMap();
model.put("format", format);
model.put("requestObject", request);
return new ModelAndView("reportView", model);
}
}
Excel Reporting
Spring MVC에서 제공하는 뷰클래스를 기본으로 이용하면 Excel 파일 내에 이미지 파일이 보이지 않는다.
이는 Spring MVC에서 JasperReports와 통합하는 과정에 Excel 파일로 Output할 때 POI 라이브러리를 사용하였기 때문이다.
이를 JExcel API를 사용하는 것으로 변경하면 Excel 파일 내에 이미지 파일을 디스플레이하는 기능을 제공할 수 있다. (내용을 참고만 한다. 실제 개발자가 할 일은 없다.)
- ExtendedJasperReportsJXlsView 클래스 생성 - 기존의 POI 라이브러리를 사용한 Exporter 대신 JExcelAPI를 사용한 Exporter를 사용하는
신규 ExtendedJasperReportsJXlsView 클래스를 생성한다.
public class ExtendedJasperReportsJXlsView
extends ExtendedAbstractJasperReportsSingleFormatView {
public ExtendedJasperReportsJXlsView() {
setContentType("application/vnd.ms-excel");
}
protected JRExporter createExporter() {
return new JExcelApiExporter();
}
중략...
}
- JasperReportsMultiFormatView 클래스 확장 - 위에서 생성한 뷰 클래스를 사용하기 위해서는 JasperReportsMultiFormatView 클래스에 등록시켜줘야 한다.
아래 소스 코드를 보면 xls 확장자 요청 시 기존의 JasperReportsXlsView 클래스를 사용하지 않고 신규로 작성한 ExtendedJasperReportsJXlsView 클래스를 사용하고 있음을 확인할 수 있다.
public ExtendedJasperReportsMultiFormatView() {
this.formatMappings = new HashMap(4);
this.formatMappings.put("csv", ExtendedJasperReportsCsvView.class);
this.formatMappings.put("html", ExtendedJasperReportsHtmlView.class);
this.formatMappings.put("pdf", ExtendedJasperReportsPdfView.class);
// this.formatMappings.put("xls", JasperReportsXlsView.class);
this.formatMappings.put("xls", ExtendedJasperReportsJXlsView.class);
}