本篇博客解决上篇博客 采用Rhino在JAVA中运行JavaScript 中提到的问题,即在执行cx.evaluateReader(scope, in, f, 1, null)时报出的数组越界的异常问题。
由于Rhino是开源的,所以将工程中的rhino-1.7.7.1.jar文件由源码替换后,加断点调试发现,当代码执行到如下图所示代码时,在获取org包时报错
在往深处调试,正在报错的语句为如下图:
servlet中在加载org包时,报StringIndexOutOfBoundsException:String index out of range:3错误,解决方法是如上图最后一个catch语句捕获StringIndexOutOfBoundsException该错误即可,便能解决这个问题
下面将导出word的servlet类贴与此处:
package com.rhino.servlet;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ContextFactory;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import com.rhino.test.ExtendUtil;
import net.sf.json.JSONArray;
/**
* Servlet implementation class ExportWordServlet
*/
@WebServlet("/ExportWordServlet")
public class ExportWordServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* Default constructor.
*/
public ExportWordServlet() {
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Context cx = ContextFactory.getGlobal().enterContext();
Scriptable scope = cx.initStandardObjects(null);
cx.setOptimizationLevel(-1);
cx.setLanguageVersion(Context.VERSION_1_8);
String[] file = { "/lib/env.rhino.1.2.js", "/lib/jquery.js" ,"/lib/batchExportWord.js"};
String exportContext = "";
try {
ScriptableObject.defineClass(scope, ExtendUtil.class);
} catch (IllegalAccessException e1) {
e1.printStackTrace();
} catch (InstantiationException e1) {
e1.printStackTrace();
} catch (InvocationTargetException e1) {
e1.printStackTrace();
}
ExtendUtil util = (ExtendUtil) cx.newObject(scope, "util");
scope.put("util", scope, util);
for (String f : file) {
try {
FileReader in = null;
in = new FileReader(ExportWordServlet.class.getResource("/").toString().substring(6)+"/com/rhino/test/"+f);
cx.evaluateReader(scope, in, f, 1, null);
if(f.equalsIgnoreCase("/lib/batchExportWord.js")){
String jsFunction = "exportWord";
Object fObj = scope.get(jsFunction, scope);
if (!(fObj instanceof Function)) {
System.out.println("找不到方法" +jsFunction);
} else {
String jsonStr ="{name:'张三',sex:'男',birthday:'1981.10',faceImg:'./img/face.jpg'fullTimeSchooling:{academicQualification:'大学本科',degree:'工学学士',university:'成都信息工程学院银杏酒店管理学院',major:'科学社会主义与国际共产主义运动'}";
Object functionArgs[] = {jsonStr};
Function fo = (Function)fObj;
Object result = fo.call(cx, scope, scope, functionArgs);
exportContext = Context.toString(result);
String filename=URLEncoder.encode("干部任免审批表","utf-8"); //解决中文文件名下载后乱码的问题
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Disposition","attachment; filename="+filename+".doc");
//获取响应报文输出流对象
ServletOutputStream out =response.getOutputStream();
//输出
out.write(exportContext.getBytes());
out.flush();
out.close();
}
}
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
在batchExportWord.js的exportWord函数中,需要将所传如的字符串转变成json格式的,js中string转json使用eval函数即可,即jsonData = eval('('+jsonStr+'));即可
在Rhino中要能使用jQuery需要引入env.rhino.1.2.js,可以从此下载。
本文介绍如何解决在使用Rhino执行JavaScript时遇到的数组越界异常问题,并提供了一个具体的Servlet示例,展示了如何通过捕获特定异常来规避此问题。
366

被折叠的 条评论
为什么被折叠?



