从后台读取项目文件在前端iframe中展示
项目中有个需求是:
对于外部提供的前端项目,包含css、js、html、图片等的项目,将这个项目存进数据库,然后iframe中展示html,然后html中引用的js、css等文件
也能从数据库中读取并正确的展现;
所以其实我们这边分为两步:
1)将整个项目,中的所有文件,js、css等都以路径形式存进数据库,路径其实就是js等文件在html中的引用路径;
2)iframe中引用了HTML,然后html中js等文件从数据库读取出来,正确引用;
(其中,参考了博客:
)
我这边只做了第二步,下面是过程+思路:
假设现在要展现这个项目,前端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中展示的更多相关文章
- struts2中从后台读取数据到<s:select>
看到网上好多有struts2中从后台读取数据到<s:select>的,但都 不太详细,可能是我自己理解不了吧!所以我自己做了 一个,其中可能 有很多不好的地方,望广大网友指出 结果如图 p ...
- 在iframe中使用cookie需要注意
cookie的使用早已不新鲜了,但是最近在做项目时还是被坑了一把. 那么接下来让我们来看一下这个"坑"是个什么情况! 前提: 1.现在有两个页面A.html, B.html,同时, ...
- Ajax的post方法,模拟 从后台读取数据小demo
$(document).ready(function() { //定义一个函数 function timer() { $.post("1.json", function(data, ...
- 网站静态化处理—web前端优化—中(12)
网站静态化处理—web前端优化—中(12) Web前端很多优化原则都是从如何提升网络通讯效率的角度提出的,但是这些原则使用的时候还是有很多陷阱在里面,如果我们不能深入理解这些优化原则背后所隐藏的技术原 ...
- 关于如何获取iframe中的元素
今天研究了一下iframe中元素的获取,发现有些地方还是有点坑的. 首先:如果使用纯前端手段,是没有办法获取非同源的iframe中的元素的,后面会提到后端手段 一.同源环境 1.首先在父页面获取ifr ...
- 【学习】如何用jQuery获取iframe中的元素
(我的博客网站中的原文:http://www.xiaoxianworld.com/archives/292,欢迎遇到的小伙伴常来瞅瞅,给点评论和建议,有错误和不足,也请指出.) 说实在的,以前真的很少 ...
- 在Bootstrap开发框架的前端视图中使用@RenderPage实现页面内容模块化的隔离,减少复杂度
在很多开发的场景中,很多情况下我们需要考虑抽象.以及模块化等方面的内容,其目的就是为了使得开发的时候关注的变化内容更加少一些,整体开发更加简单化,从而减少开发的复杂度,在Winform开发的时候,往往 ...
- 多个iframe中根据src获取特定iframe并执行操作
多个iframe中根据src获取特定iframe并执行操作 前言:在项目中做一个批量编辑工单时需要在一大堆的iframe中的某一个iframe里边再用模态框的形式显示编辑区域,然后再在模态框里边加入i ...
- Java后台+数据库+Java web前端(新手)
实现简单页面上对数据的增删改查:Java后台+数据库表+Jsp前端网页设计 这里做一个简单的学生课程信息管理系统,做之前一定要先有自己的思路,要不然对新手来说,很容易乱的. 另有一完整的代码可供参考, ...
随机推荐
- Dubbo 只注册,只订阅
只注册场景: 某一个服务,被注册中心的一些服务依赖,但是该服务不提供给消费者调用,这个时候使用只注册,注册到注册中心,注册中心内部服务可以调用该服务,但是消费者不可以.(这个服务是被调用方) 只订阅场 ...
- The current .NET SDK does not support targeting .NET Core 3.0
编译错误 Severity Code Description Project File Line Suppression StateError NETSDK1045 The current .NET ...
- luogu P1162 填涂颜色
https://www.luogu.org/problem/show?pid=1162 //其实很简单的吧 //就是最外圈加一圈0 ,然后把外圈里面的0都遍历了 //剩下的0 就变成2 就行了 #in ...
- 记一次Servlet中getAttribute的错误.
package com.ykmimi.order.servlet; import java.io.IOException; import javax.servlet.RequestDispatcher ...
- 【转载】linux fork死循环炸弹及其预防
转自linux fork死循环炸弹及其预防 在Linux系统下执行这段代码 :(){ :|:& }:: 就会引起死机,一旦执行起来后,唯一的方法就是重启系统.实际上这段代码是一段无限递归代码, ...
- 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 ...
- 使用ARouter遇到的坑
跨模块跳转不能跳转 需要被跳转的模块或者说使用了ARouter注解的模块都要加上这个 dependencies{ annotationProcessor rootProject.ext.arou ...
- tenserflow models包的安装
1.下载 models包 https://github.com/tensorflow/models 2.将models包拷贝到本机Python包的安装地址即可,本机Python包的安装地址的查看方式可 ...
- hdu——1873(优先队列)
看病要排队 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- Cookie是什么?从哪来?存在哪?往哪去?
什么是cookie? cookie最简单的介绍就是服务器返回的一个字符串信息,只不过我们每次请求都需要把它发送给服务器.以AFN和android-async-http为例子,默认都会把cookie自动 ...