实现使用struts2框架访问jar包中的jsp方案

本文介绍了两种尝试通过Struts2框架访问jar包内jsp页面的方案。第一种方案利用struts2-embeddedjsp-plugin,但遇到了中文乱码和资源引入问题。解决乱码问题后,由于不适合底层通用jar包,放弃了此方案。第二种方案是启动时解压jsp到目录,通过web.xml配置servlet实现,解决了访问和解压问题,但可能影响性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     因公司使用的eadp底层jar包拓展需求,欲将success,error等公共jsp页面封装到底层jar包, 这样公用jsp就不会被变更.

     第一种方案:使用struts2提供的struts2-embeddedjsp-plugin-2.3.3.jar 通过引入该jar包 配置struts.xm已达到l直接访问jsp

                    参考网址: https://cwiki.apache.org/confluence/display/WW/Embedded+JSP+Plugin  该网址有简单的配置说明,但使用该方法会出现几点问题,第一个是直接输出中文乱码, 第二个是如何引入jar包中相关的js、css、图片等信息  

                    第一个问题直接输出中文乱码的问题,由几个方面决定,文件编码的格式 及tomcat中的server.xml默认的编码以及jsp中的<@page   > jsp本身就是一个servlet输出.一般jsp都是访问时tomcat通过pageEncoding="UTF-8"进行编译  浏览器是由contentType="text/html; charset=UTF-8" 编码格式解析中文.但通过配置以上几个参数统一为gbk及utf-8, 均不能使输出中文恢复正常,该jar包在编译jar包中jsp时都是使用utf-8来进行编码,使用gbk来进行解码,所以导致乱码,最后通过<%String str1=new String("测试弹出".getBytes("utf-8"),"utf-8");%>  <h3><%=new String(str.getBytes("gbk"),"utf-8") %></h3> 直接对该中文进行输出,则乱码问题解决. 后折磨了三天,想通过比较简单的配置达到这个目的,通过插入jsp表达式<%response.setHeader("content-type","text/html;charset=UTF-8");response.setContentType("text/html;charset=UTF-8");response.setCharacterEncoding("UTF-8"); request.setCharacterEncoding("UTF-8"); out.print("登录信息7");%> 以及在web.xml调用相关的encodingFilter等方法. 都没有任何起色, 只能使用直接输出new String(str.getBytes("gbk"),"utf-8") 解码这种方法来实现,但该方法不适合在底层通用的jar包中使用, 故暂时放弃该方案.  

                    第二个问题引入jar包中相关的js和css 直接引入相关的js和css无论绝对路径和相对路径都会失败,只能通过调用servlet来拿到相关的文件.在web.xml中配置相关的servlet

<servlet> 
        <servlet-name> javascriptservlet </servlet-name> 
        <servlet-class> example.JavaScriptServlet </servlet-class> 
    </servlet> 
    <servlet-mapping> 
        <servlet-name> javascriptservlet </servlet-name> 
        <url-pattern> *.js </url-pattern> 
    </servlet-mapping> 

public void doGet(HttpServletRequest request,HttpServletResponse response)throws
                     ServletException,IOException { 
            String fileUri = request.getRequestURI(); 
            String contextPath = request.getContextPath(); 
            if(!contextPath.endsWith( "/ ")){ 
                  contextPath = contextPath + "/ "; 
            } 
            fileUri = fileUri.substring(contextPath.length()-1,fileUri.length());


            //注意:此处未考虑并发访问异常 
            BufferedReader in = new BufferedReader(new InputStreamReader(getClass().
                             getClassLoader().getResourceAsStream(fileUri))); 
            
            PrintWriter out = response.getWriter(); 


            response.setContentType("text/javascript;charset=UTF-8"); 
            String line = null; 
            while((line = in.readLine()) != null){ 
                 out.println(line); 
            } 


            in.close(); 
            out.close(); 
    } 

 在jsp页面中配置引入 <script src="script/jquery.js"></script> 

css及图片也是如此实现,但会影响性能


第二种方案 是想通过tomcat启动时候直接将jsp解压到相关的目录下, 该方案一共有两个难点,第一个是怎么拿到要解压的jar包 第二个是怎么只解压出jsp. 

                 配置web.xml

<servlet>   
     <servlet-name> MyServlet </servlet-name>   
     <servlet-class> read.ReadJarServlet </servlet-class>   
     <load-on-startup> 1 </load-on-startup>   
   </servlet>   
   <servlet-mapping>   
     <servlet-name> MyServlet </servlet-name>   
     <url-pattern> /read/* </url-pattern>   
   </servlet-mapping>

当tomcat启动时会访问该servlet  将servlet封装到eadp,jar包中 拿到该包的路径,通过解压约定的jsp目录达到解压的目的. 以下是实现代码

public void init() throws ServletException {

//jar包的路径
String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile();

Date d = new Date(); 

String outputPath=path.substring(0,path.indexOf("WEB-INF"));

//String outputPath = "D:/apache-tomcat-6.0.35/webapps/blank/"; 
try 

   //执行解压 
decompress(path, outputPath); 
System.out.println("Extracting  OK!"); 
}catch(IOException e) 

e.printStackTrace(); 
System.out.println("Extracting File Failed!"); 
dealError(outputPath); 
System.out.println("Installing Portal Failed"); 
return; 



String systemName = System.getProperty("os.name"); 
System.out.println("System is " + systemName); 
       //如果是unix系列操作系统则赋予用户可执行权限 
if(!systemName.toLowerCase().contains("windows")) 

   System.out.println("Start Granting User Excecute Rights......"); 
   try{ 
   Process p1 = Runtime.getRuntime().exec("chmod +x portal.sh"); 
   p1.waitFor(); 
   Process p2 = Runtime.getRuntime().exec("portal.sh"); 
   p2.waitFor(); 
   System.out.println("Granting User Excecute Rights OK!"); 
   }catch(Exception e) 
   { 
   e.printStackTrace(); 
System.out.println("Granting User Excecute Rights Failed!"); 
dealError(outputPath); 
System.out.println("Installing Portal Failed"); 
return; 
   } 
}
}
/** 
* 解压缩JAR包 
* @param fileName 文件名 
* @param outputPath 解压输出路径 
* @throws IOException IO异常 
*/ 
private void decompress(String fileName, String outputPath) throws IOException{ 


if (!outputPath.endsWith(File.separator)) { 


outputPath += File.separator; 





JarFile jf = new JarFile(fileName); 


for (Enumeration e = jf.entries(); e.hasMoreElements();) 


JarEntry je = (JarEntry) e.nextElement(); 
if(je.getName().indexOf("jspWeb/")!=-1){
String path=je.getName().substring(je.getName().indexOf("jspWeb/")+"jspWeb/".length(),je.getName().length());
String outFileName = outputPath + path;
//String outFileName = outputPath + je.getName(); 
File f = new File(outFileName); 
System.out.println(f.getAbsolutePath()); 


//创建该路径的目录和所有父目录 
makeSupDir(outFileName); 


//如果是目录,则直接进入下一个循环 
if(f.isDirectory()) 

continue; 



InputStream in = null; 
OutputStream out = null; 


try 

in = jf.getInputStream(je); 
out = new BufferedOutputStream(new FileOutputStream(f)); 
byte[] buffer = new byte[2048]; 
int nBytes = 0; 
while ((nBytes = in.read(buffer)) > 0) 

out.write(buffer, 0, nBytes); 

}catch (IOException ioe) 

throw ioe; 
} finally 

try 

if (null != out) 

out.flush(); 
out.close(); 

} catch (IOException ioe) 

throw ioe; 

                  finally 
                  { 
if (null != in) 

in.close(); 


                  } 
}





/** 
* 循环创建父目录 
* @param outFileName 
*/ 
private void makeSupDir(String outFileName) { 
//匹配分隔符 
Pattern p = Pattern.compile("[/\\" + File.separator + "]"); 
Matcher m = p.matcher(outFileName); 
//每找到一个匹配的分隔符,则创建一个该分隔符以前的目录 
while (m.find()) { 
int index = m.start(); 
String subDir = outFileName.substring(0, index); 
File subDirFile = new File(subDir); 
if (!subDirFile.exists()) 
subDirFile.mkdir(); 




/** 
* 递归删除目录及子目录 
* @param path 
*/ 
private void clean(String path) throws IOException 

File file = new File(path); 
//如果该路径不存在 
if(!file.exists()) 

System.out.println(path + " Not Exist!"); 

else 

           //如果是目录,则递归删除 
if(file.isDirectory()) 

String[] fileNames = file.list(); 


if(null == fileNames) 

throw new IOException("IO ERROR While Deleting Files"); 

//如果是空目录则直接删除 
else if(fileNames.length == 0) 

file.delete(); 

else 

for(String fileName:fileNames) 

File subFile = new File(fileName); 
clean(path + File.separator + subFile); 

System.out.println(file.getAbsolutePath()); 
//最后删除父目录 
file.delete(); 



  } 
//如果是文件,则直接删除 
else 

System.out.println(file.getAbsolutePath()); 
file.delete(); 





/** 
* 处理安装错误的异常,调用清洗过程 
* @param outputPath 输出路径 
* @throws IOException IO异常 
*/ 
private  void dealError(String outputPath) 

   //删除已解压的文件 
System.out.println("Start Deleting Files......"); 
try{ 
clean(outputPath); 
System.out.println("Deleting Files OK!"); 
}catch(IOException e) 

   e.printStackTrace(); 
System.out.println("Deleting Files Failed!"); 


public ReadJarServlet() {
super();
}




                 

antlr-2.7.2.jar, aopalliance-1.0.jar, asm-3.3.jar, asm-commons-3.3.jar, asm-tree-3.3.jar, builder-0.6.2.jar, classworlds-1.1.jar, commons-beanutils-1.8.0.jar, commons-chain-1.2.jar, commons-collections-3.2.2.jar, commons-digester-2.0.jar, commons-fileupload-1.3.2.jar, commons-io-2.2.jar, commons-lang-2.4.jar, commons-lang3-3.2.jar, commons-logging-1.1.3.jar, commons-validator-1.3.1.jar, core-0.6.2.jar, dwr-1.1.1.jar, ezmorph-1.0.6.jar, freemarker-2.3.22.jar, google-collections-1.0.jar, google-gxp-0.2.4-beta.jar, guava-r09.jar, jackson-core-asl-1.9.2.jar, jackson-mapper-asl-1.9.2.jar, javassist-3.11.0.GA.jar, jcl-over-slf4j-1.5.8.jar, json-lib-2.3-jdk15.jar, juli-6.0.18.jar, mvel2-2.0.11.jar, ognl-3.0.19.jar, org.apache.felix.framework-4.0.3.jar, org.apache.felix.main-4.0.3.jar, org.apache.felix.shell-1.4.3.jar, org.apache.felix.shell.tui-1.4.1.jar, org.osgi.compendium-4.0.0.jar, org.osgi.core-4.1.0.jar, oro-2.0.8.jar, oval-1.31.jar, plexus-container-default-1.0-alpha-10.jar, plexus-utils-1.2.jar, sitemesh-2.4.2.jar, slf4j-api-1.7.12.jar, spring-aop-3.0.5.RELEASE.jar, spring-asm-3.0.5.RELEASE.jar, spring-beans-3.0.5.RELEASE.jar, spring-context-3.0.5.RELEASE.jar, spring-core-3.0.5.RELEASE.jar, spring-expression-3.0.5.RELEASE.jar, spring-test-3.0.5.RELEASE.jar, spring-web-3.0.5.RELEASE.jar, struts-core-1.3.10.jar, struts2-cdi-plugin-2.3.30.jar, struts2-codebehind-plugin-2.3.30.jar, struts2-config-browser-plugin-2.3.30.jar, struts2-convention-plugin-2.3.30.jar, struts2-core-2.3.30.jar, struts2-dojo-plugin-2.3.30.jar, struts2-dwr-plugin-2.3.30.jar, struts2-embeddedjsp-plugin-2.3.30.jar, struts2-gxp-plugin-2.3.30.jar, struts2-jasperreports-plugin-2.3.30.jar, struts2-javatemplates-plugin-2.3.30.jar, struts2-jfreechart-plugin-2.3.30.jar, struts2-jsf-plugin-2.3.30.jar, struts2-json-plugin-2.3.30.jar, struts2-junit-plugin-2.3.30.jar, struts2-osgi-admin-bundle-2.3.30.jar, struts2-osgi-demo-bundle-2.3.30.jar, struts2-osgi-plugin-2.3.30.jar, struts2-oval-plugin-2.3.30.jar, strut
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值