項目中有個需求是:javascript
對於外部提供的前端項目,包含css、js、html、圖片等的項目,將這個項目存進數據庫,而後iframe中展現html,而後html中引用的js、css等文件css
也能從數據庫中讀取並正確的展示;html
因此其實咱們這邊分爲兩步:前端
1)將整個項目,中的全部文件,js、css等都以路徑形式存進數據庫,路徑其實就是js等文件在html中的引用路徑;java
2)iframe中引用了HTML,而後html中js等文件從數據庫讀取出來,正確引用;jquery
(其中,參考了博客:web
)spring
我這邊只作了第二步,下面是過程+思路:數據庫
假設如今要展示這個項目,前端demo項目:apache
直接打開mobile_nav.html是能訪問的,直接訪問結果:
如今要把htmldemo這個項目存進數據庫,而後再咱們的jsp頁面中iframe中引用mobile_nav.html,也能正確展示。
怎麼作呢?代碼:
1.數據庫表格式:
t_fileinfo:
create table t_fileinfo(
zipname varchar2(200),
filepath varchar2(500),
filecontent blob
);
假設htmldemo中的文件都已經被正確存儲了:
2.showMobile.jsp中建立ifrmae,並引用mobile_nav.html:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>展現iframe中的頁面</title> <style> #iframe{ width: 100%; height: 500px; } </style> </head> <body> <center>展現iframe中的頁面,html頁面從數據庫讀取</center> <iframe id="iframe" src="${pageContext.request.contextPath}/iframe/htmldemo.zip/mobile_nav.html"/> </body> </html>
3.思路是:
4.htmlController:
package com.cy.controller; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.util.AntPathMatcher; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.HandlerMapping; import com.cy.service.HtmlService; /** * 控制展現iframe中的HTML頁面 * @author CY * */ @Controller public class HtmlController { private static Logger logger = Logger.getLogger(HtmlController.class); @Autowired private HtmlService htmlService; /** * 對於iframe/path開頭的url的處理 */ @RequestMapping("/iframe/{zipName}/**") public void iframeRequest(@PathVariable("zipName") String zipName, HttpServletResponse response, HttpServletRequest request) { String filePath = extractPathFromPattern(request); logger.info("---->>>zipName:"+zipName); logger.info("---->>>filePath:"+filePath); byte[] fileContent = htmlService.getFileContent(zipName, filePath); String contentType = htmlService.getContentType(filePath); //把html等文件寫出去; response.setContentType(contentType); response.setCharacterEncoding("utf-8"); //有些引用的多餘,例如bootstrap/bootstrap.min.css.map、jquery/jquery.min.map就會報空指針異常 if(fileContent!=null){ try{ InputStream picture = new ByteArrayInputStream(fileContent); OutputStream outputStream=response.getOutputStream(); int len = 0; byte[] buf = new byte[1024]; while((len = picture.read(buf,0,1024)) != -1){ outputStream.write(buf, 0, len); } outputStream.close(); }catch (IOException e) { e.printStackTrace(); } } } // 把指定URL後的字符串所有截斷當成參數 // 這麼作是爲了防止URL中包含中文或者特殊字符(/等)時,匹配不了的問題 private static String extractPathFromPattern( final HttpServletRequest request) { String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE); String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); return new AntPathMatcher().extractPathWithinPattern(bestMatchPattern, path); } /* @RequestMapping("/iframe/{zipName}/{filePath:.+}") public void iframeRequest(@PathVariable("zipName") String zipName, @PathVariable("filePath") String filePath, HttpServletResponse response) { logger.info("---->>>zipName:"+zipName); logger.info("---->>>filePath:"+filePath); byte[] fileContent = htmlService.getFileContent(zipName, filePath); //把html頁面寫出去; response.setContentType("text/html"); response.setCharacterEncoding("utf-8"); try{ InputStream picture = new ByteArrayInputStream(fileContent); OutputStream outputStream=response.getOutputStream(); int len = 0; byte[] buf = new byte[1024]; while((len = picture.read(buf,0,1024)) != -1){ outputStream.write(buf, 0, len); } outputStream.close(); }catch (IOException e) { e.printStackTrace(); } }*/ }
htmlService:
package com.cy.service; import java.util.HashMap; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.cy.dao.HtmlMapper; import com.cy.model.FileInfo; @Service public class HtmlService { @Autowired private HtmlMapper htmlMapper; /** * 根據文件zip、文件名、文件path,獲取fileContent * @return */ public byte[] getFileContent(String zipName, String filePath){ byte[] b = null; FileInfo fi = htmlMapper.getFileContent(zipName, filePath); if(fi!=null){ b = fi.getFileContent(); } return b; } /** * 根據文件後綴名拿到文件的ContentType * @param filePath * @return */ @SuppressWarnings("serial") public String getContentType(String filePath){ int pos = filePath.lastIndexOf("."); String suffix = filePath.substring(pos+1); String contentType = "application/octet-stream"; //默認二進制流數據類型; Map<String, String> contentMap = new HashMap<String, String>(){ { put("html", "text/html"); put("jpg", "image/jpeg"); put("png", "image/png"); put("css", "text/css"); put("js", "application/x-javascript"); } }; for(Map.Entry<String, String> entry : contentMap.entrySet()){ if(entry.getKey().equals(suffix)){ contentType = entry.getValue(); break; } } return contentType; } }
HtmlMapper:
package com.cy.dao; import org.apache.ibatis.annotations.Param; import com.cy.model.FileInfo; public interface HtmlMapper { public FileInfo getFileContent(@Param("zipName")String zipName, @Param("filePath")String filePath); }
HtmlMapper.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.cy.dao.HtmlMapper" > <select id="getFileContent" resultType="com.cy.model.FileInfo"> select * from t_fileInfo where zipName=#{zipName} and filePath=#{filePath} </select> </mapper>
FileInfo.java:(model):
package com.cy.model; /** * 項目每一個文件實體類 * @author CY * */ public class FileInfo { private String zipName; private String filePath; private byte[] fileContent; public String getZipName() { return zipName; } public void setZipName(String zipName) { this.zipName = zipName; } public String getFilePath() { return filePath; } public void setFilePath(String filePath) { this.filePath = filePath; } public byte[] getFileContent() { return fileContent; } public void setFileContent(byte[] fileContent) { this.fileContent = fileContent; } }
測試:
輸入url後,iframe中能正確展現:
附: