我正在尝试制作一个 Jasper 客户端,其流程如下:它们是两个应用程序。一个调用另一个并由 iframe 显示。
主应用程序将凭据发送到 iframe 应用程序以获取会话并执行报告执行。
iframe 应用程序进行 REST 调用以获取会话,然后调用另一个以请求运行报告。结果是一个重定向到加载屏幕的链接。
资源
/**
* Request Execution "Servlet"
*
* @param request
* @param response
* @return
* @throws IOException
* @throws ServletException
*/
@Override
@POST
@Path("/execution")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.TEXT_HTML)
public String requestExection(@FormParam("username") String username,
@FormParam("pass") String pass,
@FormParam("type") String fileType,
@FormParam("fileUri") String reportUnit,
@FormParam("params") String params,
@Context HttpServletResponse response) throws IOException, ServletException {
JasperAuthentication session = new JasperAuthentication();
CookieStore cookieStore = new BasicCookieStore();
HttpContext httpContext = new BasicHttpContext();
httpContext.setAttribute(HttpClientContext.COOKIE_STORE, cookieStore);
List<NameValuePair> urlParameters = new ArrayList<>();
urlParameters.add(new BasicNameValuePair("j_username",username));
urlParameters.add(new BasicNameValuePair("j_password",pass));
String url = "";
try {
boolean valid = session.openSession(urlParameters,response,httpContext);
if (valid) {
ReportObject repObj;
Configuration config = PropertiesUtil.getProperties();
repObj = requestJasperReport(params, fileType, reportUnit, response, httpContext);
if (repObj != null) {
String strcookie = ServletUtils.getAllCookies(httpContext, ";");
System.out.println("Cookie String: " + strcookie);
Cookie cookie = new Cookie("context",
URLEncoder.encode(strcookie, StandardCharsets.UTF_8.toString()));
cookie.setPath("/");
cookie.setHttpOnly(true);
response.addCookie(cookie);
url = config.getString("client.host.url") + "/report-viewer/visualizer/processing?type=" + fileType
+ "&ticket=" + repObj.requestId + "&resource=" + repObj.exports.get(0).id + "&date="+getExpiryPropFromJasper(strcookie);
}
}
} catch (ConfigurationException e) {
e.printStackTrace();
}
return "{\"report_url\":\""+url+"\"}";
}
/**
* Method for Request a Jasper Report to Server
*
* @param strParams
* @param fileType
* @param response
* @param client
* @param httpContext
* @return
* @throws ClientProtocolException
* @throws IOException
* @throws ConfigurationException
*/
private ReportObject requestJasperReport(String strParams,
String fileType,
String reportUnit,
HttpServletResponse response,
HttpContext httpContext) throws IOException, ConfigurationException {
Configuration config = PropertiesUtil.getProperties();
StringBuilder sb = new StringBuilder();
sb.append(config.getString("server.host.url"))
.append(config.getString("services.report.execution"));
HttpPost post = new HttpPost(sb.toString());
Gson mGson = new Gson();
Map<String, String> params = new HashMap<>();
if (strParams != null) {
String[] parameters = strParams.split(",");
for (int i = 0; i < parameters.length; i++) {
String[] aux = parameters[i].split(":");
params.put(aux[0], aux[1]);
}
}
post.setHeader("Content-Type", "application/xml;");
post.setEntity(new StringEntity(ServletUtils.makeXMLRequest(reportUnit, params, fileType)));
int coderes;
Header[] headers = null;
String content = "";
ReportObject repRes = null;
try (CloseableHttpClient client = HttpClients.createDefault();
CloseableHttpResponse chres = client.execute(post,httpContext)) {
StatusLine status = chres.getStatusLine();
coderes = status.getStatusCode();
headers = chres.getAllHeaders();
content = EntityUtils.toString(chres.getEntity());
}
if (coderes == 200 && content != null && content.length() > 1) {
repRes = mGson.fromJson(content, ReportObject.class);
for (int i = 0; i < headers.length; i++) {
System.out.println(headers[i].getName() + "=" + headers[i].getValue());
response.addHeader(headers[i].getName(), headers[i].getValue());
}
}
return repRes;
}
/**
* To get Expiration Date of a Cookie from Jasper Server
*
* @param jaspercookie
* @return
*/
private String getExpiryPropFromJasper(String jaspercookie) {
String[] expirity = jaspercookie.split("expiry=");
return expirity[1].substring(0,expirity[1].length() - 2);
}
当主应用程序收到 URL 时,他会显示加载页面。加载屏幕的工作方式如下……等待 10 秒,然后重定向到另一个 servlet,它在该处请求报告的执行状态。如果报告准备好了,它会重定向到下载它的屏幕,如果它还没有准备好,那么它会重定向到加载屏幕。(我给你看这个是因为我怀疑这个)
var cont = 10; var intervalId = setInterval(countdown,1000); function countdown() { var ticket = $('#ticket').val(); var type = $('#type').val(); var resource = $('#resource').val(); var tries = $('#tries').val(); tries++; var url = window.location.protocol + "//" + window.location.host + "/report- viewer/visualizer/waitingroom? type="+type+"&ticket="+ticket+"&resource="+resource+"&tries="+tries; if (cont<=0) { clearInterval(intervalId); location.href = url; } cont--; }
问题从这里开始。当我尝试请求上一步时,我在控制台中收到此错误消息:
org.apache.http.MalformedChunkCodingException: Bad Chunk Header: {"url":"http://localhost:8080/report-viewer/visualizer/processing? . . ."} at org.apache.http.impl.io.ChunckedInputStream..getChunkSize...
但在我得到这个之前,我注意到我使用 javascript 进入了这一部分。(顺便说一句,接收到 401,这意味着我的会话似乎无效,即使我保存在 cookie 中的信息与登录 web 服务抛出的会话 cookie 完全相同。也许我错过了一些东西来保持这种视觉活跃) 然后如果我尝试再次执行调用序列,则会收到错误消息。
我可以读到默认情况下,apache 具有 maxKeepAliveRequests = 100 的属性。我怀疑我的 javascript 可能会触发这个,因为可能在循环内部(在 javascript - JSP 之间)它正在打开连接(这只是怀疑)。
我在没有连接两个应用程序的情况下拨打了所有电话,它们运行良好,我能够下载报告。当我尝试连接两个应用程序时会出现此问题...
我可以在这里做什么?