在SVG中使用外部绘图

2014-06-12 SVG

您可以在 SVG 文档中包括预定义的内容 —— 在呈现的文档内或文档之外定义的内容。

#引用内部绘图 symbol,defs 都可以事先定义好图形,而后use来引用

<svg  width="200" height="200" version="1.1"
        xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <symbol id="shape2">
        <circle cx="25" cy="25" r="25"></circle>
        <title>My image</title>
    </symbol>

    <defs>
        <g id="shape3">
            <circle cx="25" cy="25" r="25" fill="red"></circle>
        </g>
    </defs>
    <use xlink:href="#shape2" x="50" y="25" ></use>
    <use xlink:href="#shape3" x="150" y="25" ></use>
</svg>
My image

有关symbol,defs的异同点,可以参考这篇文章

#引用外部绘图 我们事先已经准备好了一个外部绘图svg文件svg-file-test.svg

##1.使用<image> 使用预定义内容作为 SVG 绘图一部分的方法之一是使用 <image>元素。在概念上,SVG 中的<image>与 HTML 中的 <img>非常类似:该元素只须指示呈现客户机在当前的 SVG 环境中绘制外部图像的内容 —— 其本身可能是 SVG 或者是 JPEG 或 PNG 格式的光栅图像。您几乎可以像调整一个规则的图形元素那样来调整外部图像的大小和改变其位置

<svg  width="100%" height="100%" version="1.1"
        xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <image  x="0" y="0" width="300" height="200"  xlink:href="../assets/img/svg-file-test.svg"></image>

    <image  x="0" y="200" width="300" height="200"  xlink:href="../assets/img/wl_white.png"></image>
</svg>

##2.使用<use>元素 任何svg, symbol, g, 单个的图形元素和use元素本质上都可以作为模板对象被use元素引用(例如初始化)。use引用的图形内容会在指定的位置渲染。与image元素不同,use元素不能引用整个文档。

<svg    width="100%" height="100%" version="1.1"
        xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <use xlink:href="../assets/img/svg-file-test.svg#svg2" x="0" y="0"  width="100" height="100" ></use>
    <use xlink:href="../assets/img/svg-file-test.svg#rect2985" x="0" y="325"  width="300" height="200" ></use>
</svg>

第一个use引用了该文件的整个svg元素。

第二个use引用了该文件的rect元素。


JavaScript使用严格模式(Strict Mode)

2014-06-07 JavaScript

ECMAScript5中引入的严格模式,通过让JavaScript运行环境对一些开发过程中最常见和不易发现的错误做出和当前不同的处理,来让开发者拥有一个”更好”的JavaScript语言。很长一段时间内,由于只有Firefox支持严格模式,我曾对严格模式表示怀疑。但到了今天,所有主流的浏览器都在他们的最新版本中支持了严格模式(包括IE10,Opera12和Android4,IOS5)是时候开始使用严格模式了。

严格模式能起到什么作用?

严格模式为JavaScript引入了很多变化,我把他们分为两类(明显的和细微的)。细微改进的目标是修复当前JavaScript中的一些细节问题,对于这些问题我不在这里进行深入介绍;如果你有兴趣,请阅读Dmitry Soshnikov撰写的精彩文档ECMA-262-5 in Detail Chapter 2 Strict Mode。 我在这里主要介绍严格模式引入的明显变化,那些在你使用严格模式前应该知道的概念和那些对你帮助最大的改变。

在开始学习具体特性前,请记住严格模式的一大目标是让你能更快更方便的调试。运行环境在发现问题时显性的抛出错误比默不做声的失败或怪异行事(未开启严格模式的JavaScript运行环境经常这样)要好。严格模式会抛出更多错误,但这是好事,因为这些错误会唤起你注意并修复很多以前很难被发现的潜在问题。

1. 去除with关键词

首先,严格模式中去除了with语句,包含with语句的代码在严格模式中会抛出异常。所以使用严格模式的第一步:确保你的代码中没有使用with。

// 在严格模式中以下JavaScript代码会抛出错误
with (location) {
    alert(href);
}

2. 防止意外为全局变量赋值

其次,局部变量在赋值前必须先进行申明。在启用严格模式之前,为一个未申明的局部变量复制时会自动创建一个同名全局变量。这是Javacript程序中最容易出现的错误之一, 在严格模式中尝试这么做时会有显性的异常抛出。

// 严格模式下会抛出异常
(function() {
    someUndeclaredVar = "foo";
}());

3. 函数中的this不再默认指向全局

严格模式中另一个重要的变化是函数中未被定义或为空( null or undefined)的this不在默认指向全局环境(global)。这会造成一些依赖函数中默认this行为的代码执行出错,例如:

window.color = "red";
function sayColor() {
    alert(this.color);
}
// 在strict模式中会报错, 如果不在严格模式中则提示 “red"
sayColor();
// 在strict模式中会报错, 如果不在严格模式中则提示 “red"
sayColor.call(null);

this在被赋值之前会一直保持为undefined,这意味着当一个构造函数在执行时,如果之前没有明确的new关键词,会抛出异常。

function Person(name) {
    this.name = name;
}
//在严格模式中会报错
var me = Person("Nicholas");

在上面的代码中,Person构造函数运行时因为之前没有new,函数中的this会保留为undefined, 由于你不能为undefined设置属性,上面的代码会抛出错误。 在非strict模式环境中,没有被复制的this会默认指向window全局变量,运行的结果将是意外的为window全局变量设置name属性。

4. 防止重名

当编写大量代码时,对象属性和函数参数很容易一不小心被设置成一个重复的名字。严格模式在这种情况下会显性的抛出错误

//重复的变量名,在严格模式下会报错
function doSomething(value1, value2, value1) {
    //code
}

//重复的对象属性名,在严格模式下会报错:
var object = {
    foo: "bar",
    foo: "baz"
};

以上的代码在严格模式中都会被认为是语法错误而在执行前就让你能得到提示。

5. 安全的 eval()

虽然eval()语句最终没有被移除,但在严格模式中仍然对它进行了一些改进。最大的改变是在eval()中执行的变量和函数申明不会直接在当前作用域中创建相应变量或函数,例如:

(function() {
    eval("var x = 10;");
    // 非严格模式中,alert 10
    // 严格模式中则因x未被定义而抛出异常,
    alert(x);
}());

任何在eval()执行过程中创建的变量或者函数保留在eval()中。但你能明确的从eval()语句的返回值来获取eval()中的执行结果,例如:

(function() {
    var result = eval("var x = 10, y = 20; x + y");
    // 在strict或非strict模式中都能正确的运行余下的语句.(resulst为30)
    alert(result);
}());

6. 对只读属性修改时抛出异常

ECMAScript5中还引入为对象的特定属性设为只读,或让整个对象不可修改的能力。 但在非严格模式中,尝试修改一个只读属性只会默不做声的失败。 在你和一些浏览器原生API打交道过程中,你很可能遇到这种情况。严格模式会在这种情况下明确的抛出异常,提醒你修改这个属性是不被允许的。

var person = {};
Object.defineProperty(person, "name" {
    writable: false,
    value: "Nicholas"
});
// 在非严格模式时,沉默的失败,在严格模式则抛出异常.
person.name = "John"; 上面的例子中,name属性被设为只读,非严格模式中执行对name属性的修改不会引发报错,但修改不会成功。但严格模式则会明确的抛出异常。

NOTE: 强烈建议你在使用任何ECMAScript属性特性指定时开启严格模式。

如何使用?

在现代浏览器中开启严格模式非常容易,只需要在JavaScript代码中出现以下指令即可

"use strict";

虽然看上去上面的代码仅仅只是未赋予某个变量的字符串,它实际上起到指示JavaScript引擎切换到严格模式的作用(不支持严格模式的浏览器会忽略以上代码,不会对后续的执行产生任何影响)。虽然你能把这个指令作用到全局或某个函数中,但这里还是要提醒,不要在全局环境下启用严格模式。

// 请不要这么使用
"use strict";
function doSomething() {
    // 这部分代码会运行于严格模式
}
function doSomethingElse() {
    // 这部分代码也会运行于严格模式
}

虽然上面的代码看起来不算一个大问题。但当你不负责维护页面中引入的全部代码时,这样使用strict模式会让你面临由于第三方代码没有为严格模式做好准备而引发的问题。 因此,最好把开启严格模式的指令作用于函数中,例如:

function doSomething() {
    "use strict";
    // 这个函数中的代码将会运行于严格模式
}
function doSomethingElse() {
    // 这个函数中代码不会运行于严格模式
}

如果你想让严格模式在不止一个函数中开启,请使用立即执行函数表达式

(immediately-invoked function expression ,IIFE):
(function() {
    "use strict";
    function doSomething() {
        // 这个函数运行于严格模式
    }
    function doSomethingElse() {
        // 这个函数同样运行于严格模式
    }
}());

结论

我强烈建议你从现在开始就启用JavaScript严格模式,它能帮你发现代码中未曾注意到的错误。不要在全局环境中启用,但你能尽量多的使用IIFE(立即执行函数表达式)来把严格模式作用到多个函数范围内。一开始,你会遇到之前未曾碰到过的错误提示,这是正常的。当启用严格模式后,请确保在支持的浏览器中做了测试,以发现新的潜在问题。一定不要仅仅在代码中添加一行”use strict”就假定余下的代码能正常工作。最后,请在严格模式下开始编写更好的代码。

注:

这里有各款浏览器对严格模式支持情况的一个汇总。

可以在这个页面对当前浏览器的严格模式支持度进行测试。

参考:


SVG Viewport和View Box

2014-06-03 SVG

SVG Viewport和View Box用来设置图像的可见部分的尺寸。

##Viewport(视口) Viewport:视口,视觉窗口,是SVG图像的可见区域。SVG图像逻辑上是能显示你想要的宽和高,但实际上同一时间仅图像的某一部分是可见的。该可见的区域被称为Viewport。

您可以通过<svg>元素的widthheight指定使用的Viewport宽度和高度的下面是一个例子:

<svg width="500" height="300"></svg>

这例子定义了一个Viewport,500个单位宽和300个单位高。

##坐标单位 如果你不指定任何内部宽度和高度属性的单位,单位都假定为像素。即,宽度500表示500个像素的宽度。

除了像素,还可以使用下面的单位:

单位 描述
em 默认字体大小 ,通常是一个字符高度
ex x字符的高度
px 像素
pt 点(一英寸的1/72)
pc 派卡(一英寸的1/6)
cm 厘米
mm 毫米
in 英寸

在<svg>元素里面设置单位只会影响的<svg>的大小(即Viewport)。在SVG图像中显示的SVG图形的大小由你对每个图形设置的单位决定。如果没有指定单位,各单位将默认为像素。

下面是一个例子:

<svg width="10cm" height="10cm">
    <rect x="50" y="100" width="50" height="50"
          style="stroke: #000000; fill: none;"/>
    <rect x="100" y="100" width="50mm" height="50mm"
          style="stroke: #000000; fill: none;" />
</svg>

该<svg>图像有其单位设置为厘米。两个<rect>元素都有自己的单位设置。一个使用像素(没有单位明确设定),另一个使用毫米。

这里是所得到的图象,右边的(单位毫米)大于左边(单位像素)。

##View Box 您可以重新在<svg>元素内部定义没有单位的坐标,通过viewBox属性来实现。下面是一个例子:

<svg width="500" height="200" viewBox="0 0 50 20" style="border: 1px solid #234567;">
    <rect x="20" y="10" width="10" height="5"
          style="stroke: #000000; fill:none;"/>
</svg>

此示例创建一个<svg>为500像素宽和200像素高,宽度元素的的viewBox属性包含四个坐标。这些坐标就定义了<svg>的viewBox属性。

在这种情况下,View Box跨度从0,0到50,20。这意味着,500 x 200像素 <svg>元素内部使用一个坐标系,它从0,0 到50,20。换言之,图形中使用的坐标,每1个单位,在<svg>对应于宽度500/50 = 10个像素,而在高200/20 = 10个像素。这就是为什么x轴为20及y轴为10的位置的矩形是真正位于(200,100),其宽度(10)和高度(5)对应于100个像素和50个像素。

另一种方式来解释它,viewBox属性的前两个坐标定义的是<svg>左上角的用户坐标,后两个坐标定义的是<svg>右下角的用户坐标。该<svg>内部的空间被解释为从左上角坐标到右下角坐标跨越。

这里是所得到的图象:

注意<rect>里面的所有坐标元素1个单位就代表10像素。

##preserveAspectRatio保持宽高比 如果Viewport和View Box不具有相同的宽高比(宽度与高度之比),您需要指定SVG显示器(例如浏览器)如何显示SVG图像。使用<svg>的preserveAspectRatio属性。

该preserveAspectRatio属性需要用空格分隔的两个值。第一个值将告诉您View Box如何在Viewport中对齐。这个值本身就是两部分组成。第二个值将告诉您宽高比如何将被保留(如果有的话)。

第一个值指定的对齐由两部分组成。第一部分指定的x对齐和第二部分指定的y对齐。这里是x轴和y取向的值的列表:

描述
xMin 对齐View Box最小x轴的值与Viewport的左边缘。
xMid 对齐View Box的x轴的中心与Viewport的中心x轴坐标。
xMax 对齐View Box最大x轴的值与Viewport的右边缘。
YMin 对齐View Box最小y轴的值与Viewport的顶部边缘。
YMid 对齐View Box的y轴的中心与Viewport的中心y轴坐标。
YMin 对齐View Box最大y轴的值与Viewport的底部边缘。

这里有两个例子:

xMaxYMax

xMidYMid

在preserveAspectRatio第二部分属性值可以采取三种不同的值:

描述
meet 保持宽高比和比例视图框,以适应内视口。
slice 保留宽高比,任何不适合Viewport宽高比的图像的会被切掉。
none 不保留宽高比。缩放图像以View Box充满完全适应Viewport。比例会被扭曲。

在第二部分preserveAspectRatio属性值附加到第一部分,以空格分隔。这里有两个例子:

preserveAspectRatio="xMidYMid meet"

preserveAspectRatio="xMinYMin slice"

下面的实施例都具有宽度为500,高度为75和的viewBox属性设为0 0 250 75。这意味着,沿x轴的每个坐标单元将对应于2个像素,而是沿着Y轴的每个坐标单位只对应1个像素。在x轴缩放比为500/250=2 ,y轴的缩放比为75/75=1。这可能会导致一个扭曲,但我们会在下面的例子查看如何设置各种preserveAspectRatio。

查看例子



SVG <marker>创建箭头

2014-05-29 SVG

SVG 中<line>并没有箭头,可以通过<marker>进行扩展。

先定义一个箭头

<defs>
    <marker id="markerArrow" markerWidth="13" markerHeight="13" refx="2" refy="6" orient="auto">
        <path d="M2,2 L2,11 L10,6 L2,2" style="fill: #000000;" />
    </marker>
</defs>

其中orient="auto"设置箭头的方向为自动适应线条的方向。

而后,画line ,line的marker-end引用上面定义好的markerArrow即可

<line x1="0" y1="0" x2="100" y2="50"  stroke="red" stroke-width="1" marker-end="url(#markerArrow)"  />

也可以应用在path中, 效果如下:

完整代码如下:

<svg width="500" height="100">
<defs>
    <marker id="markerCircle" markerWidth="8" markerHeight="8" refx="5" refy="5">
        <circle cx="5" cy="5" r="3" style="stroke: none; fill:#000000;"/>
    </marker>

    <marker id="markerArrow" markerWidth="13" markerHeight="13" refx="2" refy="6" orient="auto">
        <path d="M2,2 L2,11 L10,6 L2,2" style="fill: #000000;" />
    </marker>
</defs>
<line x1="0" y1="0" x2="100" y2="50"  stroke="red" stroke-width="1" marker-end="url(#markerArrow)"  />
<path d="M100,10 L150,10 L150,60"
      style="stroke: #6666ff; stroke-width: 1px; fill: none;
                   marker-start: url(#markerCircle);
                   marker-mid:url(#arrow);
                   marker-end: url(#markerArrow) "
        />
</svg>

SVG实例之中国地图

2014-05-27 SVG

SVG 做地图具有可以任意比例放大缩小不失真的优点。本例基于d3.js的svg制作。

地图数据用GeoJSON存储。GeoJSON 是基于JSON 的、为Web 应用而编码地理数据的一个标准。实际上,GeoJSON 并不是另一种格式,而只是JSON 非常特定的一种使用方法。

网上有很多免费的GeoJSON下载,本例子中国地图GeoJSon 可以从本例源码 下载

###1.获取d3 在项目中引入即可, <script src="http://d3js.org/d3.v3.min.js"></script>

###2.创建svg var width = 960, height = 500; var svg = d3.select(“body”) .append(“svg”) .attr(“width”, width) .attr(“height”, height); ###3.创建投影(projection) var projection = d3.geo.mercator().translate([width / 2, height / 2]).center([105, 38]).scale(550);

###4.创建path var path = d3.geo.path().projection(projection);

###5. 解析json d3.json(“china.geo.json”, function(json) {

    svg.selectAll("path")
            .data(json.features)
            .enter()
            .append("path")
            .attr("d", path)
            .on('mouseover', function(data) {
                d3.select(this).attr('fill', 'rgba(2,2,139,0.61)');

                //创建显示tooltip用的矩形
                svg.append("rect")
                        .attr("id", "tooltip1")
                        .attr("x", 50)
                        .attr("y",50)
                        .attr("width",140)
                        .attr("height",130)
                        .attr("stroke","black")
                        .attr("fill","none")
                ;

                //创建显示tooltip文本
                svg.append("text")
                        .attr("id", "tooltip2")
                        .attr("x", 100)
                        .attr("y", 100)
                        .attr("text-anchor", "middle")
                        .attr("font-family", "sans-serif")
                        .attr("font-size", "11px")
                        .attr("font-weight", "bold")
                        .attr("fill", "black")
                        .text(data.properties.name);
            })
            .on('mouseout', function(data) {
                d3.select(this).attr('fill', 'rgba(128,124,139,0.61)');
                //Remove the tooltip
                d3.select("#tooltip1").remove();
                d3.select("#tooltip2").remove();
            })
            .attr('fill', 'rgba(128,124,139,0.61)')
            .attr('stroke', 'rgba(255,255,255,1)')
            .attr('stroke-width', 1)
    ;
});

演示效果:

完整源码下载

中国地图GeoJSON

查看例子


WebStorm配置svn共享、检出项目

2014-05-26 Web

##安装svn 1下载SlikSVN

2安装

我的是在D:\Program Files\SlikSvn目录下

3.在WebStorm中配置

file->settings->Version Contorl->subversion->with conmand line client 设置成你的D:\Program Files\SlikSvn\bin\svn.exe

##svn共享项目 1.share Project share Project

2.select target select target

3.验证 验证

4.确认 确认

##svn检出项目 1.选择项目 选择项目1

选择项目2

2.检出 检出1

检出2

##相关问题的解决 如果遇到如下错误 “Cannot load supported formats: Cannot run program ‘svn’: CreateProcess error=2, ” 错误 请回到最上面,进行“安装svn”这步骤


SVG实例之电力开关

2014-05-24 SVG

<?xml version="1.0" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"  width="400" height="200" >
<script> 
function lineGClick(evt) {

var lineA = document.getElementById("lineA");
if( lineA.getAttribute("display")=="none"){

lineA.setAttribute("display","#000000");
line2.setAttribute("display","none");

}else{
lineA.setAttribute("display","none");
line2.setAttribute("display","#000000");
}
}
 </script>
<defs>
 <g id="lineG1" >
  <line id="line1" fill="none" stroke="#000000" stroke-width="4" x1="10" y1="10" x2="10" y2="40"/>
  <line id="lineA" fill="none" display="none" stroke="#000000" stroke-width="4" x1="10" y1="40" x2="10" y2="70"/>
  <line id="line2" fill="none" stroke="#000000" stroke-width="4" x1="10" y1="40" x2="35" y2="60"/>
  <line id="lineB" fill="none" stroke="#000000" stroke-width="4" x1="10" y1="70" x2="10" y2="100"/>
 </g>
</defs>
 
<text x="10" y="20" fill="red">一个SVG电力开关的例子。点击开关,进行状态转换</text>
<use x="10" y="30" xlink:href="#lineG1" onclick="lineGClick(evt)"/>
<a xlink:href="http://www.waylau.com" target="_blank">
<text x="10" y="180" fill="red">欢迎访问wwww.waylau.com</text>
  </a>
</svg>

效果:

解释:

defs标签定义了可以重复利用的组件

use引用了defs所定义的组件,其中onclick监听了鼠标点击事件


测试下几个网络相册

2014-05-23 Web

##1.百度相册外链分享

SQLServer.exe 优点:国内站,速度快,可以批量上传

缺点:右下角会有水印,很是不爽

##2.试下Photobucket 免费,无水印

 photo 4E9280547F514E0D5728A80A14E0A5E027684539F56E0_zpsc7c53c1a.jpg 优点:可以批量上传,可以照片分类,文件夹下可以再建文件夹 缺点:国外网站,网速比较慢

##3.POCO貌似也不错 POCO是您的图片生活记录和分享平台,在这里用图片记录您的生活、分享您的一切,在各兴趣社区以图会友、参加各种POCO线上线下活动。 POCO给你提供。。。。 1.跟图片有关的一切服务:发单图微博、发组图博文、发兴趣图片、建立免费可外链相册… 2.视觉图片达人必备的、互联网最创造力的个人空间 3.图片生活分享交流社区(摄影、美食、宠物、达物、旅游、手机拍客、模特….),您的优秀图片分享将有机会登上 POCO网站首页,并获得荣誉勋章 4.获得POCO优质生活体验(美食菜谱、餐厅搜索及优惠、旅游景点大全、相机图片欣赏等)

需要注意的是如果直接复制图片地址,无法正常显示的话,如下: 原地址:

将图片地址进行修改:

<img src="http://image16-c.poco.cn/mypoco/myphoto/20140523/11/17476175320140523113816047.png"/>

-c 去掉即可

<img src="http://image16.poco.cn/mypoco/myphoto/20140523/11/17476175320140523113816047.png"/> 修改地址后的图片 <img src="http://image16.poco.cn/mypoco/myphoto/20140523/11/17476175320140523113726012.png?280x280_130"/>

个人昵称水印

社区水印

缺点:只能单张图片上传

##4.七牛云存储 优点:国内站,稳定,全网加速,图片处理:

缺点:有流程和存储的限制。体验用户:储存空间1GB每月Put请求1万次每月下载流量1GB每月Get请求10万次创建1个空间仅支持富媒体上传. 如果注册为标准用户,还要提供身份,个人照片,貌似有点麻烦

##5.爱唯侦察出的图床http://99btgc01.info/

方便上传电影的封面,听站长说还算稳定。操作也简单,无需管理


SQLServer2008内存飙升 解决

2014-05-15 SQLServer

SQLServer2008在运行一段时间后内存飙升,严重导致系统奔溃 SQLServer.exe

这个是SQLServer内存管理机制决定的,由于他应用了内存池的技术,有效提高数据库的查询速度,但同时会占用大量的内存。详见SQLServer 内存管理体系结构

默认设置,他会占用计算机的所有内存。 SQLServer momery

所以要限制内存池最高内存占用量。

  • 1.登陆数据库管理工具
  • 2.“右键”数据库连接
  • 3.点击“属性”选项
  • 4.选中“内存”
  • 5.设置“最大服务器内存”

限制内存


从iReport到Jaspersoft Studio

2014-05-14 JasperReports

从5.5版本开始,Jaspersoft Studio将取代iReport 成为JasperReports官方设计器。iReport 维护截止日期到2015年底,意味着不会再有新的功能增加进iReport,但会做一些关键bug的修复、更新。所幸的是基于eclipse的Jaspersoft Studio同样开源、免费!Yeah!

Jaspersoft Studio是一个专为JasperReports报表引擎而开发的报表设计器,是iReport设计器的一个完整重构,基于Eclipse平台实现。它能够让你创建包含图表、图片、子报表、交叉表等非常复杂的布局。可以通过JDBC、TableModels、JavaBeans、XML、Hibernate、CSV或自定义数据源来读取数据。可以将报表输出成PDF、RTF、XML、XLS、CSV、HTML、XHTML、text、DOCX或OpenOffice。

##Report Life Cycle(报表生命周期) iReport和JasperSoft Studio中的报表的生命周期是相同的。

当你使用iReport或JasperSoft Studio做报表时,要创建一个JRXML文件,该文件是包含报表布局定义的XML文档。布局是完全可视化,这样你就可以忽略JRXML文件的基础结构。执行报告之前,JRXML必须编译成名为Jasper的二进制文件。Jasper文件就是应用程序生成报表所需要的。

有许多数据源类型。您可以从SQL查询,XML文件,csv文件,HQL(Hibernate查询语言)查询,JavaBeans集合等。如果你没有一个合适的数据源,JasperReports的允许你编写自己的自定义数据源。通过Jasper文件和数据源,JasperReports 就能生成最终用户想要的文档格式。

iReport和JasperSoft Studio允许您配置数据源,并使用它们来测试您的报表。在许多情况下,数据驱动向导可以帮助您快速设计您的报表。iReport包括JasperReports引擎本身,可以让您预览报表输出,测试和优化您的报表。

Report Life Cycle

##User Interface(用户界面) JasperSoft Studio 有两个不同的版本:一个独立的RCP产品,以及Eclipse插件的版本。熟悉Eclipse的人都会对用户界面感到很熟悉,而那些新用户,或者那些只熟悉iReport的设计师,则会觉得显示元素的布局会出现很大的不同。独立和插件的版本也有类似的用户界面。在下面可以看到包括JasperSoft Studio界面的预览:

Report editing area(主编辑区域)中,您直观地通过拖动,定位,对齐和通过Designer palette(设计器调色板)对报表元素调整大小。

JasperSoft Studio有一个多标签编辑器,Design,SourcePreview

  • Design tab:当你打开一个报告文件,它允许您以图形方式创建报表选中
  • Source tab: 包含用于报表的JRXML源代码。
  • Preview tab: 允许在选择数据源和输出格式后,运行报表预览。

很多页面可以查看数据:

  • Repository Explorer view:包含JasperServer生成的连接和可用的数据适配器列表
  • Project Explorer view:包含JasperReports的工程项目清单
  • Outline view:在大纲视图中显示了一个树的形式的方式报告的完整结构。
  • Properties view:通常是任何基于Eclipse的产品/插件的基础之一。它通常被填充与实际所选元素的属性的信息。这就是这样,当你从主设计区域(即:一个文本字段)选择一个报表元素或从大纲,视图显示了它的信息。其中一些属性可以是只读的,但大部分都是可编辑的,对其进行修改,通常会通知更改绘制的元素(如:元素的宽度或高度)。
  • Problems view:显示的问题和错误,例如可以阻断报告的正确的编译。

最后,Report state summary提供了有关在报表编译/填充/执行统计用户有用的信息。错误会显示在这里。

下面是一个简短的比较表,帮助用户看到iReport和JasperSoft Studio的主要内容。

iReport Designer Jaspersoft Studio
JasperServer Repository Repository Explorer
Report Inspector Outline view
Report Designer Report Editing Area
Problems List Problems view
Elements palette Designer Palette
Formatting tools Available via context menu on the element
Property sheet Properties view
Styles library
Project Explorer
iReport Designer Output window Report State summary

参考:http://community.jaspersoft.com/wiki/introduction-jaspersoft-studio http://community.jaspersoft.com/project/ireport-designer


SVG Animation动画

2014-05-09 Svg

#SVG动画示例 下面是一个简单的SVG动画的例子:

<svg width="500" height="100">
     <rect x="10" y="10" height="110" width="110"
         style="stroke:#ff0000; fill: #0000ff">
        <animateTransform
            attributeName="transform"
            begin="0s"
            dur="20s"
            type="rotate"
            from="0 60 60"
            to="360 60 60"
            repeatCount="indefinite" 
        />
    </rect>
</svg>

注意到,<rect>元素有一个<animateTransform>嵌套在它里面。正是这种元素驱动了矩形。

#动画选项的概述

动画是通过操纵图形随时间变化的属性而进行的。用下面5个SVG动画元素的 一个或多个来完成的:

  • <set>
  • <animate>
  • <animateColor>
  • <animateTransform>
  • <animateMotion>

这些动画元素在整个这段文字的后面要谈到的。

##set

<set>元素是最简单的SVG动画元素。j简单地将一个属性修改成一定值后,特定时间间隔过后就能能效了。因此,该图形是不连续的动画,只是改变属性值一次。

这里是一个<set>元素的例子:

<svg width="500" height="100">
    <circle cx="30" cy="30" r="25" style="stroke: none; fill: #0000ff;">
        <set attributeName="r" attributeType="XML"
                 to="100"
                 begin="5s" />
    </circle>
</svg>

注意<set>嵌套在circle里面。这就是<set>元素的用法。

该<set>元素将时间设置成一个属性的值。设置属性的名称是指定的attributeName。修改成的值为to。开始生效的时间间隔为begin

上面的例子中的属性设置r 5秒后为100。

##attributeType

在前面的例子也有一个attributeType属性在<set>元素里面。该值设置为XML。因为SVG的<circle >元素素是XML元素。

也可以将attributeType属性设置为CSS

Sorry, your browser does not support inline SVG.
<svg width="400" height="400">
  <rect x="20" y="20" width="250" height="250" style="fill:blue">
    <animate attributeType="CSS" attributeName="opacity" from="1" to="0" dur="5s" repeatCount="indefinite" />
  </rect>
  Sorry, your browser does not support inline SVG.  
</svg>

如果你不提供一个attributeType属性,那么浏览器会尝试猜测是一个XML属性还是CSS属性。

##animate

animate元素被用来驱动SVG图形的属性。下面是一个例子:

<svg width="500" height="75">
    <circle cx="30" cy="30" r="25" style="stroke: none; fill: #0000ff;">
        <animate attributeName="cx" attributeType="XML"
                 from="30"  to="470"
                 begin="0s" dur="5s"
                 fill="remove" repeatCount="indefinite"/>
    </circle>
</svg>

这个例子中的<circle>元素cx的属性从30改成了479。动画从0秒开始,并具有5秒持续时间。

当动画完成,animate的属性被设置回其原始值(fill=”remove”)。如果想要的将动画属保持在to值的位置,则fill设置为“freeze”。动画如果无限重复则设置repeatCount的值。

##animateColor

<svg width="500" height="80">
    <circle cx="30" cy="30" r="25" style="stroke: none; fill: #0000ff;">
        <animateColor attributeName="fill"
                 from="#0000ff"  to="#ff0000"
                 begin="0s" dur="5s"
                 fill="freeze" repeatCount="indefinite"/>
    </circle>
</svg>

这个例子中的动画填写将CSS属性从颜色#0000FF(蓝色)的颜色转为#FF0000(红色)。

: 尽管SVG定义了”animateColor”,但是它已经被弃用了,替代它的是”animate”元素。

##animateTransform

<animateTransform>元素可以驱动图形的transform&的属性。而<animate>元素不能做到这一点。 下面是一个例子:

<svg width="500" height="200">

  <rect x="20" y="20" width="100" height="40"
        style="stroke: #ff00ff; fill: none;" >
      <animateTransform attributeName="transform"
                        type="rotate"
                        from="0 100 100" to="360 100 100"
                        begin="0s" dur="10s"
                        repeatCount="indefinite"
              />
  </rect>
  <circle cx="100" cy="100" r="2" style="stroke: none; fill: #0000ff;"/>
</svg>

本例中在点(100,100)位置从0至360度进行旋绕。

下面是比例尺放大的示例:

<svg width="500" height="200">

    <rect x="20" y="20" width="40" height="40"
          style="stroke: #ff00ff; fill: none;" >
        <animateTransform attributeName="transform"
                          type="scale"
                          from="1 1" to="2 3"
                          begin="0s" dur="10s"
                          repeatCount="indefinite"
                />
    </rect>
</svg>

##animateMotion

该<animateMotion>元素可以驱动图形沿着一条路径运动。下面是一个例子:

<svg width="500" height="150">
  <path d="M10,50 q60,50 100,0 q60,-50 100,0"
    style="stroke: #000000; fill: none;"
          />
  <rect x="0" y="0" width="30" height="15"
          style="stroke: #ff0000; fill: none;">
      <animateMotion
          path="M10,50 q60,50 100,0 q60,-50 100,0"
          begin="0s" dur="10s" repeatCount="indefinite"
          />
  </rect>
</svg>

为了以配合道路的坡度,设置了rotate=”auto”。下面是一个例子:

<svg width="500" height="150">

    <path d="M10,50 q60,50 100,0 q60,-50 100,0"
          style="stroke: #000000; fill: none;"
            />

    <rect x="0" y="0" width="30" height="15"
          style="stroke: #ff0000; fill: none;">
        <animateMotion
                path="M10,50 q60,50 100,0 q60,-50 100,0"
                begin="0s" dur="10s" repeatCount="indefinite"
                rotate="auto"
                />
    </rect>
</svg>

##Time Units(时间单位)

时间单位经常用在begin,durend的属性值中,“5s”表示”5秒”。

单位 描述
h Hours(时)
min Minutes(分)
s Seconds(秒)
ms Milliseconds(毫秒)

也可以是这种hh:mm:ss这种格式,比如1:30:45表示时间长度为”1小时30分钟45秒”。

##Coordinating Animations(协调动画)

<svg width="500" height="100">
	
	<rect x="0" y="0" width="30" height="15"
	      style="stroke: #ff0000; fill: none;">
	
	    <animate id="one"
	            attributeName="x" attributeType="XML"
	            from="0" to="400"
	            begin="0s" dur="10s" fill="freeze"
	            />
	    <animate
	            attributeName="y" attributeType="XML"
	            from="0" to="80"
	            begin="one.end" dur="10s" fill="freeze"
	            />
	</rect>

</svg> 一个动画的开始时间是另外一个动画的结束时间。

也可以通过设置时间的偏移量 one.begin+10s one.end+5s

另外,你可以在一个动画指​​定一个明确的结束时间end属性。这并不能取代dur属性。它所做的是添加另一种可能结束一个动画,所以以先到为准。下面是一个例子:

<animate
attributeName="y" attributeType="XML"
from="0" to="50"
begin="one.begin+3s" dur="10s" end="one.end"
fill="freeze"
/>

该动画将有10秒的持续时间,或与one动画一起停止结束,以先到那个为准。

##Repeating Animations(重复动画)

重复动画可以用动画元素中的两个属性。

  • 第一个属性是的repeatCount属性。在这个属性,你可以设置一个数值,这是重复动画的次数,或值不确定,将继续运行动画不会停下。
  • 第二属性是repeatDur其中指定该动画将被重复的持续时间。
<svg width="500"  height="100">
   <rect x="10" y="10" width="40" height="20"
         style="stroke: #000000; fill: none;">
        <animate attributeName="x" attributeType="XML"
                 from="10" to="400"
                 begin="0s" dur="10s"
                 repeatCount="indefinite"
                />
        <animate attributeName="y" attributeType="XML"
                 from="10" to="100"
                 begin="0s" dur="10s"
                 fill="freeze"
                 repeatCount="indefinite"
                />
   </rect>
</svg>

##Combining Animations(结合动画)

动画可以组合起来用,这里是一个例子:

<svg width="500"  height="100">
   <rect x="10" y="10" width="40" height="20"
         style="stroke: #000000; fill: none;">
        <animate attributeName="x" attributeType="XML"
                 from="10" to="400"
                 begin="0s" dur="10s"
                 repeatCount="indefinite"
                />
        <animate attributeName="y" attributeType="XML"
                 from="10" to="100"
                 begin="0s" dur="10s"
                 fill="freeze"
                 repeatCount="indefinite"
                />
   </rect>
</svg>

这个例子中有两个动画,每个动画的分别驱动xŸ的属性。

当组合<animateTransform>元素,默认的行为是第二个动画来抵消第一个。但是,您可以通过设置additive属性值为sum的而使两种动画效果累加。

<svg width="500"  height="100">
    <rect x="10" y="10" width="40" height="20"
          style="stroke: #000000; fill: none;">
        <animateTransform attributeName="transform" attributeType="XML"
                 type="scale"
                 from="1" to="3"
                 begin="0s" dur="10s"
                 repeatCount="indefinite"
                 additive="sum"
                />
        <animateTransform attributeName="transform" attributeType="XML"
                 type="rotate"
                 from="0 30 20" to="360 30 20"
                 begin="0s" dur="10s"
                 fill="freeze"
                 repeatCount="indefinite"
                 additive="sum"
                />
    </rect>
</svg>

参考:http://tutorials.jenkov.com/svg/svg-animation.html


SVG Gradients之Radial

2014-05-04 Svg

##SVG <radialGradient> <radialGradient>元素必须嵌套在<defs>中

###示例1 径向渐变,从 white 到 blue

<svg height="150" width="500">
  <defs>
    <radialGradient id="grad1" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
      <stop offset="0%" style="stop-color:rgb(255,255,255);
      stop-opacity:0" />
      <stop offset="100%" style="stop-color:rgb(0,0,255);stop-opacity:1" />
    </radialGradient>
  </defs>
  <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad1)" />
</svg>

代码说明:

  • cx, cy,r 定义的是外层的圆,fx ,fy定义的是内层的圆
  • 渐变可以设置多个颜色,每种颜色都用<stop>指定
  • offset定义了渐变颜色的起止

###示例2

<svg height="150" width="500">
  <defs>
    <radialGradient id="grad2" cx="20%" cy="30%" r="30%" fx="50%" fy="50%">
      <stop offset="0%" style="stop-color:rgb(255,255,255);
      stop-opacity:0" />
      <stop offset="100%" style="stop-color:rgb(0,0,255);stop-opacity:1" />
    </radialGradient>
  </defs>
  <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad2)" />
</svg> 

SVG Gradients之Linear

2014-05-04 Svg

##SVG Gradients(渐变) 渐变是指从一种颜色向另外一种颜色的平滑转换。几种颜色转化能同时作用于同一个元素中。

SVG中主要有两种渐变:

  • Linear (线性渐变)
  • Radial (径向渐变)

##SVG <linearGradient> <linearGradient>元素必须嵌套在<defs>中

<linearGradient>可以定义成水平、垂直、任意角度渐变:

  • 水平渐变:y1 、y2相同, x1、x2 不同
  • 垂直渐变:x1、x2 相同, y1 、y2不同
  • 垂直渐变:x1、x2 不同, y1 、y2不同

###示例1 水平渐变,从yellow 到 red

<svg height="150" width="400">
  <defs>
    <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
      <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
    </linearGradient>
  </defs>
  <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad1)" />
</svg>

代码说明:

  • <linearGradient>中的x1, x2, y1,y2分别定义了渐变的起止位置
  • 渐变可以设置多个颜色,每种颜色都用<stop>指定

###示例2 垂直渐变,从yellow 到 red

<svg height="150" width="400">
  <defs>
    <linearGradient id="grad2" x1="0%" y1="0%" x2="0%" y2="100%">
      <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
      <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
    </linearGradient>
  </defs>
  <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad2)" />
</svg>

###示例3 水平渐变,从yellow 到 red,并增加了一个文本

SVG
<svg height="150" width="400">
  <defs>
    <linearGradient id="grad3" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
      <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
    </linearGradient>
  </defs>
  <ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad3)" />
  <text fill="#ffffff" font-size="45" font-family="Verdana" x="150" y="86">
  SVG</text>
</svg>

SVG Filters之阴影Drop Shadows

2014-05-04 Svg

##SVG <feOffset>

###示例1

<svg height="120" width="120">
  <defs>
    <filter id="f1" x="0" y="0" width="200%" height="200%">
      <feOffset result="offOut" in="SourceGraphic" dx="20" dy="20" />
      <feBlend in="SourceGraphic" in2="offOut" mode="normal" />
    </filter>
  </defs>
  <rect width="90" height="90" stroke="green" stroke-width="3"
  fill="yellow" filter="url(#f1)" />
</svg>

代码解释:

  • 元素的id属性定义了滤镜的唯一名称
  • 元件的滤镜属性链接到了“f1”滤镜

###示例2 加上了 <feGaussianBlur>

<svg height="140" width="140">
  <defs>
    <filter id="f2" x="0" y="0" width="200%" height="200%">
      <feOffset result="offOut" in="SourceGraphic" dx="20" dy="20" />
      <feGaussianBlur result="blurOut" in="offOut" stdDeviation="10" />
      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
    </filter>
  </defs>
  <rect width="90" height="90" stroke="green" stroke-width="3"
  fill="yellow" filter="url(#f2)" />
</svg>

###示例3

<svg height="140" width="140">
  <defs>
    <filter id="f3" x="0" y="0" width="200%" height="200%">
      <feOffset result="offOut" in="SourceAlpha" dx="20" dy="20" />
      <feGaussianBlur result="blurOut" in="offOut" stdDeviation="10" />
      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
    </filter>
  </defs>
  <rect width="90" height="90" stroke="green" stroke-width="3"
  fill="yellow" filter="url(#f3)" />
</svg>

代码解释:

  • <feOffset> 元素改成了”SourceAlpha”虚化中的Alpha通道代替了RGBA像素

###示例4

<svg height="140" width="140">
  <defs>
    <filter id="f4" x="0" y="0" width="200%" height="200%">
      <feOffset result="offOut" in="SourceGraphic" dx="20" dy="20" />
      <feColorMatrix result="matrixOut" in="offOut" type="matrix"
      values="0.2 0 0 0 0 0 0.2 0 0 0 0 0 0.2 0 0 0 0 0 1 0" />
      <feGaussianBlur result="blurOut" in="matrixOut" stdDeviation="10" />
      <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
    </filter>
  </defs>
  <rect width="90" height="90" stroke="green" stroke-width="3"
  fill="yellow" filter="url(#f4)" />
</svg>

代码解释:

  • <feColorMatrix> 转换颜色,使偏移图片的颜色值接近空(0)
  • 矩阵中三个’0.2’是获取了red、green、blue 通道

SVG Filters之虚化Blur Effects

2014-05-04 Svg

##SVG 滤镜 在 SVG 中,可用的滤镜有:

  • feBlend
  • feColorMatrix
  • feComponentTransfer
  • feComposite
  • feConvolveMatrix
  • feDiffuseLighting
  • feDisplacementMap
  • feFlood
  • feGaussianBlur
  • feImage
  • feMerge
  • feMorphology
  • feOffset
  • feSpecularLighting
  • feTile
  • feTurbulence
  • feDistantLight
  • fePointLight
  • feSpotLight

注意:

  • 您可以在每个 SVG 元素上使用多个滤镜!
  • IE 、Safari浏览器暂不支持滤镜!

##虚化Blur Effects; <filter>标签用来定义 SVG 滤镜。<filter>标签使用必需的 id 属性来定义向图形应用哪个滤镜? <filter>标签必须嵌套在 <defs> 标签内。<defs> 标签是 definitions 的缩写,它允许对诸如滤镜等特殊元素进行定义。

###SVG <feGaussianBlur>

####示例1

<svg height="110" width="110">
  <defs>
    <filter id="f1" x="0" y="0">
      <feGaussianBlur in="SourceGraphic" stdDeviation="15" />
    </filter>
  </defs>
  <rect width="90" height="90" stroke="green" stroke-width="3"
  fill="yellow" filter="url(#f1)" />
</svg>

代码解释:

  • 元素的id属性定义了滤镜的唯一名称
  • 元素定义了虚化效果
  • 在in=“SourceGraphic”部分定义了在整个元素中创建的效果
  • 该stdDeviation属性定义虚化的值
  • 元件的滤镜属性链接到了“f1”滤镜

SVG Stroke 属性

2014-05-04 Svg

##9.Stroke 属性 SVG stroke拥有很多属性,下面只重点讲一部分:

###stroke

stroke用来定义line、text或者元素的outline等的颜色

<svg height="80" width="300">
  <g fill="none">
    <path stroke="red" d="M5 20 l215 0" />
    <path stroke="blue" d="M5 40 l215 0" />
    <path stroke="black" d="M5 60 l215 0" />
  </g>
</svg>

###stroke-width stroke-width用来定义line、text或者元素的outline等的厚度

<svg height="80" width="300">
  <g fill="none" stroke="black">
    <path stroke-width="2" d="M5 20 l215 0" />
    <path stroke-width="4" d="M5 40 l215 0" />
    <path stroke-width="6" d="M5 60 l215 0" />
  </g>
</svg>

###stroke-linecap stroke-linecap定义线条结尾的不同样式

<svg height="80" width="300">
  <g fill="none" stroke="black" stroke-width="16">
    <path stroke-linecap="butt" d="M5 20 l215 0" />
    <path stroke-linecap="round" d="M5 40 l215 0" />
    <path stroke-linecap="square" d="M5 60 l215 0" />
  </g>
</svg>

###stroke-dasharray stroke-dasharray定义断续线

<svg height="80" width="300">
  <g fill="none" stroke="black" stroke-width="4">
    <path stroke-dasharray="5,5" d="M5 20 l215 0" />
    <path stroke-dasharray="10,10" d="M5 40 l215 0" />
    <path stroke-dasharray="20,10,5,5,5,10" d="M5 60 l215 0" />
  </g>
</svg>

###stroke-opacity stroke-opacity不透明度

欢迎光临www.waylau.com
<svg width="500" height="120">
<text x="22" y="40">欢迎光临www.waylau.com</text>
<path d="M20,40 l50,0"
      style="stroke: #00ff00;    fill:none;
             stroke-width:16px;
             stroke-opacity: 0.3;
             " />
<path d="M80,40 l50,0"
      style="stroke: #00ff00;    fill:none;
             stroke-width:16px;
             stroke-opacity: 0.7;
             " />
<path d="M140,40 l50,0"
      style="stroke: #00ff00;    fill:none;
             stroke-width:16px;
             stroke-opacity: 1;
             " />
</svg>

参考:http://tutorials.jenkov.com/svg/stroke.html http://www.w3schools.com/svg/svg_stroking.asp


SVG <text>文本

2014-05-04 Svg

##8.文本 <text>

####示例8.1 写一个文本:

欢迎访问wwww.waylau.com
 <svg height="30" width="200">
  <text x="0" y="15" fill="red">欢迎访问wwww.waylau.com </text>
</svg>

####示例8.2 让文本转个角度:

欢迎访问wwww.waylau.com
<svg height="60" width="200">
  <text x="0" y="15" fill="red" transform="rotate(10 20,40)">欢迎访问wwww.waylau.com</text>
</svg>

####示例8.3 让文本引用path:

欢迎访问www.waylau.com个人博客欢迎访问www.waylau.com
<svg width="500" height="220">
 <defs>
   <path id="myTextPath2"
   d="M75,20 l100,0 l100,30 q0,100 150,100"/>
</defs>

<text x="10" y="100" style="stroke: #000000;">
   <textPath xlink:href="#myTextPath2">
   欢迎访问www.waylau.com个人博客欢迎访问www.waylau.com
  </textPath>
</text>  
</svg>

####示例8.4

可以使用 <tspan> 将文本元素分成几部分,允许每部分有各自的样式

Several lines: 欢迎访问 wwww.waylau.com
<svg height="90" width="200">
  <text x="10" y="20" style="fill:red;">Several lines:
    <tspan x="10" y="45">欢迎访问</tspan>
    <tspan x="10" y="70">wwww.waylau.com</tspan>
  </text>
</svg>

####示例8.5 使用 <a> 使文本变成一个链接

欢迎访问wwww.waylau.com
<svg height="30" width="200" xmlns:xlink="http://www.w3.org/1999/xlink">
  <a xlink:href="http://www.waylau.com" target="_blank">
    <text x="0" y="15" fill="red">欢迎访问wwww.waylau.com</text>
  </a>
</svg>

####示例8.6 垂直样式

欢迎访问wwww.waylau.com 欢迎访问wwww.waylau.com
<svg height="260" width="200">
<text x="10" y="10" fill="red" style="writing-mode: tb; glyph-orientation-vertical: 0;">
   欢迎访问wwww.waylau.com
</text>
<text x="110" y="10" fill="red"  style="writing-mode: tb; glyph-orientation-vertical: 90;">
   欢迎访问wwww.waylau.com
</text> 
</svg>

SVG <path>路径

2014-05-04 Svg

##7.路径 <path>

下面的命令可用于路径数据:

  • M = moveto
  • L = lineto
  • H = horizontal lineto
  • V = vertical lineto
  • C = curveto
  • S = smooth curveto
  • Q = quadratic Belzier curve
  • T = smooth quadratic Belzier curveto
  • A = elliptical Arc
  • Z = closepath

注释:以上所有命令均允许小写字母。大写表示绝对定位,小写表示相对定位。

####示例7.1 例子定义了一条路径,它开始于位置 250 150,到达位置 150 350,然后从那里开始到 350 350,最后在 250 150 关闭路径。

<svg height="210" width="400">
  <path d="M150 0 L75 200 L225 200 Z" />
</svg>

####示例7.2

A B C
<svg height="400" width="450">
  <path id="lineAB" d="M 100 350 l 150 -300" stroke="red"
  stroke-width="3" fill="none" />
  <path id="lineBC" d="M 250 50 l 150 300" stroke="red"
  stroke-width="3" fill="none" />
  <path d="M 175 200 l 150 0" stroke="green" stroke-width="3"
  fill="none" />
  <path d="M 100 350 q 150 -300 300 0" stroke="blue"
  stroke-width="5" fill="none" />
  <!-- Mark relevant points -->
  <g stroke="black" stroke-width="3" fill="black">
    <circle id="pointA" cx="100" cy="350" r="3" />
    <circle id="pointB" cx="250" cy="50" r="3" />
    <circle id="pointC" cx="400" cy="350" r="3" />
  </g>
  <!-- Label the points -->
  <g font-size="30" font="sans-serif" fill="black" stroke="none"
  text-anchor="middle">
    <text x="100" y="350" dx="-30">A</text>
    <text x="250" y="50" dy="-10">B</text>
    <text x="400" y="350" dx="30">C</text>
  </g>
</svg>

由于绘制路径的复杂性,因此强烈建议您使用 SVG 编辑器来创建复杂的图形。推荐用开源矢量图编辑器Inkscape


SVG Shapes之多边形 <polygon>

2014-05-04 Svg

##5.多边形 <polygon>

####示例5.1

<svg height="210" width="500">
  <polygon points="200,10 250,190 160,210" style="fill:lime;stroke:purple;stroke-width:1" />
</svg> **代码解释:**
  • points 属性定义多边形每个角的 x 和 y 坐标

####示例5.2

<svg height="250" width="500">
  <polygon points="220,10 300,210 170,250 123,234" style="fill:lime;stroke:purple;stroke-width:1" />
</svg>

####示例5.3

<svg height="210" width="500">
  <polygon points="100,10 40,180 190,60 10,60 160,180"
  style="fill:lime;stroke:purple;stroke-width:5;fill-rule:nonzero;" />
</svg>

####示例5.4 fill-rule属性改为”evenodd”

<svg height="210" width="500">
  <polygon points="100,10 40,180 190,60 10,60 160,180"
  style="fill:lime;stroke:purple;stroke-width:5;fill-rule:evenodd;" />
</svg>

SVG Shapes之折线 <polyline>

2014-05-04 Svg

##6.折线 <polyline>

####示例6.1

<svg height="200" width="500">
  <polyline points="20,20 40,25 60,40 80,120 120,140 200,180"
  style="fill:none;stroke:black;stroke-width:3" />
</svg>

####示例6.2

<svg height="180" width="500">
  <polyline points="0,40 40,40 40,80 80,80 80,120 120,120 120,160"
  style="fill:white;stroke:red;stroke-width:4" />
</svg>

SVG Shapes之线条 <line>

2014-05-04 Svg

##4.线条 <line>

####示例4.1

<svg height="210" width="500">
  <line x1="0" y1="0" x2="200" y2="200" style="stroke:rgb(255,0,0);stroke-width:2" />
</svg> **代码解释:**
  • x1 属性在 x 轴定义线条的开始
  • y1 属性在 y 轴定义线条的开始
  • x2 属性在 x 轴定义线条的结束
  • y2 属性在 y 轴定义线条的结束

SVG Shapes之椭圆 <ellipse>

2014-05-04 Svg

##3.椭圆 <ellipse>

####示例3.1

<svg height="140" width="500">
  <ellipse cx="200" cy="80" rx="100" ry="50"
  style="fill:yellow;stroke:purple;stroke-width:2" />
</svg> **代码解释:**
  • cx 属性定义圆点的 x 坐标
  • cy 属性定义圆点的 y 坐标
  • rx 属性定义水平半径
  • ry 属性定义垂直半径

####示例3.2

<svg height="150" width="500">
  <ellipse cx="240" cy="100" rx="220" ry="30" style="fill:purple" />
  <ellipse cx="220" cy="70" rx="190" ry="20" style="fill:lime" />
  <ellipse cx="210" cy="45" rx="170" ry="15" style="fill:yellow" />
</svg> ####示例3.3
<svg height="100" width="500">
  <ellipse cx="240" cy="50" rx="220" ry="30" style="fill:yellow" />
  <ellipse cx="220" cy="50" rx="190" ry="20" style="fill:white" />
</svg>

SVG Shapes之圆形 <circle>

2014-05-04 Svg

##2.圆形 <circle>

####示例2.1

<svg height="100" width="100">
  <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg> **代码解释:**
  • cx 和 cy 属性定义圆点的 x 和 y 坐标。如果省略 cx 和 cy,圆的中心会被设置为 (0, 0)
  • r 属性定义圆的半径

SVG Shapes之矩形 <rect>

2014-05-04 Svg

##SVG 形状 SVG 有一些预定义的形状元素,可被开发者使用和操作:

  • 矩形 <rect>
  • 圆形 <circle>
  • 椭圆 <ellipse>
  • 线 <line>
  • 折线 <polygon>
  • 多边形 <polyline>
  • 路径 <path>

##1.矩形 <rect> ####示例1.1

<svg width="400" height="110">
  <rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
</svg> **代码解释:**
  • rect 元素的 width 和 height 属性可定义矩形的高度和宽度
  • style 属性用来定义 CSS 属性
  • CSS 的 fill 属性定义矩形的填充颜色(rgb 值、颜色名或者十六进制值)
  • CSS 的 stroke-width 属性定义矩形边框的宽度
  • CSS 的 stroke 属性定义矩形边框的颜色

####示例1.2

<svg width="400" height="180">
  <rect x="50" y="20" width="150" height="150"
  style="fill:blue;stroke:pink;stroke-width:5;fill-opacity:0.1;stroke-opacity:0.9" />
</svg> **代码解释:**
  • x 属性定义矩形的左侧位置(例如,x=”0” 定义矩形到浏览器窗口左侧的距离是 0px)
  • y 属性定义矩形的顶端位置(例如,y=”0” 定义矩形到浏览器窗口顶端的距离是 0px)
  • CSS 的 fill-opacity 属性定义填充颜色透明度(合法的范围是:0 - 1)
  • CSS 的 stroke-opacity 属性定义笔触颜色的透明度(合法的范围是:0 - 1)

####示例1.3

<svg width="400" height="180">
  <rect x="50" y="20" width="150" height="150"
  style="fill:blue;stroke:pink;stroke-width:5;opacity:0.5" />
</svg> **代码解释:**
  • CSS 的 opacity 属性定义整个元素的透明值(合法的范围是:0 - 1) 参考:

####示例1.4

<svg width="400" height="180">
  <rect x="50" y="20" rx="20" ry="20" width="150" height="150"
  style="fill:red;stroke:black;stroke-width:5;opacity:0.5" />
</svg> **代码解释:**
  • rx 和 ry 属性可使矩形产生圆角。

####示例1.5

<svg width="400" height="180">
   <rect x="50" y="70" width="35" height="20"
	style="fill: yellow; fill-opacity: 0.5;
  	stroke: green; stroke-width: 2; stroke-dasharray: 5 2"/>
</svg> **代码解释:**
  • stroke-dasharray定义断续线,实线和虚线分别以5和2的长度交替显示。

SVG基本知识

2014-05-04 Svg

##什么是SVG?

  • SVG 指可伸缩矢量图形 (Scalable Vector Graphics)
  • SVG 用来定义用于网络的基于矢量的图形
  • SVG 使用 XML 格式定义图形
  • SVG 图像在放大或改变尺寸的情况下其图形质量不会有所损失
  • SVG 是万维网联盟的标准
  • SVG 与诸如 DOM 和 XSL 之类的 W3C 标准是一个整体
  • SVG 是 W3C 推荐标准
  • SVG 于 2003 年 1 月 14 日成为 W3C 推荐标准。

##SVG 的历史

##SVG 优势 与其他图像格式相比,使用 SVG 的优势在于:

  • SVG 可被非常多的工具读取和修改(比如记事本)
  • SVG 与 JPEG 和 GIF 图像比起来,尺寸更小,且可压缩性更强。
  • SVG 是可伸缩的
  • SVG 图像可在任何的分辨率下被高质量地打印
  • SVG 可在图像质量不下降的情况下被放大
  • SVG 图像中的文本是可选的,同时也是可搜索的(很适合制作地图)
  • SVG 可以与 Java 技术一起运行
  • SVG 是开放的标准
  • SVG 文件是纯粹的 XML

SVG 的主要竞争者是 Flash。

与 Flash 相比,SVG 最大的优势是与其他标准(比如 XSL 和 DOM)相兼容。而 Flash 则是未开源的私有技术。

##查看 SVG 文件

  • 今天,所有浏览器均支持 SVG 文件,不过需要安装插件的 Internet Explorer 除外。插件是免费的,最常用的SVG插件来自Adobe公司(Adobe SVG Viewer),另外Corel也提供SVG浏览器(Corel SVG Viewer)。然而前者宣布于2009年1月1日停止对该产品的支持。
  • 旧版IE、以及移动端浏览器查看svg的另外一个路子SVG向下兼容降级技术或者SVG Fallbacks

##SVG实例 下面的例子是一个简单的 SVG 文件的例子。SVG 文件必须使用 .svg 后缀来保存:

<?xml version="1.0" standalone="no"?>

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg">

<circle cx="100" cy="50" r="40" stroke="black"
stroke-width="2" fill="red"/>

</svg> [查看例子(仅用于支持 SVG 的浏览器)](http://www.w3school.com.cn/svg/circle1.svg) ####代码解释: * 第一行包含了 XML 声明。请注意 standalone 属性!该属性规定此 SVG 文件是否是“独立的”,或含有对外部文件的引用。 standalone="no" 意味着 SVG 文档会引用一个外部文件 - 在这里,是 DTD 文件。 * 第二和第三行引用了这个外部的 SVG DTD。该 DTD 位于 “http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd”。该 DTD 位于 W3C,含有所有允许的 SVG 元素。 * SVG 代码以 &lt;svg&gt;元素开始,包括开启标签 &lt;svg&gt;和关闭标签 &lt;/svg&gt; 。这是根元素。width 和 height 属性可设置此 SVG 文档的宽度和高度。version 属性可定义所使用的 SVG 版本,xmlns 属性可定义 SVG 命名空间。 * SVG 的 &lt;circle&gt;用来创建一个圆。cx 和 cy 属性定义圆中心的 x 和 y 坐标。如果忽略这两个属性,那么圆点会被设置为 (0, 0)。r 属性定义圆的半径。 stroke 和 stroke-width 属性控制如何显示形状的轮廓。我们把圆的轮廓设置为 2px 宽,黑边框。 fill 属性设置形状内的颜色。我们把填充颜色设置为红色。 * 关闭标签的作用是关闭 SVG 元素和文档本身。 ####注释:所有的开启标签必须有关闭标签!

##HTML 页面中的 SVG SVG 文件可通过以下方式嵌入 ####1.使用 <embed> 标签 <embed>标签被所有主流的浏览器支持,并允许使用脚本。

注释:当在 HTML 页面中嵌入 SVG 时使用<embed>标签是 Adobe SVG Viewer 推荐的方法!然而,如果需要创建合法的 XHTML,就不能使用 <embed>。任何 HTML 规范中都没有 <embed>标签。

语法:

<embed src="rect.svg" width="300" height="100" 
type="image/svg+xml"
pluginspage="http://www.adobe.com/svg/viewer/install/" />

注释:pluginspage 属性指向下载插件的 URL。

####2.使用 <object>标签 <object>标签是 HTML 4 的标准标签,被所有较新的浏览器支持。它的缺点是不允许使用脚本。

注释:假如您安装了最新版本的 Adobe SVG Viewer,那么当使用 <object>标签时 SVG 文件无法工作(至少不能在 IE 中工作)!

语法:

<object data="rect.svg" width="300" height="100" 
type="image/svg+xml"
codebase="http://www.adobe.com/svg/viewer/install/" />

注释:codebase 属性指向下载插件的 URL。

####3.使用 <iframe>标签 <iframe> 标签可工作在大部分的浏览器中。

语法:

<iframe src="rect.svg" width="300" height="100">
</iframe> ####4.HTML5原生支持 在新版浏览器里,直接在html里面写即可

语法:

<svg width="100" height="100">
  <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
</svg>

参考: http://zh.wikipedia.org/wiki/%E5%8F%AF%E7%B8%AE%E6%94%BE%E5%90%91%E9%87%8F%E5%9C%96%E5%BD%A2

http://www.w3school.com.cn/svg/svg_intro.asp

[SVG参考手册]http://www.w3cschool.cc/svg/svg-reference.html


Jekyll安装及写静态博客

2014-05-02 Jekyll

下载、安装 ruby 和 DEVELOPMENT KIT

地址http://rubyinstaller.org/downloads/

其中 Ruby 与 DEVELOPMENT KIT 的版本要对应来安装

  • Ruby 1.8.7 and 1.9.3: DevKit-tdm-32-4.5.2-20111229-1559-sfx.exe
  • Ruby 2.0 and 2.1 (32bits version only): DevKit-mingw64-32-4.7.2-20130224-1151-sfx.exe
  • Ruby 2.0 and 2.1 (x64 - 64bits only): DevKit-mingw64-64-4.7.2-20130224-1432-sfx.exe

ruby安装到C:\Ruby193;

DevKit安装到C:\rubydevkit

cd C:\rubydevkit
ruby dk.rb init
ruby dk.rb install

如果是ruby2.0 64位的还需在C:\rubydevkit\config.yml 中添加”- C:\Ruby200-x64”


Github仓库发布成静态页面

2014-04-30 Git

###Github仓库发布成静态页面

  • 1.在仓库(repository)下点击“settings”
  • 2.点击“Automatic Page Generator”
  • 3.点击“Continue To Layouts”
  • 4.选择主题,预览,点击“Publish”

此时,该仓库已经发布为静态网页,网址为“你的用户名.github.io/项目名”; 此时,在原来项目下会建立一个分支“gh-pages”,静态网页需上传到该分支下。

cd repository
git fetch origin
git checkout gh-pages

如果该仓库为用户站点(项目仓库为设定定为“你的用户名.github.com”),直接pull代码到master下就可以了,该网址为“你的用户名.github.io”。此功能可以用来搭建个人主页或者博客。

cd repository
git checkout master
git pull origin master


Sqlserver Check The Number Of Rows Per Table

2014-04-22


layout: post title: SQLServer 查询每个表的行数 date: 2014-04-22 08:51 author: admin comments: true categories: [SQLServer] tags: [SQLServer,查询,行数]

查询每个表的行数

select a.name AS name,b.rows AS rows INTO #Temp1
from EEMS.dbo.sysobjects a LEFT JOIN EEMS.dbo.sysindexes b
ON( a.id=b.id ) WHERE a.type='u' ORDER BY b.rows DESC

SELECT name,max(rows) FROM #Temp1 GROUP BY NAME ORDER BY max(rows) DESC

在Heroku上部署静态网站

2014-04-10 Web

静态网页是无法直接部署在Heroku的,push代码也报错。

解决方法:增加一个index.php,包裹html将静态网站伪装成php网站即可,代码如下:

 <?php
    include_once("index.html");
?>

此时,push 代码,Heroku会自动生成php框架。




用Heroku、snova-c4搭梯子上墙

2014-04-03 Heroku Web

1.snova-c4(翻墙软件)下载

https://code.google.com/p/snova/downloads/list

服务端https://snova.googlecode.com/files/snova-c4-java-server-0.22.0.war

客户端https://snova.googlecode.com/files/gsnova_0.22.1_windows_386.zip

2.在 heroku.com 部署 snova-c4-java-server-0.22.0.war

heroku login

heroku plugins:install https://github.com/heroku/heroku-deploy --只需执行一次,以后不用执行

heroku apps:create --此步创建一个app,名字随机,记住此步的appname("xx.herokuapp.com")。更新不用执行此步

heroku deploy:war --war <path_to_war_file> --app <app_name>

留意执行“heroku apps:create”时的输出,一般会显示创建的域名,为 “xx.herokuapp.com”, 记下该域名,为配置Client准备

输入域名,见下面页面,则说明部署成功

3.解压 gsnova_0.22.1_windows_386.zip

修改gsnova.conf

将GAE的Enable设置为0

C4的Enable设置为1,WorkerNode[0]后面写上你的Heroku二级域名”xx.herokuapp.com”

SPAC的Enable设置为0,确定保存

双击打开gsnova.exe可执行文件。

4.浏览器设置代理

google 就装switchysharp

代理设置端口时要与你在配置文件中设置的端口是一致的。

默认是127.0.0.1 端口48102

翻墙成功


Git简单应用

2014-04-01 Git

First time using Git(首次用git)

cd myproject
git init
# add all your files.  Use can use specific filenames or directories instead of '.'
git add .
git commit -a -m 'Initial commit'
git remote add origin ssh://[email protected]/p/doufe-com/code
git push origin master
git branch --set-upstream master origin/master  # so 'git pull' will work later

Existing repository using Git(已经存在库)

cd myproject
git remote add origin ssh://[email protected]/p/doufe-com/code
git push origin master
git branch --set-upstream master origin/master  # so 'git pull' will work later

用Jersey构建RESTful服务6--Jersey+SQLServer+Hibernate4.3

2014-03-26 Java Jersey REST

#一、总体说明

本例运行演示了用Jersey构建RESTful服务中,如何同过Hibernate将数据持久化进SQLServer的过程

#二、环境

  • 1.上文的项目RestDemo
  • 2.SQLServer2005
  • 3.jtds数据库连接驱动:下载地址最新版本,替换掉上文项目中的mysql-connector

#三、配置

1.与上文mysql的配置不同点主要在hibernate.cfg.xml文件; 配置如下:

<?xml version='1.0' encoding='utf-8'?>  
<!DOCTYPE hibernate-configuration PUBLIC  
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">  
  
<hibernate-configuration>  
   <session-factory>  
   <!-- Database connection settings -->  
        <property name="connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property>  
        <property name="connection.url">jdbc:jtds:sqlserver://192.168.1.10:1433;RestDemo</property>  
        <property name="connection.username">sa</property>  
        <property name="connection.password">aA123456</property>  
        <property name="hibernate.default_schema">RestDemo</property>
        <!-- JDBC connection pool (use the built-in) -->  
        <property name="connection.pool_size">1</property>  
        <!-- SQL dialect -->  
        <property name="dialect">org.hibernate.dialect.SQLServerDialect</property>  
        <!-- Enable Hibernate's automatic session context management -->  
        <property name="current_session_context_class">thread</property>  
        <!-- Disable the second-level cache  -->  
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>  
        <!-- Echo all executed SQL to stdout -->  
        <property name="show_sql">true</property>  
        <!-- Drop and re-create the database schema on startup -->  
        <property name="hbm2ddl.auto">update</property>  
        <mapping resource="com/waylau/rest/bean/User.hbm.xml"/>  
      </session-factory>  
</hibernate-configuration>  

2.修改于mysql不兼容的sql语句com.waylau.rest.dao.impl中的UserDaoImpl:

getUserById修改成如下:

@Override
public User getUserById(String id) {
    SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); 
	Session s = null;
	Transaction t = null;
	User user = null;
	try{
	 s = sessionFactory.openSession();
	 t = s.beginTransaction();
	 String hql = "from User where userId='"+id+"'";  
	 Query query = s.createQuery(hql);  
	 user = (User) query.uniqueResult(); 
	 t.commit();
	}catch(Exception err){
	t.rollback();
	err.printStackTrace();
	}finally{
	s.close();
	}
	return user;
}

getAllUsers给成如下:

@Override
public List<User> getAllUsers() {
    SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); 
	Session s = null;
	Transaction t = null;
	List<User> uesrs = null;
	try{
	 s = sessionFactory.openSession();
	 t = s.beginTransaction();
	 String hql = "select * from [RestDemo].dbo.t_user";  
	 Query query = s.createSQLQuery(hql).addEntity(User.class);  
     //query.setCacheable(true); // 设置缓存  
     uesrs = query.list();  
	 t.commit();
	}catch(Exception err){
	t.rollback();
	err.printStackTrace();
	}finally{
	s.close();
	}
	return uesrs;
}

或者如下:

@Override
public List<User> getAllUsers() {
    SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); 
	Session s = null;
	Transaction t = null;
	List<User> uesrs = null;
	try{
	 s = sessionFactory.openSession();
	 t = s.beginTransaction();
	 String hql = " from User";  
	 Query query = s.createQuery(hql);  
     //query.setCacheable(true); // 设置缓存  
     uesrs = query.list();  
	 t.commit();
	}catch(Exception err){
	t.rollback();
	err.printStackTrace();
	}finally{
	s.close();
	}
	return uesrs;
}

#四、问题

##可能会出现如下错误

ERROR: 指定的架构名称 "RestDemo" 不存在,或者您没有使用该名称的权限。
三月 26, 2014 3:38:43 下午 org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000232: Schema update complete
Hibernate: insert into RestDemo.T_USER (userName, age, USERID) values (?, ?, ?)
三月 26, 2014 3:38:43 下午 org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 208, SQLState: S0002
三月 26, 2014 3:38:43 下午 org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: 对象名 'RestDemo.T_USER' 无效。

##解决方案:

将配置文件中的hibernate.default_schema值修改为如下即可:

<property name="hibernate.default_schema">RestDemo.dbo</property>  

或者去掉上面的配置,在“User.hbm.xml”修改如下

<class name="User" table="T_USER" schema="RestDemo.dbo">  

本章源码https://github.com/waylau/RestDemo/tree/master/jersey-demo6-sqlserver-hibernate

https://github.com/waylau/RestDemo/tree/master/jersey-demo6.2-sqlserver-hibernate


用Jersey构建RESTful服务5--Jersey+MySQL5.6+Hibernate4.3

2014-03-23 Java Jersey REST

#一、总体说明

本例运行演示了用Jersey构建RESTful服务中,如何同过Hibernate将数据持久化进MySQL的过程

#二、环境

1.上文的项目RestDemo

2.MySQL5.6下载http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.16-win32.zip

3.Hibernate4.3.4下载http://sourceforge.net/projects/hibernate/files/hibernate4/4.3.4.Final/hibernate-release-4.3.4.Final.zip

4.Java程序连接MySQL的驱动mysql-connector-java-5.1.29-bin.jar下载 http://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.29.zip

#三、数据库准备

1.搭建MySQL数据库

2.创建数据库RestDemo ,及数据表t_user,结构如下

DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
  `userId` varchar(50) NOT NULL,
  `userName` varchar(50) NOT NULL,
  `age` varchar(50) NOT NULL,
  PRIMARY KEY (`userId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

PS: userId 非自增长类型,需要在业务添加

#四、引入Hibernate

1.解压Hibernate的包,在lib\required文件夹下所有jar引入进项目

2.解压mysql-connector-java-5.1.29.zip,将mysql-connector-java-5.1.29-bin.jar引入进项目

3.在项目的根目录创建hibernate的配置文件hibernate.cfg.xml,内容如下:

<?xml version='1.0' encoding='utf-8'?>  
<!DOCTYPE hibernate-configuration PUBLIC  
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">  
  
<hibernate-configuration>  
   <session-factory>  
   <!-- Database connection settings -->  
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>  
        <property name="connection.url">jdbc:mysql://127.0.0.1:3306/RestDemo</property>  
        <property name="connection.username">root</property>  
        <property name="connection.password"></property>  
  
        <!-- JDBC connection pool (use the built-in) -->  
        <property name="connection.pool_size">1</property>  
  
        <!-- SQL dialect -->  
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>  
  
        <!-- Enable Hibernate's automatic session context management -->  
        <property name="current_session_context_class">thread</property>  
  
        <!-- Disable the second-level cache  -->  
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>  
   
        <!-- Echo all executed SQL to stdout -->  
        <property name="show_sql">true</property>  
  
        <!-- Drop and re-create the database schema on startup -->  
        <property name="hbm2ddl.auto">update</property>  
  
  
        <mapping resource="com/waylau/rest/bean/User.hbm.xml"/>  
   
    </session-factory>  
</hibernate-configuration>  

4.在项目User.java 的同个目录下,创建该类的映射文件User.hbm.xml

<?xml version="1.0"?>  
<!DOCTYPE hibernate-mapping PUBLIC  
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  
  
   
<hibernate-mapping package="com.waylau.rest.bean">  
  
    <class name="User" table="T_USER">  
        <id name="userId" column="USERID"  type="string" >  
            <generator class="assigned"/>  
        </id>  
        <property name="userName" type="string" />  
        <property name="age" type="string" />  
    </class>  
   
</hibernate-mapping>   

5.创建包com.waylau.rest.util,在该包下创建HibernateUtil.java

package com.waylau.rest.util;  
  
import org.hibernate.SessionFactory;  
import org.hibernate.boot.registry.StandardServiceRegistry;  
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;  
import org.hibernate.cfg.Configuration;  
/** 
 * Hibernate 初始化配置工具类 
 * @author waylau.com 
 * 2014-3-23 
 */  
public class HibernateUtil {  
     private static Configuration configuration;  
     private static SessionFactory sessionFactory;  
     private static StandardServiceRegistry standardServiceRegistry;  
        static {  
            try {  
             //第一步:读取Hibernate的配置文件  hibernamte.cfg.xml文件  
              configuration = new Configuration().configure("hibernate.cfg.xml");          
             //第二步:创建服务注册构建器对象,通过配置对象中加载所有的配置信息  
              StandardServiceRegistryBuilder sb = new StandardServiceRegistryBuilder();  
              sb.applySettings(configuration.getProperties());  
             //创建注册服务  
              standardServiceRegistry = sb.build();    
            //第三步:创建会话工厂  
              sessionFactory = configuration.buildSessionFactory(standardServiceRegistry);     
            } catch (Throwable ex) {  
                // Make sure you log the exception, as it might be swallowed  
                System.err.println("Initial SessionFactory creation failed." + ex);  
                throw new ExceptionInInitializerError(ex);  
            }  
        }  
  
        public static SessionFactory getSessionFactory() {  
            return sessionFactory;  
        }  
}  

6.在项目中建com.waylau.rest.dao包,在该包下建立User操作的接口UserDao.java

package com.waylau.rest.dao;  
  
import java.util.List;  
  
import com.waylau.rest.bean.User;  
   
  
/** 
 * User Dao 接口 
 * @author waylau.com 
 * 2014-3-18 
 */  
public interface UserDao {  
      
    public User getUserById(String id);  
  
    public boolean deleteUserById(String id);  
  
    public boolean createUser(User user);  
  
    public boolean updateUser(User user);  
  
    public List<User> getAllUsers();  
}  

7.在项目中建com.waylau.rest.dao.impl包,在该包下建立User操作接口的实现UserDaoImpl.java

package com.waylau.rest.dao.impl;  
  
import java.util.List;  
  
import org.hibernate.Query;  
import org.hibernate.Session;  
import org.hibernate.SessionFactory;  
import org.hibernate.Transaction;  
  
import com.waylau.rest.bean.User;  
import com.waylau.rest.dao.UserDao;  
import com.waylau.rest.util.HibernateUtil;  
/** 
 * 用户DAO实现 
 * @author waylau.com 
 * 2014-3-23 
 */  
public class UserDaoImpl implements UserDao {  
  
    @Override  
    public User getUserById(String id) {  
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();   
        Session s = null;  
        Transaction t = null;  
        User user = null;  
        try{  
         s = sessionFactory.openSession();  
         t = s.beginTransaction();  
         String hql = "from User where userId="+id;    
         Query query = s.createQuery(hql);    
         user = (User) query.uniqueResult();   
         t.commit();  
        }catch(Exception err){  
        t.rollback();  
        err.printStackTrace();  
        }finally{  
        s.close();  
        }  
        return user;  
    }  
  
    @Override  
    public boolean deleteUserById(String id) {  
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();   
        Session s = null;  
        Transaction t = null;  
        boolean flag = false;  
        try{  
         s = sessionFactory.openSession();  
         t = s.beginTransaction();  
         User user = new User();    
         user.setUserId(id);  
         s.delete(user);  
         t.commit();  
         flag = true;  
        }catch(Exception err){  
        t.rollback();  
        err.printStackTrace();  
        }finally{  
        s.close();  
        }  
        return flag;  
    }  
  
    @Override  
    public boolean createUser(User user) {  
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();   
        Session s = null;  
        Transaction t = null;  
        boolean flag = false;  
        try{  
         s = sessionFactory.openSession();  
         t = s.beginTransaction();  
         s.save(user);  
         t.commit();  
         flag = true;  
        }catch(Exception err){  
        t.rollback();  
        err.printStackTrace();  
        }finally{  
        s.close();  
        }  
        return flag;  
    }  
  
    @Override  
    public boolean updateUser(User user) {  
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();   
        Session s = null;  
        Transaction t = null;  
        boolean flag = false;  
        try{  
         s = sessionFactory.openSession();  
         t = s.beginTransaction();  
         s.update(user);  
         t.commit();  
         flag = true;  
        }catch(Exception err){  
        t.rollback();  
        err.printStackTrace();  
        }finally{  
        s.close();  
        }  
        return flag;  
    }  
  
    @Override  
    public List<User> getAllUsers() {  
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();   
        Session s = null;  
        Transaction t = null;  
        List<User> uesrs = null;  
        try{  
         s = sessionFactory.openSession();  
         t = s.beginTransaction();  
         String hql = "select * from t_user";    
         Query query = s.createSQLQuery(hql).addEntity(User.class);    
         query.setCacheable(true); // 设置缓存    
         uesrs = query.list();    
         t.commit();  
        }catch(Exception err){  
        t.rollback();  
        err.printStackTrace();  
        }finally{  
        s.close();  
        }  
        return uesrs;  
    }  
  
}  

8.修改项目中 com.waylau.rest.resources包下的UserResource.java,使之前在内存中模拟CURD转为在数据库中实现

package com.waylau.rest.resources;  
  
import java.util.ArrayList;  
import java.util.List;  
  
import javax.ws.rs.Path;  
import javax.ws.rs.Produces;  
import javax.ws.rs.Consumes;  
import javax.ws.rs.PathParam;  
import javax.ws.rs.core.MediaType;  
import javax.ws.rs.DELETE;  
import javax.ws.rs.GET;  
import javax.ws.rs.POST;  
import javax.ws.rs.PUT;  
  
import com.waylau.rest.bean.User;  
import com.waylau.rest.dao.impl.UserDaoImpl;  
  
/** 
 * 用户资源 
 * @author waylau.com 
 * 2014-3-19 
 */  
@Path("/users")  
public class UserResource {  
    private UserDaoImpl userDaoImpl = new UserDaoImpl();  
    /** 
     * 增加 
     * @param user 
     */  
    @POST  
    @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})  
    public void createUser(User user)  
    {  
        userDaoImpl.createUser(user);  
    }  
      
    /** 
     * 删除 
     * @param id 
     */  
    @DELETE  
    @Path("{id}")  
    public void deleteUser(@PathParam("id")String id){  
        userDaoImpl.deleteUserById(id);  
    }  
      
    /** 
     * 修改 
     * @param user 
     */  
    @PUT  
    @Consumes(MediaType.APPLICATION_XML)  
    public void updateUser(User user){  
        userDaoImpl.updateUser(user);  
    }  
   
    /** 
     * 根据id查询 
     * @param id 
     * @return 
     */  
    @GET  
    @Path("{id}")  
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})  
    public User getUserById(@PathParam("id") String id){  
        User u = userDaoImpl.getUserById(id);  
        return u;  
    }  
     
    /** 
     * 查询所有 
     * @return 
     */  
    @GET  
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})  
    public List<User> getAllUsers(){       
        List<User> users = new ArrayList<User>();     
        users = userDaoImpl.getAllUsers();  
        return users;  
    }  
      
      
}  

#五、运行 1.将服务端运行后

2.运行UserClient客户端,可以看到数据库已经实现增删改查

完整项目架构如下:

本章源码https://github.com/waylau/RestDemo/tree/master/jersey-demo5-mysql-hibernate


用Jersey构建RESTful服务4--通过jersey-client客户端调用Jersey的Web服务模拟CURD

2014-03-19 Java Jersey REST

#一、总体说明

通过jersey-client接口,创建客户端程序,来调用Jersey实现的RESTful服务,实现增、删、改、查等操作。 服务端主要是通过内存的方式,来模拟用户的增加、删除、修改、查询等操作。

#二、创建服务端

1.在上文项目中, 在“com.waylau.rest.resources.UserResource“中修改代码, 首先创建一个HashMap,用来保存添加的用户

private static Map<String,User> userMap  = new HashMap<String,User>();  

2.创建增、删、改、查 用户资源等操作


    /** 
     * 增加 
     * @param user 
     */  
    @POST  
    @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})  
    public void createStudent(User user)  
    {  
        userMap.put(user.getUserId(), user );  
    }  
      
    /** 
     * 删除 
     * @param id 
     */  
    @DELETE  
    @Path("{id}")  
    public void deleteStudent(@PathParam("id")String id){  
        userMap.remove(id);  
    }  
      
    /** 
     * 修改 
     * @param user 
     */  
    @PUT  
    @Consumes(MediaType.APPLICATION_XML)  
    public void updateStudent(User user){  
        userMap.put(user.getUserId(), user );  
    }  
   
    /** 
     * 根据id查询 
     * @param id 
     * @return 
     */  
    @GET  
    @Path("{id}")  
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})  
    public User getUserById(@PathParam("id") String id){  
        User u = userMap.get(id);  
        return u;  
    }  
     
    /** 
     * 查询所有 
     * @return 
     */  
    @GET  
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})  
    public List<User> getAllUsers(){       
        List<User> users = new ArrayList<User>();     
        users.addAll( userMap.values() );    
        return users;  
    }  

#三、创建客户端程序

1.创建包“com.waylau.rest.client”,在包下建一个UserClient.java,代码如下:


	package com.waylau.rest.client;  
	  
	import javax.ws.rs.client.Client;  
	import javax.ws.rs.client.ClientBuilder;  
	import javax.ws.rs.client.Entity;  
	import javax.ws.rs.client.WebTarget;  
	import javax.ws.rs.core.MediaType;  
	import javax.ws.rs.core.Response;  
	  
	import org.codehaus.jackson.jaxrs.JacksonJsonProvider;  
	  
	import com.waylau.rest.bean.User;  
	  
	   
	/** 
	 * 用户客户端,用来测试资源 
	 * @author waylau.com 
	 * 2014-3-18 
	 */  
	public class UserClient {  
	  
	    private static String serverUri = "http://localhost:8089/RestDemo/rest";  
	    /** 
	     * @param args 
	     */  
	    public static void main(String[] args) {  
	        addUser();  
	        getAllUsers();  
	        updateUser();  
	        getUserById();  
	        getAllUsers();  
	        delUser();  
	        getAllUsers();  
	  
	    }  
	    /** 
	     * 添加用户 
	     */  
	     private static void addUser() {  
	         System.out.println("****增加用户addUser****");  
	         User user = new User("006","Susan","21");    
	         Client client = ClientBuilder.newClient();  
	         WebTarget target = client.target(serverUri + "/users");  
	         Response response = target.request().buildPost(Entity.entity(user, MediaType.APPLICATION_XML)).invoke();  
	         response.close();  
	    }  
	       
	    /** 
	     * 删除用户 
	     */  
	     private static void delUser() {  
	         System.out.println("****删除用户****");  
	         Client client = ClientBuilder.newClient();  
	         WebTarget target = client.target(serverUri + "/users/006");  
	         Response response = target.request().delete();  
	         response.close();  
	    }  
	       
	       
	    /** 
	     * 修改用户 
	     */  
	     private static void updateUser() {  
	         System.out.println("****修改用户updateUser****");  
	         User user = new User("006","Susan","33");    
	         Client client = ClientBuilder.newClient();  
	         WebTarget target = client.target(serverUri + "/users");  
	         Response response = target.request().buildPut( Entity.entity(user, MediaType.APPLICATION_XML)).invoke();  
	         response.close();  
	    }  
	    /** 
	     * 根据id查询用户 
	     */  
	     private static void getUserById() {  
	         System.out.println("****根据id查询用户****");  
	         Client client = ClientBuilder.newClient().register(JacksonJsonProvider.class);// 注册json 支持  
	         WebTarget target = client.target(serverUri + "/users/006");  
	         Response response = target.request().get();  
	         User user = response.readEntity(User.class);  
	         System.out.println(user.getUserId() + user.getUserName()  +  user.getAge());  
	         response.close();  
	    }  
	    /** 
	     * 查询所有用户 
	     */  
	     private static void getAllUsers() {  
	         System.out.println("****查询所有getAllUsers****");  
	           
	         Client client = ClientBuilder.newClient();  
	  
	         WebTarget target = client.target(serverUri + "/users");  
	         Response response = target.request().get();  
	 		 String value = response.readEntity(String.class);  
	    	 System.out.println(value);  
			 response.close();  //关闭连接  
	     }  
	       
	}  

#四、运行 启动服务端项目,运行客户端程序UserClient,控制台输出如下

****增加用户addUser****  
****查询所有getAllUsers****  
[{"userId":"006","userName":"Susan","age":"21"}]  
****修改用户updateUser****  
****根据id查询用户****  
006Susan33  
****查询所有getAllUsers****  
[{"userId":"006","userName":"Susan","age":"33"}]  
****删除用户****  
****查询所有getAllUsers****  
[]  

#五、总结 1.客户端如果需要进行JSON转换,需要进行JSON注册

Client client = ClientBuilder.newClient().register(JacksonJsonProvider.class);  

2.WebTarget 指明了要请求的资源的地址

3.target.request(). 后面跟的是请求的方法:POST,GET,PUT或DELETE

本章源码https://github.com/waylau/RestDemo/tree/master/jersey-demo4-client-curd


用Jersey构建RESTful服务3--JAVA对象转成JSON输出

2014-03-17 Java Jersey REST

#一、 总体说明

XML和JSON 是最为常用的数据交换格式。本例子演示如何将java对象,转成JSON输出。

#二、流程

  • 1.在上文项目中, 在“com.waylau.rest.resources.UserResource“中增加代码,代码如下:
	@GET    
	@Path("/getUserJson")    
	@Produces(MediaType.APPLICATION_JSON)    
	public User getUserJson() {    
	 User user  = new User();    
	 user.setAge("27");    
	 user.setUserId("005");    
	 user.setUserName("Fmand");    
	 return user;    
	}   

MediaType.APPLICATION_JSON 说明输出的是JSON格式

	org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyWriter not found for media type=application/json, type=class com.waylau.rest.bean.User, genericType=class com.waylau.rest.bean.User.  
	    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:247)  
	    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)  
	    at org.glassfish.jersey.filter.LoggingFilter.aroundWriteTo(LoggingFilter.java:293)  
	    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)  
	    at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:103)  
	    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)  
	    at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:88)  
	    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)  
	    at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1154)  
	    at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:571)  
	    at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:378)  
	    at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:368)  
	    at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:262)  

此时,需要获取json转换包的支持 。 可以由多种方式实现:MOXy、JSON-P、Jackson、Jettison等,本例为Jackson。

    1. jackson-all-1.9.11.jar 下载地址http://wiki.fasterxml.com/JacksonDownload
    1. 项目中引入jackson-all-1.9.11.jar
  • 5.在“com.waylau.rest”目录下创建RestApplication.java
package com.waylau.rest;  
  
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;  
import org.glassfish.jersey.filter.LoggingFilter;  
import org.glassfish.jersey.server.ResourceConfig;  
   
/** 
 * 应用 
 * @author waylau.com 
 * 2014-3-18 
 */  
public class RestApplication extends ResourceConfig {  
    public RestApplication() {  
   
     //服务类所在的包路径  
     packages("com.waylau.rest.resources");  
     //注册JSON转换器  
     register(JacksonJsonProvider.class);  
   
    }  
}  
  • 6.修改web.xml,初始化从RestApplicaton进入应用,如下:
<servlet>    
     <servlet-name>Way REST Service</servlet-name>  
     <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>  
      <init-param>  
           <param-name>javax.ws.rs.Application</param-name>  
           <param-value>com.waylau.rest.RestApplication</param-value>  
       </init-param>  
       
    <load-on-startup>1</load-on-startup>  
  </servlet>  
    
  <servlet-mapping>  
    <servlet-name>Way REST Service</servlet-name>  
    <url-pattern>/rest/*</url-pattern>  
  </servlet-mapping>  

本章源码https://github.com/waylau/RestDemo/tree/master/jersey-demo3-json


Way Lau

Software Engineer and Full Stack Developer, now work and live in Shenzhen, China. Detail

Donate

See the list of Donors.