实现使用struts2框架访问jar包中的jsp方案
2014-02-25 16:40
671 查看
因公司使用的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();
}
第一种方案:使用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();
}
相关文章推荐
- Struts详解之Action类
- 转载一遍Java规范
- 8.8.5: spring整合jpa---使用声明式事务
- 8.8.4: spring整合jpa---借助jpadaosupport实现dao组件
- 8.8.3: spring整合jpa---使用jpacallback
- SpringMVC-Mybatis-Maven项目整合
- 深入理解java的finalize
- 8.8.2: spring整合jpa---使用jpatemplate
- 8.8.1: spring整合jpa---管理entitymanager
- 8.7.7: Spring整合Hibernate---使用声明式事务
- 8.7.6: Spring整合Hibernate---使用IoC容器组装各种组件
- 8.7.5: Spring整合Hibernate---实现DAO组件
- 8.7.4: Spring整合Hibernate---使用HibernateCallback
- 8.7.3: Spring整合Hibernate---使用HibernateTemplate
- 8.7.2: Spring整合Hibernate---管理Hibernate的SessionFactory
- 8.7.1: Spring整合Hibernate---Spring提供的DAO支持
- Struts2注解使用说明
- 8.6.4: Spring整合Struts2---使用自动装配
- 8.6.3: Spring整合Struts2---让Spring管理控制器
- jdk与openjdk的区别