我为每个模块(项目、产品……)使用相同的代码来导出 PDF。所有地方都工作正常,但在一个地方,PDF文件创建和下载成功,但在控制台中它给出了这样的错误。
getOutputStream() has already been called for this response. Stacktrace follows:
java.lang.IllegalStateException: getOutputStream() has already been called for this response
at net.bull.javamelody.FilterServletResponseWrapper.getWriter(FilterServletResponseWrapper.java:121)
at grails.converters.JSON.value(JSON.java:199)
at grails.converters.JSON.render(JSON.java:134)
at grails.converters.JSON.render(JSON.java:150)
at com.****.***.RoomController$_closure2.doCall(RoomController.groovy:78)
at net.bull.javamelody.JspWrapper.invoke(JspWrapper.java:117)
at net.bull.javamelody.JdbcWrapper$DelegatingInvocationHandler.invoke(JdbcWrapper.java:233)
at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:197)
at net.bull.javamelody.MonitoringFilter.doFilter(MonitoringFilter.java:171)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
2013-05-06 17:38:54,381 ERROR [http-bio-8080-exec-5] GrailsExceptionResolver IllegalStateException occurred when processing request: [GET] /****/room/listByCompanyJSON - parameters:
extension: pdf
format: pdf
代码:
package com.company.pro
import grails.converters.JSON
import grails.plugins.springsecurity.Secured
import java.sql.Timestamp
import com.company.pro.constants.CommonSearchParams
import com.company.pro.constants.TicketType
import com.company.pro.decorator.JQGridDecorator
import com.company.pro.search.RoomSearch
class RoomController extends BaseController
{
def debugOn = log.isDebugEnabled()
static defaultAction = "list"
def userService
def inventoryJMSService
def filterUtilService
def accountJMSService
def ticketingJMSService
def minutesUntilStale = 5 //TODO: make this configurable?
def millisUntilStale = minutesUntilStale * 60 * 1000
def proExportService
@Secured(['ROLE_TelePresenceReportUser'])
def list(){
def colNames="'${g.message( code:'common.status' )}','${g.message( code:'rooms.label' )}','${g.message( code:'user.details.site' )}','${g.message( code:'device.city' )}','${g.message( code:'common.stateProvince' )}','${g.message( code:'common.country' )}'"
def colModel="{name:'status', editable: false, fixed: true, width:'60px'},{name:'room', editable: false, fixed: false, width:'200px'},{name:'siteName', editable: false, fixed: false, width:'350px'},{name:'city', editable: false, fixed:true, width:'125px'},{name:'state', editable: false, fixed: true, width:'150px'},{name:'country', editable: false, fixed: true, width:'150px'}"
[colNames:colNames, colModel:colModel]
}
@Secured(['ROLE_TelePresenceReportUser'])
def listJSON = {
chain(action: 'listByCompanyJSON', params: params)
}
@Secured(['ROLE_TelePresenceReportUser'])
def listByCompanyJSON = {
params.companyId= filterUtilService.getCurrentCustomer()?.id
params.monitoringStatus = CommonSearchParams.MONITORING
if(params.format!=null && params.format != "html"){
downloadList(session, params)
}
session.setAttribute("lastSearchParams", params)
def findRoomsResponse = inventoryJMSService.findRooms(params)
def search = new RoomSearch()
search.params = params
search.doSearch()
session.setAttribute("lastRoomsSearch", search.data?.collect {it.room})
def decorator = new JQGridDecorator(search)
def data = decorator.asRoomsListGrid()
def up = message(code:"status.up")
def down = message(code:"status.down")
data.rows.each {row -> row.cell[0] = row.cell[0] ? up : down }
render data as JSON
}
private downloadList(javax.servlet.http.HttpSession session, Map params) {
String cname = filterUtilService.getCurrentCustomer()?.name
cname = cname.replaceAll(" ","_")
def arrRooms =session.getAttribute("lastRoomsSearch")
def deviceArray = getAllDevices().findAll { device -> arrRooms.find({currRoom -> device.room == currRoom})}
def siteMap = getSiteMap(deviceArray)
deviceArray.each( {
it.siteName = it.siteName?.split(":")[1];
})
//populate device array with site map
deviceArray.each( {
it.metaClass.city = siteMap[it.siteId]?.city
it.metaClass.state = siteMap[it.siteId]?.state
it.metaClass.country = siteMap[it.siteId]?.country
it.metaClass.countryAbbrev = siteMap[it.siteId]?.countryAbbrev
it.metaClass.companyId = siteMap[it.siteId]?.companyId
it.metaClass.companyName = siteMap[it.siteId]?.companyName
})
def idList = deviceArray.collect({ it.deviceId})
def arrId = idList.toArray(new String[0])
//get url information for all device id's and populate that in deviceArray
params.deviceIds =arrId
params.populateSoldServices = false
def respo2 = inventoryJMSService.findDevicesByKeys(params)
def deviceByKeysSO = respo2.getDevices()
deviceArray.each({
def parentRec = it
def record = deviceByKeysSO.find {parentRec.deviceId == it.deviceHeaderMgmtSysSO.deviceId}
it.metaClass.deviceURL = record.deviceURL
it.metaClass.region = record.region
it.metaClass.floor = record.floor
})
List fields = ["city","state","companyId","companyName","countryAbbrev","country",
"productCategorization.tier1","productCategorization.tier2","productCategorization.tier3",
"deviceId", "deviceName","siteId", "siteName",
"mgmtSysAddIPSO.description","mgmtSysAddIPSO.ipAddress",
"mgmtSysAddIPSO.deviceExternalSysRefKey","mgmtSysAddIPSO.ipAddressTypeId",
"deviceURL",
"productCategorization.manufacturer","productCategorization.productModelVersion",
"region","floor","room"
]
Map labels = ["city" : message(code:"device.city"),
"state" : message(code:"common.stateProvince"),
"companyId" : message(code:"reports.telepresence.cdr.columns.COMPANYID"),
"companyName": message(code:"reports.telepresence.cdr.columns.COMPANYNAME"),
"countryAbbrev" : message(code:"common.country.abbrev"),
"country":message(code:"common.country"),
"deviceId": message(code:"device.label.id"),
"deviceName": message(code:"device.label.name"),
"siteId": message(code:"common.siteId"),
"siteName": message(code:"site.name"),
"deviceURL" : message(code:"device.url"),
"productCategorization.manufacturer": message(code:"device.detail.manufacturer"),
"productCategorization.productModelVersion": message(code:"device.detail.model.version"),
"region": message(code:"site.region"),
"floor":message(code:"site.floor"),
"room": message(code:"site.room")]
Map parameters
def title = message(code:"rooms.label.plural") + " " + message(code:"common.downloadDateTime") + " "+new Date()
if(params.extension == TicketType.EXPORT_EXCEL){
parameters = [title: title, "column.widths": [0.1, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.3, 0.3, 0.3,0.3,0.3,0.3,0.3,0.3,0.3, 0.2, 0.2, 0.2,0.2,0.2]]
labels << ["productCategorization.tier1": message(code:"device.product.categorization.tier1"),
"productCategorization.tier2": message(code:"device.product.categorization.tier2"),
"productCategorization.tier3": message(code:"device.product.categorization.tier3"),
"mgmtSysAddIPSO.description": message(code:"device.mgmt.system"),
"mgmtSysAddIPSO.ipAddress": message(code:"device.mgmt.system.address"),
"mgmtSysAddIPSO.deviceExternalSysRefKey": message(code:"device.mgmt.system.refc"),
"mgmtSysAddIPSO.ipAddressTypeId": message(code:"device.mgmt.system.ipAddress.typid")]
} else{
parameters = [title: title]
labels << ["productCategorization.tier1": message(code:"device.product.categorization.pc.tier1"),
"productCategorization.tier2": message(code:"device.product.categorization.pc.tier2"),
"productCategorization.tier3": message(code:"device.product.categorization.pc.tier3"),
"mgmtSysAddIPSO.description": message(code:"device.mgmt.sys"),
"mgmtSysAddIPSO.ipAddress": message(code:"device.mgmt.sys.address"),
"mgmtSysAddIPSO.deviceExternalSysRefKey": message(code:"device.mgmt.sys.refc"),
"mgmtSysAddIPSO.ipAddressTypeId": message(code:"device.mgmt.sys.ipAddress.typid")]
}
downloadDataToFiles(params.format, params.extension, "Room_List_" + cname,deviceArray, fields, labels, null, parameters)
return
}
/**
* This behavior has been moved to the JQGridDecorator object.
* Must remove this later, when there is time to test thoroughly
*/
private formatPanelResults={ findRoomsResponse ->
session.setAttribute("lastRoomsSearch", findRoomsResponse?.collect {it.room})
def allRows = findRoomsResponse?.collect {
[
cell: [
it.status,
it.room,
it.siteName,
it.city,
it.state,
it.country
],
id : it.room
]
}.unique()
def totalRows = allRows.size()
def maxRows = Integer.valueOf(params.rows?:1)
def currentPage = Integer.valueOf(params.page?:1)
def numberOfPages = Math.ceil(totalRows / maxRows).toInteger()
def rowOffset = ((currentPage - 1) * maxRows)
def maxIndex = rowOffset + maxRows
if (maxIndex > totalRows ) { maxIndex = totalRows }
[rows:allRows, records: totalRows, page: currentPage, total:numberOfPages]
}
@Secured(['ROLE_TelePresenceReportUser'])
def listDevicesByRoomJSON() {
if (params.room == null) {render ''}
def devicesForRoom = getRoomDeviceList().findAll { it.room == params.room }
if (debugOn) log.debug('devicesForRoom: ' + devicesForRoom)
def totalRows = devicesForRoom.size()
def maxRows = Integer.valueOf(params.rows?:1)
def currentPage = Integer.valueOf(params.page?:1)
def numberOfPages = Math.ceil(totalRows / maxRows).toInteger()
def rowOffset = ((currentPage - 1) * maxRows)
def maxIndex = rowOffset + maxRows
if (maxIndex > totalRows ) {maxIndex = totalRows}
if (debugOn) log.debug ("totalRows: $totalRows, maxRows: $maxRows, currentPage: $currentPage, numberOfPages: $numberOfPages, rowOffset: $rowOffset, maxIndex: $maxIndex")
def roleArr = session.getAttribute("roles")
def svcRole = roleArr.findAll{ it.name.equalsIgnoreCase('RequestServiceUser')}
def validRoleExists = false
if(svcRole.size == 1)
validRoleExists = true
def rows = devicesForRoom[rowOffset ..< maxIndex].collect() {
[
cell: [
it.deviceId,
it.deviceName,
it.status?'Up':'Down',
"<a href=" + createLink(controller:'requestService', action:'create',absolute:true, params:[thisDevice:it.deviceId, requestType:14, showDevSel:false]) + ">" + message(code:'default.button.create.label') + "</href>"
],
id:it.deviceId
]
}
def jsonData = [rows:rows, records: totalRows, page: currentPage, total:numberOfPages,showSvcReq:validRoleExists]
render jsonData as JSON
}
private uniqueRoomData() {
def deviceList = getRoomDeviceList()
def downRooms = deviceList.findAll { !it.status }.collect { it.room }
if (debugOn) log.debug("downRooms: $downRooms")
/* Added the below code for Download functionality */
//for the room list, we do not want device data
def temp = deviceList?.collect {
[
'status' : downRooms.contains(it.room) ? 'Down' : 'Up' ,
'room' : it.room,
'siteName' : it.siteName,
'city' : it.city,
'state' : it.state,
'country' : it.country
]
}
temp = sortList(temp)
//if more than one device in a room, there will be duplicate data. Remove it.
def rows = temp.unique().collect {
[
cell: [
it.status,
it.room,
it.siteName,
it.city,
it.state,
it.country
],
id : it.room
]
}
}
private sortList(list) {
def asc = params['sord']=='asc'
def idx = params['sidx']
if (asc) {
return list.sort { a, b ->
a[idx].compareToIgnoreCase(b[idx])
}
}
else {
return list.sort { a, b ->
b[idx].compareToIgnoreCase(a[idx])
}
}
}
private getRoomDeviceList() {
def roomDeviceList = session.getAttribute("roomDeviceList")
def roomDeviceListCreated = session.getAttribute("roomDeviceListCreated")
def refreshNeeded = false
//check for null or stale list
if (roomDeviceList != null && roomDeviceListCreated != null) {
def now = new Timestamp(System.currentTimeMillis())
refreshNeeded = (now - roomDeviceListCreated > millisUntilStale)
}
else {
//roomDeviceList or roomDeviceListCreated *is* null, generate new list
refreshNeeded = true
}
if(debugOn) log.debug( "refreshNeeded: " + refreshNeeded)
if (refreshNeeded) roomDeviceList = populateRoomDeviceListForSession()
if(debugOn) log.debug('roomDeviceList: ' + roomDeviceList?:"<null>")
return roomDeviceList
}
private populateRoomDeviceListForSession() {
//def devices = devicesInRooms(getAllDevices())
def devices = getAllDevices().findAll { it.room }
def alarmMap = getAlarmMap()
def siteMap = getSiteMap (devices)
def results = devices?.collect {
[
room : it.room,
deviceId : it.deviceId,
deviceName : it.deviceName,
siteName : it.siteName == null ? null: it.siteName.substring(it.siteName.indexOf(":")+1), //strip companyId & ':' from site name,
city : siteMap[it.siteId].city,
state : siteMap[it.siteId].state,
country : siteMap[it.siteId].country,
status:!(alarmMap?.values()?.contains(it.deviceId))
//status: message(code:alarmMap.values().contains(it.deviceId)?'status.down':'status.up')
]
}
session.setAttribute("roomDeviceList", results)
session.setAttribute("roomDeviceListCreated",new Timestamp(System.currentTimeMillis()))
return results
}
private getAllDevices() {
//AuthenticatedUser usr = springSecurityService.getPrincipal()
params.companyId= filterUtilService.getCurrentCustomer()?.id //usr.getCompanyId()
params.totalDeviceCountNeeded=true
params.monitoringStatus = CommonSearchParams.MONITORING
def tempRowParam = params.rows //need to store this value - will restore it later
params.rows = 9999 //we need all devices to find those with rooms...
def resp = inventoryJMSService.searchDevices(params)
params.rows = tempRowParam //restore original value so that pagination will work properly on first call
log.info("getAllDevices params:$params")
return resp?.getSearchDevices()
}
private getSiteMap(devices) {
String[] siteIds = (devices*.siteId).unique()
def siteMap = [:]
if (!siteIds) {
return siteMap
}
def resp = accountJMSService.findSitesByKeys([siteIds:siteIds])
resp?.sites?.each {
siteMap.put(it.id, [
name: it.name == null ? null: it.name.substring(it.name.indexOf(":")+1), //strip companyId & ':' from site name,
city:it.city,
state:it.stateProvince,
//country:it.countryAbbrev,//updated
countryAbbrev:it.countryAbbrev,
country:it.country,
companyId: it.companyId,
companyName:it.companyName
]
)
}
if (debugOn) log.debug(siteMap)
return siteMap
}
private getAlarmMap() {
def tempRowParam = params.rows //need to store this value - will restore it later
params.rows = 9999
if (debugOn) log.debug("getAlarmMap params: $params")
def resp = ticketingJMSService.searchAlapro([companyId:params.companyId, monitoringStatus:CommonSearchParams.MONITORING, ticketState: 'OPEN'])
def map = [:]
params.rows = tempRowParam //restore original value so that pagination will work properly on first call
log.info("getAlarmMap params:$params")
resp?.alapro?.each {
map.put(it.id, it.deviceId)
}
if (debugOn) log.debug("getAlarmMap map: $map")
return map
}
def listAll = {
def customer = filterUtilService.getCurrentCustomer()?.id
def search = new RoomSearch(customer)
render search.parseDataAsJSON() as JSON
}
def lastSearchFullDataset = {
def params = session.getAttribute("lastSearchParams");
params.loadonce = true
def search = new RoomSearch()
search.params = params
search.doSearch()
render search.data as JSON
}
def getRoomsByGroup = {
def rooms = []
def group = params.group=='Group 1'?'0':'1'
getAllDevices().collect{
if(group == it.group){
if(it.room !=null && it.room.trim() !="" && it.room.trim().length()>0){
rooms.add(it.room)
}
}
}
render rooms as JSON
}
}