精华内容
下载资源
问答
  • 星星打分评价页面功能,需求上经常会碰到。网上搜一下,Js + CSS,纯 CSS 的版本也非常多。觉得搜到的都不理想,下意识觉得应该能有更好的实现自己动手尝试一下,果然能更好用所以开篇文章,分享一下 ^_^先来 HTML...

    星星打分评价的页面功能,需求上经常会碰到。

    网上搜一下,Js + CSS,纯 CSS 的版本也非常多。

    觉得搜到的都不理想,下意识觉得应该能有更好的实现

    自己动手尝试一下,果然能更好用

    所以开篇文章,分享一下 ^_^

    先来 HTML 代码感受下

    请打分

    一星

    二星

    三星

    四星

    五星

    只讨论现代浏览器,非现代浏览器请出门左转

    需要的 CSS 基础

    总体没有用到很复杂或者罕见的 CSS 语法,对自己 CSS 水平有自信的可以跳过这一节

    A ~ B MDN 文档:组合器和选择器组

    通用兄弟选择器:匹配B元素,满足条件:B是A之后的兄弟节点中的任意一个(AB有相同的父节点,B在A之后,但不一定是紧挨着A)

    A + B MDN 文档:组合器和选择器组

    相邻兄弟选择器:匹配B元素,满足条件:B是A的下一个兄弟节点(AB有相同的父结点,并且B紧跟在A的后面)

    E:hover MDN 文档::hover()

    鼠标悬停在元素上时提供的样式

    E:checked MDN 文档::checked()

    处于选中状态的元素的样式,单选框,复选框,下拉选择select中的option

    E:not(X) MDN 文档::not()

    匹配不符合参数选择器X描述的元素

    Data Uri MDN 文档:Data URLs

    允许嵌入小文件(通常用来嵌入小图片,但不只是图片哦)

    准备星星资源

    为了 WYCIWYG,我没有用独立图片,通过 Data Uri 是嵌入小图片

    .star input {background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAA8CAYAAABxVAqfAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RjJFRDE5Qjg0NTYwMTFFOTk5QzM5RjY0NTY0MDc0MEUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RjJFRDE5Qjk0NTYwMTFFOTk5QzM5RjY0NTY0MDc0MEUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpGMkVEMTlCNjQ1NjAxMUU5OTlDMzlGNjQ1NjQwNzQwRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpGMkVEMTlCNzQ1NjAxMUU5OTlDMzlGNjQ1NjQwNzQwRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PtLQhvIAAAOnSURBVHja7FdbSBRRGHbKSizKzIzNagnSpBvkbmEPXSiK6Lb0EEJEkkUURNFD0IOvQdAVFgoRErqgQQ/RDYSEjKCLuz5EJElEkZRb2YpGaBe371/+ibPTnHXO3CRw4OPMnDlzvvnPOf/l01KpVM5/dYVisYPAIrvfazZJS9B0AZ+AQDwcHlKdY4zNHz7HbTGw0ReLYW0AzQehK8FWp7y2+IzheQaw3lOLYS2RdJu8+giUqFitavEpST8t/1pPLIa10/kUy673QNCq1SoWnxzm/WxgtS2LYRU95wNkXRBYACwD1gBzLcxH/hwHHgHtwCteiSRWYjCDGGTL0e7jvy3zMNj9Ap4BreQZRHwHN5t9jrgR2uPtwBMfSWux7Lc03ttcNPdVDofN6xhIT6f3WE+L4Xh8LJp7wAaPSA/HQqHo38Ml5mOQ09LfBLa6THoApHUZp9pYCDB5E7DDJdIakDb848dmFQjIae8vA7scku7EnjaacZgSa5pGB24cbn84IG0FKQWeHDOObCFzkkNrl9qN1XMcEk/Gqo23Q7zEhYNVZId4lQvE8+wQuxG/K5SIOYQGskxYD0zjtBnPMk5aleRK+gsl/TeAQ3CTBD9/JbfHj4bRXjNJq+ukhYAkgFSieSx0tQB7QfguS2mkcZK5SoWf8CoPkWvQqsVBbtuAahB2DLeZXGs9wA9QCbSFI18BuRXw2arFeWhmYrI3DrQVZbty4CUsTlkiHlWLo2pxpNXiJSb1XS1OBVZwgeibWoyCpBdts37A/FKLhSBOcj9Fqdt+qMULOilftNRf/FCLRSDuMXwX4XrcM7VYjwn2m2wDrVwPJwVHarGXB5CYew68Ztfpk+0hFw8FnBLLuMpcCVSaZMGIxvXzQx5A12JM/sLluH4EzXlBLZ4wU4vfgFK87HaJVN//TLVoyJ+6Whxg8i6HpFWsw9JqEfNFZadaVIskX+Zj8FubpHs4rKbVIuapyxpAmFxXi3QSF+KjTtVcTf6uq0V832ApcrE/62pxiH03aZF0E5q7olq0HLnYZWqEMb8VDP4pqMVGOyFTVIv9CsSdbqnFNsUkn3BLLTZL9nIWkG+yTQPsjo7V4lNjegSaOPj34/6oiWUtbqjFDiacAlzknFwlfH+Wf6Cag5BIXKFUCHAI1U9nObtVrUEtHud66wp9wv19wG5gAnCdCgQs/TYV4mLhkGRTi/p4mVr8jrETVYhdVYvGImBk1aLk791Si6VU/pjFgT8CDAD9y6CbITrTjwAAAABJRU5ErkJggg==');}

    实际图片:134cf4690ea98386848220141af0e35e.png 宽 30 x 高 60,每个样子的图片 30 x 30

    注意以下细节要求:(配合CSS)

    1 小图片以列方式竖着依次保存

    2 第一个是选中样子,第2个是未选中样子

    * WYCIWYG :What You Copy Is What You Get

    基本原理

    Q:这个功能最重要最基础的部分是什么呢?

    A:鼠标滑过,星星选中和取消

    .star {

    font-size:30px;

    }

    .star input {

    display:block; /* 和 inline-block 的恶心留白说再见 */

    float:left; /* 多个星星排排坐,肩靠肩 */

    margin:0;padding:0; /* 重置 input 默认样式 */

    width:1em;height:1em; /* em 单位 棒!棒!棒! */

    font:inherit; /* 有这个 em 单位才能棒起来 */

    background:center 0/cover no-repeat; /* 准备好背景样式 */

    outline:0 none transparent; /* 再见! Chrome 的默认黄框框 */

    -webkit-appearance:none;-moz-appearance:none;appearance:none; /* 取消浏览器对 input 的默认渲染 */

    }

    .star input:hover ~ input {

    /*

    样式 .star input 把所有 input 元素 背景图 默认设为了选中样式

    当前 hover 的 input 元素之后的所有兄弟 input 元素,背景图调整为未选中样式

    -----------------

    default | ★★★★★

    hover | ✪

    style | ★★★☆☆

    ---------------------

    Final | ★★★☆☆

    */

    background-position:center -1em;

    }

    /*

    请在这里复制上面那段 data uri 的 CSS 哦,不然没有小星星

    因为有样式优先级,位置错了也可能没有小行星哦

    */

    鼠标滑过,星星变动一目了然

    走过路过动图了解一下(更清楚的展示原理)

    5255bb4365e1950f1dfd31a6fa22eb8c.png

    But:鼠标没放上去的时候是全选中的星星? [黑人问号???]

    这部分只是基本原理,下面 实现详解 解决所有问题

    实现详解

    1 解决鼠标没放上去的时候是全选中的星星

    在最前面增加一个 input ,表示为 `0星`,这个 `0星` input 可以隐藏不显示

    为了演示,这个章节里不隐藏 `0星` input

    2 增加 星星对应文本

    每个 input 后面增加对应用 label 包起来的文本

    input `float:left` label `float:right`

    05d590491f014b7670cacfffcebd1ba5.png

    .star {

    /* 基本原理 已有注释 */

    display:inline-block;height:1em;line-height:1em;font-size:30px;

    }

    .star input {

    /* 基本原理 已有注释 */

    display:block;float:left;margin:0;padding:0;width:1em;height:1em;font:inherit;background:center 0/cover no-repeat;outline:0 none transparent;

    -webkit-appearance:none;

    -moz-appearance:none;

    appearance:none;

    }

    .star input:first-child {

    /* 为了演示效果,不隐藏,但恢复浏览器渲染 */

    -webkit-appearance:radio;

    -moz-appearance:radio;

    appearance:radio;

    }

    .star input:checked ~ input {

    /* Style [C]

    已选中的 input 元素之后的所有兄弟 input 元素,背景图调整为未选中样式

    ---------------------

    default | ★★★★★

    checked | ✪

    style [C] | ★★☆☆☆

    ---------------------

    Final | ★★☆☆☆

    */

    background-position:center -1em;

    }

    .star:hover input:checked ~ input {

    /* Style [HC]

    鼠标悬浮在 star 元素上时,已选中的 input 元素之后的所有兄弟 input 元素,背景图调整为选中样子

    主要作用,覆盖上一条,将 input 元素 背景图全部恢复到 选中样子

    -----------------

    default | ★★★★★

    checked | ✪

    style [C] | ★★☆☆☆

    hover | ✪

    style [HC] | ★★★★★

    ---------------------

    Final | ★★★★★

    */

    background-position:center 0;

    }

    .star:hover input:hover ~ input {

    /* Style [HH]

    基本原理 已有注释

    -----------------

    default | ★★★★★

    checked | ✪

    style [C] | ★★☆☆☆

    hover | ✪

    style [HC] | ★★★★★

    style [HH] | ★★★★☆

    ---------------------

    Final | ★★★★☆

    */

    background-position:center -1em;

    }

    /* label 部分参照上面 inpu 的样式,试着自己理解 */

    .star label {display:none;float:right;}

    .star input:checked + label {display:block;}

    .star:hover input:checked + label {display:none;}

    .star:hover input:hover + label {display:block;}

    /*

    请在这里复制上面那段 data uri 的 CSS 哦,不然没有小星星

    因为有样式优先级,位置错了也可能没有小行星哦

    */

    请打分

    一星

    二星

    三星

    四星

    五星

    More 6666 ~~~

    更多选择,更多欢乐 :)

    1 只能选一次,选完之后不能重新选择

    /* pointer-events 请自行搜索了解 */

    .star-once input:first-child:not(:checked) ~ input {background-position:center 0;pointer-events:none;}

    .star-once input:not(:first-child):checked ~ input {background-position:center -1em;}

    .star-once input:first-child:not(:checked) ~ label {display:none;}

    .star-once input:not(:first-child):checked + label {display:block;}

    2 已有默认选择,锁定只读,不能更改,用来展示

    /* pointer-events 请自行搜索了解 */

    .star-lock {pointer-events:none;}

    3 多种尺寸只要修改 star 上的字体大小

    /*

    除了 star 其他都是 em 单位,背景图用了 cover

    自由缩放,轻松愉快哦

    */

    .star {font-size:50px;}

    a8315da8b25695550cc1f95a8064f6d0.png

    完整代码

    Star

    .star {position:relative;display:inline-block;line-height:1em;}

    .star input {display:block;float:left;margin:0;padding:0;width:1em;height:1em;font:inherit;background:center 0/cover no-repeat;outline:0 none transparent;

    -webkit-appearance:none;

    -moz-appearance:none;

    appearance:none;

    }

    .star label {display:none;float:right;margin-left:0.5em;}

    .star input:first-child {

    display:none;

    /* -webkit-appearance:radio;-moz-appearance:radio;appearance:radio; */

    }

    .star input:checked ~ input {background-position:center -1em;}

    .star:hover input:checked ~ input {background-position:center 0;}

    .star:hover input:hover ~ input {background-position:center -1em;}

    .star input:checked + label {display:block;}

    .star:hover input:checked + label {display:none;}

    .star:hover input:hover + label {display:block;}

    .star-once input:first-child:not(:checked) ~ input {background-position:center 0;pointer-events:none;}

    .star-once input:not(:first-child):checked ~ input {background-position:center -1em;}

    .star-once input:first-child:not(:checked) ~ label {display:none;}

    .star-once input:not(:first-child):checked + label {display:block;}

    .star-lock {pointer-events:none;}

    /*

    以上的 css 可写入统一样式表

    以下的样式 可在用的地方分别处理,自定义 大小,星星图片

    */

    .star {font-size:30px;}

    .star input {background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAA8CAYAAABxVAqfAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RjJFRDE5Qjg0NTYwMTFFOTk5QzM5RjY0NTY0MDc0MEUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RjJFRDE5Qjk0NTYwMTFFOTk5QzM5RjY0NTY0MDc0MEUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpGMkVEMTlCNjQ1NjAxMUU5OTlDMzlGNjQ1NjQwNzQwRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpGMkVEMTlCNzQ1NjAxMUU5OTlDMzlGNjQ1NjQwNzQwRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PtLQhvIAAAOnSURBVHja7FdbSBRRGHbKSizKzIzNagnSpBvkbmEPXSiK6Lb0EEJEkkUURNFD0IOvQdAVFgoRErqgQQ/RDYSEjKCLuz5EJElEkZRb2YpGaBe371/+ibPTnHXO3CRw4OPMnDlzvvnPOf/l01KpVM5/dYVisYPAIrvfazZJS9B0AZ+AQDwcHlKdY4zNHz7HbTGw0ReLYW0AzQehK8FWp7y2+IzheQaw3lOLYS2RdJu8+giUqFitavEpST8t/1pPLIa10/kUy673QNCq1SoWnxzm/WxgtS2LYRU95wNkXRBYACwD1gBzLcxH/hwHHgHtwCteiSRWYjCDGGTL0e7jvy3zMNj9Ap4BreQZRHwHN5t9jrgR2uPtwBMfSWux7Lc03ttcNPdVDofN6xhIT6f3WE+L4Xh8LJp7wAaPSA/HQqHo38Ml5mOQ09LfBLa6THoApHUZp9pYCDB5E7DDJdIakDb848dmFQjIae8vA7scku7EnjaacZgSa5pGB24cbn84IG0FKQWeHDOObCFzkkNrl9qN1XMcEk/Gqo23Q7zEhYNVZId4lQvE8+wQuxG/K5SIOYQGskxYD0zjtBnPMk5aleRK+gsl/TeAQ3CTBD9/JbfHj4bRXjNJq+ukhYAkgFSieSx0tQB7QfguS2mkcZK5SoWf8CoPkWvQqsVBbtuAahB2DLeZXGs9wA9QCbSFI18BuRXw2arFeWhmYrI3DrQVZbty4CUsTlkiHlWLo2pxpNXiJSb1XS1OBVZwgeibWoyCpBdts37A/FKLhSBOcj9Fqdt+qMULOilftNRf/FCLRSDuMXwX4XrcM7VYjwn2m2wDrVwPJwVHarGXB5CYew68Ztfpk+0hFw8FnBLLuMpcCVSaZMGIxvXzQx5A12JM/sLluH4EzXlBLZ4wU4vfgFK87HaJVN//TLVoyJ+6Whxg8i6HpFWsw9JqEfNFZadaVIskX+Zj8FubpHs4rKbVIuapyxpAmFxXi3QSF+KjTtVcTf6uq0V832ApcrE/62pxiH03aZF0E5q7olq0HLnYZWqEMb8VDP4pqMVGOyFTVIv9CsSdbqnFNsUkn3BLLTZL9nIWkG+yTQPsjo7V4lNjegSaOPj34/6oiWUtbqjFDiacAlzknFwlfH+Wf6Cag5BIXKFUCHAI1U9nObtVrUEtHud66wp9wv19wG5gAnCdCgQs/TYV4mLhkGRTi/p4mVr8jrETVYhdVYvGImBk1aLk791Si6VU/pjFgT8CDAD9y6CbITrTjwAAAABJRU5ErkJggg==');}

    star 

    请打分

    一星

    二星

    三星

    四星

    五星

    once 

    请打分

    一星

    二星

    三星

    四星

    五星

    lock 

    请打分

    一星

    二星

    三星

    四星

    五星

    展开全文
  • 最终选取的方案代码细节不足之处可选方案及评价从以下三个方面考虑:页面效果还原程度是否支持复杂html/js解析中文字体显示效果JEditorPane首先找到的方案是使用java内置的Html解释工具javax.swing.JEditorPane。...

    Java图片处理:网页转图片

    需求来源于前端同事跟我反馈整天调试布局样式很难受,希望能有服务端网页转图片的方法。 记录一下研究过程。

    可选方案及评价。

    最终选取的方案

    代码细节

    不足之处

    可选方案及评价

    从以下三个方面考虑:

    页面效果还原程度

    是否支持复杂html/js解析

    中文字体显示效果

    JEditorPane

    首先找到的方案是使用java内置的Html解释工具javax.swing.JEditorPane。

    public void testHtml2Image() throws Exception

    {

    String html = "贝叶斯统计推断贝叶斯统计推断

    最大后验概率MAP

    最小均方误差LMS1.最大后验概率是在观测条件x下,寻求待估量最可能的值作为估计值,即最大后验概率时的值。

    2.最小均方误差是在观测条件x下,以待估量的均值作为估计值。";

    JEditorPane editPane = new JEditorPane("text/html", html);

    editPane.setEditable(false);

    Dimension prefSize = editPane.getPreferredSize();

    BufferedImage img = new BufferedImage(prefSize.width,prefSize.height, BufferedImage.TYPE_INT_ARGB);

    Graphics graphics = img.getGraphics();

    editPane.setSize(prefSize);

    editPane.paint(graphics);

    graphics.dispose();

    ImageIO.write(img, "png", new File("/Users/yourname/Documents/work/temp/20190219.png"));

    }

    这是最简单的HTML代码了,但显示效果却不太好,如下图所示:

    6555eb8bc8fd6049946db48287eb32be.png

    而且多尝试后发现JeditorPane解析稍微复杂一点的js页面就会出错。

    html2image

    这是百度来的,从maven上可以搜索到,下载之后发现其内部就是调用JEditorPane,只是作了简单的封装,同样不满意。

    wkhtmltox

    这是在StackOverFlow上搜索Html2Image时看到的一种方案。尝试以后,效果强于JEditorPane,考虑试用。如谷歌首页转化如下:

    最终选取方案

    wkhtmltox在三个方面均强于JEditorPane。wkhtmltox没有java版本,采用java代码调用linux命令的方式使用该工具包。

    wkhtmltox分为wkhtmltoimage 和wkhtmltopdf,经过尝试wkhtmltoimage显示效果不太好,且可调参数较少。而wkhtmltopdf转化效果相当好,因此最终解决方案:

    Created with Raphaël 2.2.0 html字符 pdf image 优化image

    其中生成pdf使用wkhtmltopdf,pdf转化image使用pdfbox(apache出品,放心使用,效果也相当好).wkhtmltopdf是将整个浏览器显示效果转为为pdf,所以对于一些没有铺满整个浏览器的网页,此时的pdf含有一部分无用的空白,应当去掉。

    先看最终效果:

    bca8912439e28faec3e4c322fac09cf1.png

    代码

    安装wkhtmltox

    在https://wkhtmltopdf.org/下载安装。linux系统可使用wget下载。

    安装成功测试命令:

    wkhtmltopdf http://google.com google.pdf

    帮助文档:

    wkhtmltopdf -H

    wkhtmltoimage -H

    代码

    命令:

    wkhtmltopdf --javascript-delay 1000 -B 0mm -L 0mm -R 0mm -T 0mm url qptest.pdf

    说明:javascript-delay是指最多等待js加载1000ms;B\L\R\T参数均是与生成的pdf文件的边距有关,可自行尝试。

    对应上面流程图的方法调用:

    html->htmlToPdf()->pdfToImage()->cutOffInvliadPart()->image

    代码实现:

    package test.java.com.action;

    import java.awt.image.BufferedImage;

    import java.io.File;

    import java.io.FileOutputStream;

    import java.io.IOException;

    import javax.imageio.ImageIO;

    import org.apache.pdfbox.pdmodel.PDDocument;

    import org.apache.pdfbox.pdmodel.encryption.InvalidPasswordException;

    import org.apache.pdfbox.rendering.PDFRenderer;

    public class HtmlToImage

    {

    public static void main(String[] args) throws Exception

    {

    Param0 param=new Param0();

    param.setDpi("2");

    param.setJavascriptDelay(1000);

    param.setUrl("https://www.google.com/");

    File pdf=htmlToPdf(param);

    File image=pdfToImage(pdf, param);

    }

    /*

    * 去掉无用的部分(pdf转成的图片有很大一部分是无用的白色背景)

    * 找出图片的有效部分,把有效部分复制到另一张新图上。

    */

    private static BufferedImage cutOffInvliadPart(BufferedImage image)

    {

    int width=image.getWidth();

    int height=image.getHeight();

    //记录原始图片每个像素的color

    int[][] rgbs=new int[width][height];

    //以下是图片有效部分的边界

    int top=height;

    int bottom=0;

    int left=-1;

    int right=-1;

    for (int i = 0; i < width; i++)

    {

    for (int j = 0; j < height; j++)

    {

    int rgb=image.getRGB(i, j);

    rgbs[i][j]=rgb;

    int tempRgb=rgb & 0x00ffffff;

    boolean isWhite=(tempRgb==0x00ffffff);

    if(!isWhite)

    {

    if(j

    {

    top = j ;

    }

    if(j>bottom)

    {

    bottom=j;

    }

    if(left==-1)

    {

    left=i;

    }

    if(i>right)

    {

    right=i;

    }

    }

    }

    }

    //留白

    bottom=(bottom+10)>(height-1)?(height-1):(bottom+10);

    left=(left>1)?(left-1):0;

    System.out.println(String.format("left:%s right:%s top:%s bottom:%s", left,right,top,bottom));

    //像素的坐标是从0算起的,所以宽高要+1.

    BufferedImage newImage = new BufferedImage(right-left+1, bottom-top+1, BufferedImage.TYPE_INT_RGB);

    for (int i = 0; i < width; i++)

    {

    for (int j = 0; j < height; j++)

    {

    if((j>=top) && (j<=bottom) && (i>=left) && (i<=right))

    {

    newImage.setRGB(i-left, j-top, rgbs[i][j]);

    }

    }

    }

    return newImage;

    }

    private static File pdfToImage(File pdf,Param0 param) throws InvalidPasswordException, IOException

    {

    String filePath=System.getProperty("java.io.tmpdir") + "/" + "test" + ".png";

    System.out.println(filePath);

    File file=new File(filePath);

    try

    {

    PDDocument pdDoc=PDDocument.load(pdf);

    PDFRenderer render=new PDFRenderer(pdDoc);

    //1=72 dpi

    BufferedImage image=render.renderImage(0,Float.parseFloat(param.getDpi()));

    BufferedImage newImage = cutOffInvliadPart(image);

    ImageIO.write(newImage, "png", new FileOutputStream(file));

    return file;

    }

    finally

    {

    //如果上传到图片服务器上则删除本地文件

    //if(file!=null && file.exists())

    //{

    //file.delete();

    //}

    if(pdf!=null && pdf.exists())

    {

    pdf.delete();

    }

    }

    }

    private static File htmlToPdf(Param0 param) throws IOException, InterruptedException

    {

    StringBuilder commandBuilder = new StringBuilder();

    if (System.getProperty("os.name").contains("Mac") || System.getProperty("os.name").contains("mac"))

    {

    //我的本地配置

    commandBuilder.append("/usr/local/bin/wkhtmltopdf");

    }

    else

    {

    //服务器配置

    commandBuilder.append("/usr/local/bin/wkhtmltopdf");

    }

    //wkhtmltopdf --javascript-delay 1000 -B 1mm -L 1mm -R 1mm -T 1mm url qptest.pdf

    commandBuilder.append(" --javascript-delay ").append(param.getJavascriptDelay() + " ")

    .append(" -B 0mm -L 0mm -R 0mm -T 0mm ");

    commandBuilder.append(param.getUrl());

    String pdfPath = System.getProperty("java.io.tmpdir") + "/" + "test" + ".pdf";

    File pdf = new File(pdfPath);

    commandBuilder.append(" " + pdfPath);

    String command = commandBuilder.toString();

    System.out.println(command);

    Process process = Runtime.getRuntime().exec(command);

    process.waitFor();

    return pdf;

    }

    /**

    * 外部传入的参数

    */

    private static class Param0

    {

    private String url;

    private String dpi="2";

    private int javascriptDelay=200;

    public String getUrl()

    {

    return url;

    }

    public void setUrl(String url)

    {

    this.url = url;

    }

    public String getDpi()

    {

    return dpi;

    }

    public void setDpi(String dpi)

    {

    this.dpi = dpi;

    }

    public int getJavascriptDelay()

    {

    return javascriptDelay;

    }

    public void setJavascriptDelay(int javascriptDelay)

    {

    this.javascriptDelay = javascriptDelay;

    }

    }

    }

    不足之处

    解决方案有以下不足:

    需要在服务器上安装wkhtmltox

    接口运行速度需要提高

    pdf转图片时只取了第一页,严谨的做法遍历以后拼到一张图上

    展开全文
  • 背景图片超链接:评价5.在js中获取html中表单元素的value值:function show() { alert(document.getElementById("txt").value) }6.在js中打开另一个jsp页面:function to(){window.location.href="in...

    1.点击按钮返回 上一页:

    2.点击按钮跳转到另一个jsp页面:

    3.复选框 :

    保存登录名

    4.背景图片超链接:

    评价

    5.在js中获取html中表单元素的value值:

    function show() { alert(document.getElementById("txt").value ) }

    6.在js中打开另一个jsp页面:

    function to(){ window.location.href="index.jsp"; }

    7.在js中给从表单传过来的中文用户名编码 :

    var username=encodeURI(document.getElementById("username").value);

    8.servlet端处理jsp页面传递过来的中文 :

    String username=URLEncoder.encode(request.getParameter("username"),"utf-8");

    9.js中判断jsp中的复选框 是否被选中:

    if(document.getElementById("checkboxID").checked){ alert("checkbox is checked"); }

    10.由jsp表单向servlet传递中文变量的技巧:

    先在js中处理,然后提交给servlet

    var username='';

    username=encodeURI(username);

    11.单选按钮 的问题:

    学生

    教师

    管理员

    把三个 name 设置一样才可以单选。

    12.js中如何判断单选按钮被选中:

    for(i=0;i

    if(document.form1.place[i].checked)

    {

    alert(document.form1.place[i].value);

    }

    }

    或:var type=document.getElementsByName("cate");

    for(i=0;i

    if(type[i].checked)

    {

    tag=type[i].value;

    }

    }

    13.在servlet中给jsp页面传来的搜索关键字编码 :

    String kw=URLEncoder.encode(request.getParameter("kw"),"utf-8");

    14.分页自增问题:

    要引一下java.lang.*包

    jsp代码:

    15.点击按钮生成一个文本框:

    点我生成一个文本框

    16.js中的字符串分割函数:

    str="2,2,3,5,6,6"; //这是一字符串

    var strs= new Array(); //定义一数组

    strs=str.split (","); //字符分割

    for (i=0;i

    document.write(strs[i]+"
    "); //分割后的字符输出

    }

    17.对文字onclick(点击Test会调用test()函数):

    Test

    18.文本域 :

    您的意见:

    19.js中分割字符串 :

    var a="a?b?c";

    var arr=a.split("?");

    alert(arr[0]);

    20.js中判断变量是否undefined :

    if ( typeof (temp) == "undefined" ){

    alert("undefined" );

    }

    21.获取被选中下拉框 的值:

    请选择...

    alert($("#yewuyuan").find("option:selected").text())

    或:alert($("#yewuyuan option:checked").text());

    $("#yewuyuan ").val();

    22.中文乱码 :

    get请求:

    String  stuname = request.getParameter("stuname");

    String str = new String(stuname.getBytes("ISO-8859-1"),"utf-8")

    post请求:

    request. setCharacterEncoding("UTF-8");

    23.js中获得当前系统时间 :

    var myDate = new Date();

    var mytime=myDate.toLocaleTimeString();

    24.js丢弃小数部分,保留整数部分

    js:parseInt(7/2)

    25.超链接去掉下划线:

    style="text-decoration: none"

    26.table合并行或列:

    星期一菜谱  合并3列成一列素菜茄子扁豆豆腐白菜  合并2行成一行

    27.js正则表达式验证手机号码 :

    var reg =/(^0{0,1}1[3|4|5|6|7|8|9][0-9]{9}$)/;

    if(!reg.test(num1)){

    var mes="您输入的手机号码不正确,请重新输入!";

    $("#mes").html(mes);

    return;

    }

    28.js取整 :

    丢弃小数部分,保留整数部分

    js:parseInt(7/2)

    向上取整,有小数就整数部分加1

    js: Math.ceil(7/2)

    四舍五入

    js: Math.round(7/2)

    向下取整

    js: Math.floor(7/2)

    parseInt(str)

    29.jsp页面添加锚点 :

    A

    A

    30.div中添加滚动条 :

    这里是你要显示的内容

    如果要出现水平滚动条,则: overflow-x:auto

    同理,垂直滚动条为: overflow-y:auto

    31.页面获取回车事件 并提交表单:s

    if (event.keyCode == 13)

    {

    document.getElementById("login").click();

    }

    32.jquery获取table中的值 :

    //点击保存某个答案

    function saveone(obj){

    //序号

    var ide=$(obj).parent().parent().parent().children().eq(0).children().eq(0).children().eq(0).val();

    alert(ide);

    }

    33.jquery获取被选中单选框 的值:

    var myname='key'+myserial;

    alert(myname);

    var thekey=$("input[name='"+myname+"']:checked").val();

    alert(thekey);

    34.jquery获取被选中的复选框 的值:

    $("[name='"+myname+"']:checked").each(function(){

    var i=parseInt($(this).val());

    thekey+=i;

    })

    35.jquery获取table的每一行的第一列 数据

    $("#myques tr").each(function(){

    var $thisTr = $(this);

    var $thisFirstTd = $("td:eq(0)",$thisTr );

    alert($thisFirstTd.text());

    });

    36.jquery获取table的行数

    var t01 = $("#myques tr").length;

    37.jquery给变量id 赋值

    $('#'+id).val(allparams);

    38.fmt 标签:

    展开全文
  • java爬取携程酒店的评价信息以及eleven参数获取

    千次阅读 热门讨论 2018-09-27 16:13:09
    本贴已经无用了,需要爬数据的可以去携程app...访问页面https://m.ctrip.com/webapp/hotel/hoteldetail/dianping/7500321.html?&fr=detail&atime=20190510&days=1 请求地址:https://m.ctrip.com/re...

    本贴已经无用了,需要爬数据的可以去携程app端,未加密可以直接请求接口获取数据 下面给出一个简单的思路:

    访问页面https://m.ctrip.com/webapp/hotel/hoteldetail/dianping/7500321.html?&fr=detail&atime=20190510&days=1

    请求地址:https://m.ctrip.com/restapi/soa2/16765/gethotelcomment?_fxpcqlniredt=09031069110301833861 

    带入json参数  ,参数可以自己去看一下:

    String json = "{\"hotelId\":" + hotelId + ",\"pageIndex\":" + pageIndex + ",\"tagId\":0,\"pageSize\":10,\"groupTypeBitMap\":2,\"needStatisticInfo\":0,\"order\":0,\"basicRoomName\":\"\",\"travelType\":-1,\"head\":{\"cid\":\"09031121310402803767\",\"ctok\":\"\",\"cver\":\"1.0\",\"lang\":\"01\",\"sid\":\"8888\",\"syscode\":\"09\",\"auth\":\"\",\"extension\":[]}}";

    酒店 id 和 pageIndex 传一下就行了

    用httpclient 循环请求该接口 然后 返回字段有个

    当此值为1就说明是最后一一页。爬取的时候注意让程序休眠一会。否则会可能限流以及封ip.

    以下方法已经不可用

    源码可以在我的资源中下载,谢谢!https://download.csdn.net/download/qq_39477018/10764634

    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    import org.jsoup.nodes.Element;
    import org.jsoup.select.Elements;
    import org.springframework.http.*;
    import org.springframework.http.HttpMethod;
    
    import javax.script.Invocable;
    import javax.script.ScriptEngine;
    import javax.script.ScriptEngineManager;
    import javax.script.ScriptException;
    import javax.swing.plaf.metal.OceanTheme;
    import java.io.IOException;
    import java.io.StringReader;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.regex.Matcher;
    
    /**
     * Created by Administrator on 2018/9/28.
     */
    public class GetHotelJudge {
        private static BlockingQueue<Object[]> insertqueuej= new LinkedBlockingQueue<>();//评价
    
        public static void main(String[] args) throws IOException {
    
         //入库操作可根据自己数据库设置
            String sql="insert into hoteljude(HOTELNAME,USERIMG,USERNAME,SCORE,GGSCORE,HOTELTYPE,CHECKINTIME,BADTYPE,JUDGETIME,JUDGEINTRO,JUDGEREPLAY,JUDGEIMG) values(?,?,?,?,?,?,?,?,?,?,?,?)";
            URLDemo2.insert(sql,insertqueuej);
    
            getHotel();
    
        }
    
        public static void   getHotel(){
    
            try {
                String hotelid="441351"; //酒店id
                String uri="http://hotels.ctrip.com/hotel/"+hotelid+".html";
                HttpClient h=new JavaHttpClient();
                HttpResponse  s = h.doGet(uri,null);//可以自己实现get请求链接  或者参考本人的。
                String hotel=s.getResponseString();
                Document doc=Jsoup.parse(hotel);//获取酒店信息
                Element e=doc.selectFirst("#J_htl_info > div.name > h2.cn_n");
                String hotelname=e.text();
                Map cookies=s.getCookies();
                Map head=gethead(hotelid);
                String even=oceanball(hotelid,head,cookies);//获取even
                int currentPage=0;
                getEiinfo(currentPage,hotelid,"",head,even,cookies,hotelname);//获取评价信息
    
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    
    
        //获取评价信息
        public static void getEiinfo(int currentPage,String hotelid,String sub,Map headMap,String eleven,Map cookies, String hotelname){
            try {
                String pl = "http://hotels.ctrip.com/Domestic/tool/AjaxHotelCommentList.aspx?" +
                        "MasterHotelID=" + hotelid + "&hotel=" + hotelid + "&NewOpenCount=0&AutoExpiredCount=0&RecordCount=2365&OpenDate=&keywordPress=1&card=-1&property=-1" +
                        "&UserType=&productcode=&keyword=&roomName=&orderBy=2&currentPage="+currentPage+"&viewVersion=c&contyped=0" +
                        "&eleven="+eleven+"&callback="+getcallback(15)+"&_="+System.currentTimeMillis();
                HttpClient h=new JavaHttpClient();
                HttpResponse r=h.doGet2(pl,headMap,cookies);
                String result=r.getResponseString();
                Document doc=Jsoup.parse(result);
                Element element= doc.selectFirst("#divCtripComment > div.comment_detail_list");//得到所有的评论信息div
                if(element!=null){
                    Elements elements=element.getElementsByClass("comment_block J_asyncCmt");
                    if(elements!=null&&elements.size()>0){
                        for (Element e:elements){
                            Element eltImg=e.selectFirst("div.user_info > p.head > span.img > img");
                            String img=eltImg==null?null:eltImg.attr("src");//用户头像
                            //System.out.println("img:"+img);
                            Element eltName=e.selectFirst("div.user_info > p.name > span");
                            String name=eltName==null?null:eltName.text();//用户名称
                            //System.out.println("name:"+name);
                            Element eltscore=e.selectFirst("div.comment_main > p > span.score > span");
                            String score=eltscore==null?0+"":eltscore.text();//评分总分
                            //System.out.println("score:"+score);
                            Element eltggscore=e.selectFirst("div.comment_main > p > span.small_c");
                            String ggscore=eltggscore==null?null:eltggscore.attr("data-value");//各个维度评分
                            //System.out.println("ggscore:"+ggscore);
                            Element elttype=e.selectFirst("div.comment_main > p > span.type");
                            String type=elttype==null?null:elttype.text();//出游类型
                            //System.out.println("type:"+type);
                            Element elttime=e.selectFirst("div.comment_main > p > span.date");
                            String time=elttime==null?null:elttime.text();//出游时间
                            // System.out.println("time:"+time);
                            Element eltbad=e.selectFirst("div.comment_main > p > a");
                            String bad=eltbad==null?null:eltbad.text();//房型
                            //System.out.println("bad:"+bad);
                            Element eltdate=e.selectFirst("div.comment_main > div.comment_txt > div.comment_bar > p > span");
                            String date=eltdate==null?null:eltdate.text().replace("发表于","");//评论时间
                            //System.out.println("date:"+date);
                            Element eltintro=e.selectFirst("div.comment_main > div.comment_txt > div.J_commentDetail");
                            String intro=eltintro==null?null:eltintro.text();//评论内容
                            System.out.println("intro:"+intro);
                            Element eltreplay=e.selectFirst("div.comment_main > div.htl_reply > p.text");
                            String replay=eltreplay==null?null:eltreplay.text();//酒店回复内容
                            //System.out.println("replay:"+replay);
                            Element picturediv=e.selectFirst("div.comment_main > div > div.comment_pic");
                            String purl="";
                            if(picturediv!=null){
                                Elements picture=picturediv.getElementsByClass("pic");//评论的图集
                                if(picture!=null&&picture.size()>0){
                                    for (Element pic:picture){
                                        Element imgs=pic.selectFirst("img.p");
                                        String url=imgs==null?null:imgs.attr("src");
                                        purl=purl+url+";";
                                        //System.out.println("url:"+url);
                                    }
                                }
                            }
    
                            //组装成对象
                            Object[] o=new Object[12];
                            o[0]=hotelname;
                            o[1]=img;
                            o[2]=name;
                            o[3]=score;
                            o[4]=ggscore;
                            o[5]=type;
                            o[6]=time;
                            o[7]=bad;
                            o[8]=date;
                            o[9]=intro;
                            o[10]=replay;
                            o[11]=purl;
                            insertqueuej.add(o);//加入队列进行入库
    
                        }
                    }
                    Elements adiv=doc.select("#divCtripComment > div.c_page_box > div > div.c_page_list.layoutfix > a");//获取分页信息的a标签
                    int tpage=Integer.parseInt(adiv.last().text());//得到总页数的值
                    Element cPage=doc.selectFirst("#divCtripComment > div.c_page_box > div > div.c_page_list.layoutfix > a.current");//得到当前页的a标签
                    int cpage=Integer.parseInt(cPage.text());//得到当前页的值
                    if (cpage+1<=tpage){//进行循环读取
                   /* try {
                        Thread.sleep(30000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }*/
                        String even=oceanball(hotelid,headMap,cookies);//获取even
                        getEiinfo(cpage+1,hotelid,"",headMap,even,cookies,hotelname);//获取评价信息
                    }
    
                }else{
                    String even=oceanball(hotelid,headMap,cookies);//获取even
                    getEiinfo(currentPage,hotelid,"",headMap,even,cookies,hotelname);//获取评价信息
                }
    
    
                } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    
        /**
         * 请求头设置
         * @param hotelid
         * @return
         */
        public static  Map gethead(String hotelid){
            Map map = new HashMap();
            map.put("Host", "hotels.ctrip.com");
    
            map.put("Accept", "*/*");
            map.put("Cache-Control", "max-age=0");
            map.put("If-Modified-Since", "Thu, 01 Jan 1970 00:00:00 GMT");
            map.put("Content-Type","application/x-javascript; charset=utf-8");
            map.put("Accept-Language", "zh-CN,zh;q=0.8");
            map.put("Referer", "http://hotels.ctrip.com/hotel/" + hotelid + ".html");
            map.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36");
            return  map;
        }
    
        /**
         *  加密
         * @param hotelid
         * @return
         */
        public static String oceanball(String hotelid,Map headMap,Map cookies){
    
            try {
                String callback = getcallback(15);
                HttpClient h=new JavaHttpClient();
                long currtime = System.currentTimeMillis();
                String oceanball = "http://hotels.ctrip.com/domestic/cas/oceanball?callback="+callback+"&_="+currtime+"";
                HttpResponse res=h.doGet2(oceanball,headMap,cookies);
                String ocean = res.getResponseString();
                ocean = ocean.replace("eval","JSON.stringify");
                ScriptEngineManager manager = new ScriptEngineManager();
                ScriptEngine engine = manager.getEngineByName("javascript");
                ocean = String.valueOf( engine.eval(ocean));
                ocean = ocean.replace(callback,"var eleven=" + callback);
                ocean = String.valueOf(engine.eval(new StringReader(ocean)));
                ScriptEngineManager manager1 = new ScriptEngineManager();
                ScriptEngine engine1 = manager1.getEngineByName("javascript");
    
                engine1.eval("var hotel_id = \""+hotelid+"\"; var site = {}; site.getUserAgent = function(){}; var Image = function(){}; var window = {}; window.document = window.document = {body:{innerHTML:\"1\"}, documentElement:{attributes:{webdriver:\"1\"}}, createElement:function(x){return {innerHTML:\"1\"}}}; var document = window.document;window.navigator = {\"appCodeName\":\"Mozilla\", \"appName\":\"Netscape\", \"language\":\"zh-CN\", \"platform\":\"Win\"}; window.navigator.userAgent = site.getUserAgent(); var navigator = window.navigator; window.location = {}; window.location.href = \"http://hotels.ctrip.com/hotel/\"+hotel_id+\".html\"; var location = window.location;" +
                        " var navigator = {userAgent:{indexOf: function(x){return \"1\"}}, geolocation:\"1\"};var getEleven = 'zgs';  " );
                engine1.eval("var "+callback+" = function(a){getEleven = a;};");
                engine1.eval(ocean);
                String eleven = "";
                if (engine instanceof Invocable) {
                    Invocable invocable = (Invocable) engine1;
                    eleven = (String) invocable.invokeFunction("getEleven");//4.使用 invocable.invokeFunction掉用js脚本里的方法,第一個参数为方法名,后面的参数为被调用的js方法的入参
                }
                return eleven;
            } catch (IOException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (ScriptException e) {
                e.printStackTrace();
            }
    
            return null;
        }
    
        /**
         * callback参数获取
         * @param number
         * @return
         */
        public  static String getcallback(int number){
            String s[]={"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};
            String cal="CAS";
            for(int i=0;i<number;i++){
                int t= (int) Math.ceil(51 * Math.random());
                cal=cal+s[t];
            }
           return cal;
        }
    }

    get 或者post 请求代码 好几个类写的比较复杂,可以直接复制使用。

    import javax.net.ssl.*;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.HttpURLConnection;
    import java.net.InetSocketAddress;
    import java.net.Proxy;
    import java.net.URL;
    import java.security.KeyManagementException;
    import java.security.NoSuchAlgorithmException;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * @Author: liaog
     * @Date: 2018-08-01 13:28
     * @description:
     */
    public class JavaHttpClient extends AbstractHttpClient implements HttpClient{
    
        protected String defaultCharset = "utf-8";
    
        protected int timeout = 20000;
    
        protected boolean useProxy;
    
        protected String hostname;
    
        protected int port;
    
        public HttpResponse doRequest(HttpMethod method, String url, Map<String, String> userHeaders, InputStream data,Map<String, String> cookies) throws IOException {
    
            URL urlObject = new URL(url);
            HttpURLConnection urlConnection = openConnection(urlObject);
    
            if (urlObject.getProtocol().equalsIgnoreCase("https")) {
                HttpsURLConnection httpsURLConnection = (HttpsURLConnection) urlConnection;
                prepareForHttps(httpsURLConnection);
            }
            String sessionid="";
            if (cookies != null) {
                for (Map.Entry<String, String> entry : cookies.entrySet()) {
                    //urlConnection.addRequestProperty(entry.getKey(), entry.getValue());
                    sessionid=sessionid+entry.getKey()+"="+entry.getValue()+";";
                }
                urlConnection.addRequestProperty("Cookie", sessionid);
            }
    
            urlConnection.setRequestMethod(method.name());
            urlConnection.setConnectTimeout(timeout);
            urlConnection.setReadTimeout(timeout);
            urlConnection.setInstanceFollowRedirects(false);
            if (userHeaders != null) {
                for (Map.Entry<String, String> entry : userHeaders.entrySet()) {
                    urlConnection.addRequestProperty(entry.getKey(), entry.getValue());
                }
            }
            if (data != null) {
                int len = data.available();
                urlConnection.addRequestProperty("Content-Length", String.valueOf(len));
                urlConnection.setDoInput(true);
                urlConnection.setDoOutput(true);
                OutputStream outputStream = urlConnection.getOutputStream();
                IOUtil.copyAndClose(data, outputStream);
            }
            urlConnection.setInstanceFollowRedirects( false );
            InputStream responseInputStream = urlConnection.getInputStream();
            int responseCode = urlConnection.getResponseCode();
            ByteArrayOutputStream bos = new ByteArrayOutputStream(64);
            IOUtil.copyAndClose(responseInputStream, bos);
    
            Map<String, List<String>> headers = new HashMap<String, List<String>>(urlConnection.getHeaderFields());
            String sessionId = "";
            String cookieVal = "";
            String key = null;
            Map<String,String > map=new HashMap();
            for(int i = 1; (key = urlConnection.getHeaderFieldKey(i)) != null; i++){//获取cookies
                if(key.equalsIgnoreCase("set-cookie")){
                    cookieVal = urlConnection.getHeaderField(i);
                    cookieVal = cookieVal.substring(0, cookieVal.indexOf(";"));
                    String s[]=cookieVal.split("=");
                    map.put(s[0],s[1]);
                    sessionId = sessionId + cookieVal + ";";
                    System.out.println("==="+cookieVal);
                }
            }
           // System.out.println("session"+sessionId);
            String redirect=urlConnection.getHeaderField( "location" );//获得302转发地址
            //System.out.println("location:"+redirect);
            /*if(redirect!=null){
                doRequest(HttpMethod.GET,redirect,userHeaders,null,map);
            }*/
    
            return new HttpResponse(defaultCharset, responseCode, headers, bos.toByteArray(),map);
        }
    
        private HttpURLConnection openConnection(URL url) throws IOException {
            if (isUseProxy()) {
                return (HttpURLConnection)url.openConnection(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(getHostname(), getPort())));
            } else {
                return (HttpURLConnection)url.openConnection();
            }
        }
    
        private void prepareForHttps(HttpsURLConnection httpsURLConnection) {
            try {
                SSLContext sslContext = SSLContext.getInstance("SSL");
                sslContext.init(null, new TrustManager[]{new AbstractHttpClient.TrustAnyTrustManager()}, secureRandom);
                httpsURLConnection.setSSLSocketFactory(sslContext.getSocketFactory());
                httpsURLConnection.setHostnameVerifier(new TrustAnyHostnameVerifier());
            } catch (NoSuchAlgorithmException e) {
                throw new RuntimeException(e);
            } catch (KeyManagementException e) {
                throw new RuntimeException(e);
            }
        }
    
        public String getDefaultCharset() {
            return defaultCharset;
        }
    
        public void setDefaultCharset(String defaultCharset) {
            this.defaultCharset = defaultCharset;
        }
    
        public int getTimeout() {
            return timeout;
        }
    
        public void setTimeout(int timeout) {
            this.timeout = timeout;
        }
    
        public boolean isUseProxy() {
            return useProxy;
        }
    
        public void setUseProxy(boolean useProxy) {
            this.useProxy = useProxy;
        }
    
        public String getHostname() {
            return hostname;
        }
    
        public void setHostname(String hostname) {
            this.hostname = hostname;
        }
    
        public int getPort() {
            return port;
        }
    
        public void setPort(int port) {
            this.port = port;
        }
    }
    

     

     

    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Map;
    
    /**
     * @Author: liaogk
     * @Date: 2018-08-01 13:18
     * @description:
     */
    public interface HttpClient {
    
        HttpResponse doRequest(HttpMethod method, String url, Map<String, String> userHeaders, InputStream data,Map<String,String> cookies)throws IOException;
    
        byte[] doGet(String url) throws IOException;
    
        HttpResponse doGet(String url, Map<String, String> headers) throws IOException;
        HttpResponse doGet2(String url, Map<String, String> headers,Map<String,String> cookies) throws IOException;
        HttpResponse dopost(String url, Map<String, String> headers,InputStream data,Map<String,String> cookies) throws IOException;
    
    }

     

     

    /**
     * @Author: liaogk
     * @Date: 2018-08-01 13:22
     * @description:
     */
    public enum  HttpMethod {
        POST, GET, PUT, DELETE, HEADER, OPTIONS;
    }
    import java.io.UnsupportedEncodingException;
    import java.util.List;
    import java.util.Map;
    
    /**
     * @Author: liaog
     * @Date: 2018-08-01 13:24
     * @description:
     */
    public class HttpResponse {
    
        private int responseCode;
        private Map<String, List<String>> headers;
        private byte[] responseData;
        private String defaultCharset;
        private Map<String ,String> cookies;
    
        public HttpResponse(String defaultCharset, int responseCode, Map<String, List<String>> headers, byte[] responseData,Map<String ,String> cookies) {
            this.defaultCharset = defaultCharset;
            this.responseCode = responseCode;
            this.headers = headers;
            this.responseData = responseData;
            this.cookies = cookies;
        }
    
        public int getResponseCode() {
            return responseCode;
        }
    
        public byte[] getResponseData() {
            return responseData;
        }
    
        public String getResponseString() {
            try {
                return new String(responseData, getResponseCharset());
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException(e);
            }
        }
    
        public List<String> getHeaders(String name) {
            return headers.get(name);
        }
    
        public String getHeader(String name) {
            List<String> theHeaders = getHeaders(name);
            if (theHeaders == null || theHeaders.isEmpty()) {
                return null;
            }
            return theHeaders.get(0);
        }
    
    
        public String getResponseCharset() {
            String contentType = getHeader("Content-Type");
            if (contentType == null || contentType.length() == 0) {
                return defaultCharset;
            }
            String[] parts = contentType.split(";");
            for (String part : parts) {
                part = part.trim();
                String[] kvParts = part.split("=");
                if (kvParts.length < 2) {
                    continue;
                }
                String key = kvParts[0].trim();
                String value = kvParts[1].trim();
                if (key.equals("charset")) {
                    return value;
                }
            }
            return defaultCharset;
        }
    
        public Map<String ,String> getCookies() {
            return cookies;
        }
    
        public void setCookies(Map<String ,String> cookies) {
            this.cookies = cookies;
        }
    }

     

    import java.io.*;
    
    /**
     * @Author: liaog
     * @Date: 2018-08-01 13:39
     * @description:
     */
    public class IOUtil {
    
        private static final int BUF_LEN = 1024 * 8;
        /**
         * 通过threadLocal做cache优化,避免重复申请内存
         */
        private static final ThreadLocal<byte[]> bufTl = new ThreadLocal<byte[]>() {
            @Override
            protected byte[] initialValue() {
                return new byte[BUF_LEN];
            }
        };
    
        private static byte[] getBuf() {
            return bufTl.get();
        }
    
        public static void copyAndClose(InputStream is, OutputStream os) throws IOException {
            byte[] buf = getBuf();
            while (true) {
                int len = is.read(buf);
                if (len < 0) {
                    break;
                }
                os.write(buf, 0, len);
            }
            close(is);
            close(os);
        }
    
        public static byte[] readAsBytes(File file) throws IOException {
            ByteArrayOutputStream bos = new ByteArrayOutputStream(BUF_LEN);
            copyAndClose(readAsStream(file), bos);
            return bos.toByteArray();
        }
    
        public static void writeBytesToFile(File file, byte[] data) throws IOException{
            FileOutputStream fos = new FileOutputStream(file);
            copyAndClose(new ByteArrayInputStream(data), fos);
        }
    
        public static InputStream readAsStream(File file) throws IOException {
            return new FileInputStream(file);
        }
    
        public static void close(Closeable c) {
            if (c != null) {
                try {
                    c.close();
                } catch (Exception e) {
                    // ignore
                }
            }
        }
    
        public static String getFileNameSuffix(String name) {
            if (name == null) {
                return null;
            }
            int pos = name.lastIndexOf('.');
            if (pos < 0) {
                return null;
            }
            return name.substring(pos);
        }
    
    }
    

     

    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.SSLSession;
    import javax.net.ssl.X509TrustManager;
    import java.io.IOException;
    import java.io.InputStream;
    import java.security.SecureRandom;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import java.util.Map;
    
    /**
     * @Author: liaogk
     * @Date: 2018-08-01 13:19
     * @description:
     */
    public abstract class AbstractHttpClient implements HttpClient{
    
        @Override
        public abstract HttpResponse doRequest(HttpMethod method, String url, Map<String, String> userHeaders, InputStream data ,Map<String,String> cookies) throws IOException;
    
        @Override
        public  byte[] doGet(String url) throws IOException {
            return doGet(url, null).getResponseData();
        }
    
        @Override
        public HttpResponse doGet(String url, Map<String, String> headers) throws IOException {
            return doRequest(HttpMethod.GET, url, headers, null,null);
        }
    
    
        @Override
        public HttpResponse doGet2(String url, Map<String, String> headers,Map<String,String> cookies) throws IOException {
            return doRequest(HttpMethod.GET, url, headers, null,cookies);
        }
    
        @Override
        public HttpResponse dopost(String url, Map<String, String> headers,InputStream data, Map<String, String>  cookies) throws IOException {
            return doRequest(HttpMethod.POST, url, headers, data,cookies);
        }
        protected static class TrustAnyTrustManager implements X509TrustManager {
            @Override
            public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
            }
    
            @Override
            public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
            }
    
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        }
    
        protected static class TrustAnyHostnameVerifier implements HostnameVerifier {
            @Override
            public boolean verify(String s, SSLSession sslSession) {
                return true;
            }
        }
    
        protected final SecureRandom secureRandom = new SecureRandom();
    }
    

     

     

     

    展开全文
  • Java图片处理:网页转图片(HtmlToImage)

    千次阅读 2019-03-12 15:02:17
    Java图片处理:网页转图片 需求来源于前端同事跟我反馈整天调试布局样式很难受,...页面效果还原程度 是否支持复杂html/js解析 中文字体显示效果 JEditorPane 首先找到的方案是使用java内置的Html解释工具javax.sw...
  • 让JSP页面过期, 即保证每次的JSP页面都是最新的 数据分页显示 - JDBC 2.0 - Oracle 认 识 JINI 如何捕获视频 如何捕获音频及输出音频 如何成为一个优秀的jsp程序员 如何从mail server删除一条消息的例子 如何...
  • Java-Web中表单的应用

    2021-01-23 10:54:25
    表单就是html页面中,用来收集用户信息的所有元素集合,然后把这些信息发送给服务器 需求:创建一个个人信息注册信息表单界面,包含用户名、密码、确认密码、性别(单选), 兴趣爱好(多选),国籍(下拉列表),...
  • JAVA模板语言(摘)

    千次阅读 2013-10-15 08:35:25
    最近一直为选择模板语言所扰,搜了一下文章,有以下几点评价。(这是原文作者的比较,各人意见仁者见仁,智者见智吧) Velocity:  Turbine项目(http://jakarta.apache.org/Turbine)采用了velocity技术。  1....
  • 完善URLerwrite配置,避免一些特殊URL造成404非友好页面 修正投票系统对不同版本MYSQL兼容问题,造成投票数据不正确 修正部分MYSQL版本造成下单过程保存个人资料失败问题 修正部分MYSQL版本造成会员登录次数不会增加...
  • jsp页面合并表格

    千次阅读 2012-09-28 15:08:50
    在实际项目中经常会遇到合并表格的情形,现在我将自己...<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> 评价信息详情 function fixRowspan() { var tb = document.
  • 前台jsp页面: ``` <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html lang="en"> , initial-scale=1, maximum-scale=1, user-scalable=0"> ...
  • 树形展示数据——dhtmlxTree的使用

    万次阅读 多人点赞 2014-04-03 00:45:08
    Java Web项目开发中,一般用JSP做前台数据展示,后台通过SSH框架来进行高效开发,有流程的控制,业务的处理和对数据库的各种处理,而数据则存放在Oracle等选择的数据库中。现在大家想这样一个问题,用户和什么打...
  • JavaScript权威指南第四版图书评价:★★★★☆ 图书语言:简体图书 图书大小:19.11MB 图书格式:PDF图书作者:David Flanagan 更新日期:2006-05-23 下载次数:765394 ...Java Script程序可以直接嵌入HTML页面。与We
  • 本毕业设计采用struts2框架,以java为核心编程语言,使用css3与html5做前台页面展示,数据库采用oracle 11,jdk1.7,tomcat7,系统中普遍运用ajax技术改善用户体验,比如图片上传、输入信息验证等。系统分为管理员、...
  • Java Web项目开发中,一般用JSP做前台数据展示,后台通过SSH框架来进行高效开发,有流程的控制,业务的处理和对数据库的各种处理,而数据则存放在Oracle等选择的数据库中。现在大家想这样一个问题,用户和什么打...
  • 它在传统的静态页面文件(*.html,*.htm)中加入JAVA程序片段和JSP标记,就构成了JSP页面。JSP具有以下的优点: 1、将业务层与表示层分离:使用JSP技术,网络开发人员可充分使用HTML来设计页面显示部分(如字体颜色...
  • 它在传统的静态页面文件(*.html,*.htm)中加入JAVA程序片段和JSP标记,就构成了JSP页面。JSP具有以下的优点: 1、将业务层与表示层分离:使用JSP技术,网络开发人员可充分使用HTML来设计页面显示部分(如字体颜色...
  • Java版本:1.8 数据库:MySQL 框架:Spring + Spring MVC + MyBatis 服务器:Tomcat 前端解析框架:Thymeleaf 开发工具:Idea 2017 版本管理工具:Maven 版本控制工具:GitHub 3.2 实现过程 3.2.1 商品首页实现 ...
  • 甚至javafx,flex,我在这里不想评价谁更好,我想让有经验的人帮我指点一个最好用的吧。 另外我至今没弄明白ajax和ssh框架的关系,你看ajax和struts都是显示层的,为什么两者竟然可以不互斥的在一起?我一直以为有了...
  • 9.6.2 交易流程测试结果分析及性能评价 281 9.6.3 查询流程测试结果分析 281 第10章 循序渐进--进阶LoadRunner高手 282 10.1 性能测试用例的设计策略 282 10.1.1 "普遍撒网,重点查看"的原则 282 10.1.2 保证数据的...
  • 过期了

    2020-12-30 02:07:08
    <ul><li>整个阿里所有的商品数据、评价数据、店铺数据,整个淘系的图片这些海量数据等待你来挖掘。</li><li>整个item.taobao.com域、淘系的店铺域、淘系的所有图片空间、还有一个个性化搜索产品,这些...
  • IOS开发工程师、Java程序员 负责iOS的app包括:和包商户版、和包客户端、和聚宝、和包刷卡、商户接入和包支付能力项目 以及为和飞信app 提供安全支付组件 对iOS商户和包支付插件项目进行代码重构,进行底层的网络...
  • 计算机网络基础知识

    2013-12-31 12:14:07
    1.5.2 模型评价 1.6 本书的结构 第一部分 数据通信 第2章 数据通信基础知识 2.1 基本概念 2.1.1 信号与通信 2.1.2 模拟通信 2.1.3 数字通信 2.2 数据通信基础理论 2.2.1 信号的频谱和带宽 2.2.2 信道的...
  • 这是我的页面: [code="java"] <%@ page language="java" import="java.util.*" pageEncoding="GBK"%> String path = request.getContextPath(); String basePath = request.getScheme() + "://" + ...
  • 1.5.2 模型评价 1.6 本书的结构 第一部分 数据通信 第2章 数据通信基础知识 2.1 基本概念 2.1.1 信号与通信 2.1.2 模拟通信 2.1.3 数字通信 2.2 数据通信基础理论 2.2.1 信号的频谱和带宽 2.2.2 信道的截止...
  • 计算机网络,计算机网络基础知识

    千次下载 热门讨论 2008-12-04 12:50:10
    1.5.2 模型评价 1.6 本书的结构 第一部分 数据通信 第2章 数据通信基础知识 2.1 基本概念 2.1.1 信号与通信 2.1.2 模拟通信 2.1.3 数字通信 2.2 数据通信基础理论 2.2.1 信号的频谱和带宽 2.2.2 信道的截止...
  • 排行榜、树洞 OCR 文字识别 、从包含表格的扫描图片中识别表格和文字、语声迁移、Python口语自然语言处理工具集(英文)、 similarity:相似度计算工具包,java编写、海量中文预训练ALBERT模型 、Transformers 2.0 、...

空空如也

空空如也

1 2
收藏数 40
精华内容 16
关键字:

java评价页面html

java 订阅