项目中有个需求是:

对于外部提供的前端项目,包含css、js、html、图片等的项目,将这个项目存进数据库,然后iframe中展示html,然后html中引用的js、css等文件

也能从数据库中读取并正确的展现;

所以其实我们这边分为两步:

1)将整个项目,中的所有文件,js、css等都以路径形式存进数据库,路径其实就是js等文件在html中的引用路径;

2)iframe中引用了HTML,然后html中js等文件从数据库读取出来,正确引用;

(其中,参考了博客:

主要是获取路径时,想了好久,restful的表达式中可以正则等等。。

)

我这边只做了第二步,下面是过程+思路:

假设现在要展现这个项目,前端demo项目:

直接打开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.思路是:

  • iframe中src使用路径是:/iframe/包名/路径,根据包名+路径获取文件的二进制流,response根据文件后缀类型设置相应的content-type,
  • html就采用html的contenttype,js文件采用js的contenttype等。。
  • controller中采用restful风格的requestMapping来接受,就能获取到包名、和路径,就能获取文件流了。
  • 值得注意的一点是:iframe里面的文件的引用地址,也会带上/iframe/包名   父路径,这样子页面中的文件引用也能根据包名+路径获取,非常关键。

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中能正确展示:

附:

从后台读取项目文件在前端iframe中展示的更多相关文章

  1. struts2中从后台读取数据到<s:select>

    看到网上好多有struts2中从后台读取数据到<s:select>的,但都 不太详细,可能是我自己理解不了吧!所以我自己做了 一个,其中可能 有很多不好的地方,望广大网友指出 结果如图 p ...

  2. 在iframe中使用cookie需要注意

    cookie的使用早已不新鲜了,但是最近在做项目时还是被坑了一把. 那么接下来让我们来看一下这个"坑"是个什么情况! 前提: 1.现在有两个页面A.html, B.html,同时, ...

  3. Ajax的post方法,模拟 从后台读取数据小demo

    $(document).ready(function() { //定义一个函数 function timer() { $.post("1.json", function(data, ...

  4. 网站静态化处理—web前端优化—中(12)

    网站静态化处理—web前端优化—中(12) Web前端很多优化原则都是从如何提升网络通讯效率的角度提出的,但是这些原则使用的时候还是有很多陷阱在里面,如果我们不能深入理解这些优化原则背后所隐藏的技术原 ...

  5. 关于如何获取iframe中的元素

    今天研究了一下iframe中元素的获取,发现有些地方还是有点坑的. 首先:如果使用纯前端手段,是没有办法获取非同源的iframe中的元素的,后面会提到后端手段 一.同源环境 1.首先在父页面获取ifr ...

  6. 【学习】如何用jQuery获取iframe中的元素

    (我的博客网站中的原文:http://www.xiaoxianworld.com/archives/292,欢迎遇到的小伙伴常来瞅瞅,给点评论和建议,有错误和不足,也请指出.) 说实在的,以前真的很少 ...

  7. 在Bootstrap开发框架的前端视图中使用@RenderPage实现页面内容模块化的隔离,减少复杂度

    在很多开发的场景中,很多情况下我们需要考虑抽象.以及模块化等方面的内容,其目的就是为了使得开发的时候关注的变化内容更加少一些,整体开发更加简单化,从而减少开发的复杂度,在Winform开发的时候,往往 ...

  8. 多个iframe中根据src获取特定iframe并执行操作

    多个iframe中根据src获取特定iframe并执行操作 前言:在项目中做一个批量编辑工单时需要在一大堆的iframe中的某一个iframe里边再用模态框的形式显示编辑区域,然后再在模态框里边加入i ...

  9. Java后台+数据库+Java web前端(新手)

    实现简单页面上对数据的增删改查:Java后台+数据库表+Jsp前端网页设计 这里做一个简单的学生课程信息管理系统,做之前一定要先有自己的思路,要不然对新手来说,很容易乱的. 另有一完整的代码可供参考, ...

随机推荐

  1. Dubbo 只注册,只订阅

    只注册场景: 某一个服务,被注册中心的一些服务依赖,但是该服务不提供给消费者调用,这个时候使用只注册,注册到注册中心,注册中心内部服务可以调用该服务,但是消费者不可以.(这个服务是被调用方) 只订阅场 ...

  2. The current .NET SDK does not support targeting .NET Core 3.0

    编译错误 Severity Code Description Project File Line Suppression StateError NETSDK1045 The current .NET ...

  3. luogu P1162 填涂颜色

    https://www.luogu.org/problem/show?pid=1162 //其实很简单的吧 //就是最外圈加一圈0 ,然后把外圈里面的0都遍历了 //剩下的0 就变成2 就行了 #in ...

  4. 记一次Servlet中getAttribute的错误.

    package com.ykmimi.order.servlet; import java.io.IOException; import javax.servlet.RequestDispatcher ...

  5. 【转载】linux fork死循环炸弹及其预防

    转自linux fork死循环炸弹及其预防 在Linux系统下执行这段代码 :(){ :|:& }:: 就会引起死机,一旦执行起来后,唯一的方法就是重启系统.实际上这段代码是一段无限递归代码, ...

  6. codeforces 354 div2 C Vasya and String 前缀和

    C. Vasya and String time limit per test 1 second memory limit per test 256 megabytes input standard ...

  7. 使用ARouter遇到的坑

    跨模块跳转不能跳转 需要被跳转的模块或者说使用了ARouter注解的模块都要加上这个 dependencies{    annotationProcessor rootProject.ext.arou ...

  8. tenserflow models包的安装

    1.下载 models包 https://github.com/tensorflow/models 2.将models包拷贝到本机Python包的安装地址即可,本机Python包的安装地址的查看方式可 ...

  9. hdu——1873(优先队列)

    看病要排队 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  10. Cookie是什么?从哪来?存在哪?往哪去?

    什么是cookie? cookie最简单的介绍就是服务器返回的一个字符串信息,只不过我们每次请求都需要把它发送给服务器.以AFN和android-async-http为例子,默认都会把cookie自动 ...