zoukankan      html  css  js  c++  java
  • 从后台读取项目文件在前端iframe中展示

    项目中有个需求是:

    对于外部提供的前端项目,包含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>
    View Code

    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;
        }
    }
    View Code

    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);
    }
    View Code

    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>
    View Code

    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;
        }
        
        
    }
    View Code

    测试:

    输入url后,iframe中能正确展示:

    附:

  • 相关阅读:
    ajax发送请求
    Canvas与SVG的区别
    jquery中attr()和prop()方法的区别
    ab(Apache Benchmark)测试工具的安装
    Nginx与阻塞操作
    构造函数调用顺序
    对一个类求sizeof,虚继承
    代码清单16-4 服务器压力测试程序
    libevent源码分析-TCP服务端代码
    Linux内核源码之红黑树
  • 原文地址:https://www.cnblogs.com/tenWood/p/8025311.html
Copyright © 2011-2022 走看看