在Heroku上部署静态网站
2014-04-10 Web静态网页是无法直接部署在Heroku的,push代码也报错。
解决方法:增加一个index.php,包裹html将静态网站伪装成php网站即可,代码如下:
<?php
include_once("index.html");
?>
此时,push 代码,Heroku会自动生成php框架。
静态网页是无法直接部署在Heroku的,push代码也报错。
解决方法:增加一个index.php,包裹html将静态网站伪装成php网站即可,代码如下:
<?php
include_once("index.html");
?>
此时,push 代码,Heroku会自动生成php框架。
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
翻墙成功
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
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服务中,如何同过Hibernate将数据持久化进SQLServer的过程
#二、环境
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服务中,如何同过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-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
#一、 总体说明
XML和JSON 是最为常用的数据交换格式。本例子演示如何将java对象,转成JSON输出。
#二、流程
@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。
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);
}
}
<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
##一、 总体说明 XML和JSON 是最为常用的数据交换格式。本例子演示如何将java对象,转成XML输出。 ##二、流程
package com.waylau.rest.bean;
import javax.xml.bind.annotation.XmlRootElement;
/* *
* 用户 bean
* @author waylau.com
* 2014-3-17
*/
@XmlRootElement
public class User {
private String userId;
private String userName;
private String age;
public User() {};
public User(String userId, String userName, String age) {
this.userId = userId;
this.userName = userName;
this.age = age;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
注意:该类上面增加了一个注解“@XmlRootElement”,在将该类转化成XML时,说明这个是XML的根节点。
package com.waylau.rest.resources;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
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;
@Path("/users")
public class UserResource {
private static Map<String,User> userMap = new HashMap<String,User>();//存储用户
/**
* 查询所有
* @return
*/
@GET
@Produces(MediaType.APPLICATION_XML)
public List<User> getAllUsers(){
List<User> users = new ArrayList<User>();
User u1 = new User("001","WayLau","26");
User u2 = new User("002","King","23");
User u3 = new User("003","Susan","21");
userMap.put(u1.getUserId(), u1);
userMap.put(u2.getUserId(), u2);
userMap.put(u3.getUserId(), u3);
users.addAll( userMap.values() );
return users;
}
@GET
@Path("/getUserXml")
@Produces(MediaType.APPLICATION_XML)
public User getUserXml() {
User user = new User();
user.setAge("21");
user.setUserId("004");
user.setUserName("Amand");
return user;
}
}
其中MediaType.APPLICATION_XML 说明了是以XML形式输出
在浏览器输入http://localhost:8089/RestDemo/rest/users/getUserXml,输出单个对象
在浏览器输入 http://localhost:8089/RestDemo/rest/users 输出对象的集合
本章源码:https://github.com/waylau/RestDemo/tree/master/jersey-demo2-xml
#一、环境
#二、流程
package com.waylau.rest.resources;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType;
@Path("/hello")
public class HelloResource {
@GET @Produces(MediaType.TEXT_PLAIN)
public String sayHello()
{
return "Hello World!" ;
}
@GET @Path("/{param}")
@Produces("text/plain;charset=UTF-8")
public String sayHelloToUTF8(@PathParam("param") String username)
{
return "Hello " + username;
}
}
<servlet>
<servlet-name>Way REST Service</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.waylau.rest.resources</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>
http://localhost:8089/RestDemo/rest/hello/Way你好吗,输出Hello Way你好吗
参考:https://jersey.java.net/documentation/latest/user-guide.html
本章源码:https://github.com/waylau/RestDemo/tree/master/jersey-demo1-helloworld
图标中的文本如果太长就显示不全了。
查API ,
Label继承了TextBase,而 TextBase有maxDisplayedLines属性,表述如下:
确定是否截断文本以及在何处截断文本的整数。
刚换了win7系统 ,原有Flex项目中的字体显示出现不一致的情况,如下图
且,几部电脑安装该系统盘均出现上述情况,而用另外系统碟装的系统却正常。 由于该Flash项目调用的是系统中的字库,可初步判断是字库的问题 。
解决:更换系统字库
在C:\Windows\Fonts 目录下 存放的就是系统所有的字体,
更换也挺简单,只需要复制其他系统的全部字体过来,覆盖该系统的字体即可
近期项目发现,在使用release发布项目包,图片找不到了,而debug下面又有图片。
后来发现,原来图片被另外一个组件嵌入了。
下面例子展示了组件嵌入和不嵌入图片的区别
<?xml version=”1.0″ encoding=”utf-8″?>
<s:Application xmlns:fx=”http://ns.adobe.com/mxml/2009″ xmlns:s=”library://ns.adobe.com/flex/spark” xmlns:mx=”library://ns.adobe.com/flex/mx” minWidth=”955″ minHeight=”600″>
<fx:Declarations>
<!– Flex项目release后图片资源不见了—-图片资源采用嵌入与不嵌入的区别 更多示例请访问www.waylau.com–>
</fx:Declarations>
<s:VGroup>
<s:Panel title=”嵌入测试”>
<s:HGroup>
<s:Button id=”btn1″ icon=”@Embed(source=’images/close.png’)”/>
<s:Button id=”btn2″ icon=”images/close.png”/>
</s:HGroup>
</s:Panel>
<s:Panel title=”未嵌入测试”>
<s:HGroup> <s:Button id=”btn3″ icon=”images/myIco.png”/> <s:Button id=”btn4″ icon=”images/myIco.png”/> </s:HGroup>
</s:Panel>
</s:VGroup>
</s:Application>
btn1嵌入了的图片,btn2就无法引用了, 而btn3、btn4没有嵌入,所以都可以引用。 看release的文件btn1嵌入的图片close.png是看不到的,已经嵌入进swf, 而myIco.png是存在的。
嵌入图片和不嵌入图片各有利弊,嵌入图会加快访问图片的速度,但同时也增大了编译文件, 以下是一个错误的示例,多个文件嵌入了同一份资源save24.png,使得每个swf文件都变大了。要按照实际需要选择
在上面的例子中当多个控件引用的是同一个资源时,嵌入图片用简单的变量访问方式,在多个地方引用所嵌入的资源。 这是变量就代表资源,提高写代码的效率
<?xml version=”1.0″ encoding=”utf-8″?>
<s:Application xmlns:fx=”http://ns.adobe.com/mxml/2009″ xmlns:s=”library://ns.adobe.com/flex/spark” xmlns:mx=”library://ns.adobe.com/flex/mx” minWidth=”955″ minHeight=”600″>
<fx:Declarations>
<!– Flex项目release后图片资源不见了,图片资源采用嵌入与不嵌入的区别 更多示例请访问www.waylau.com–>
</fx:Declarations>
<fx:Script>
<![CDATA[ [Embed(source="images/close.png")] [Bindable] public var imgCls:Class; ]]>
</fx:Script>
<s:VGroup>
<s:Panel title=”嵌入测试”>
<s:HGroup>
<s:Button id=”btn1″ icon=”{imgCls}”/>
<s:Button id=”btn2″ icon=”{imgCls}”/>
</s:HGroup>
</s:Panel>
<s:Panel title=”未嵌入测试”>
<s:HGroup>
<s:Button id=”btn3″ icon=”images/myIco.png”/>
<s:Button id=”btn4″ icon=”images/myIco.png”/>
</s:HGroup>
</s:Panel>
</s:VGroup>
</s:Application>
核心代码
s=”该分类下没有应用”;
myTip = ToolTipManager.createToolTip(s,event.currentTarget.x + event.currentTarget.width, event.currentTarget.y+50,null, IUIComponent(event.currentTarget)) as ToolTip;
myTip.setStyle(“styleName”, “errorTip”);
myTip.width = 135;
myTip.height = 55样式 <fx:Style>
@namespace s “library://ns.adobe.com/flex/spark”;
@namespace mx “library://ns.adobe.com/flex/mx”;
.errorTip {
borderColor: #1F1F27;
backgroundColor :#1F1F27;
color: #ffffff;
fontFamily: Base02Embedded;
fontSize: 12;
fontWeight: normal;
}
</fx:Style>
从惠州骑行至厦门,三天骑行 600+ 公里,我们做到了!!
六字概况谓之“天时地利人和”。
打开Android的官网http://www.android.com/ 没有问题,但是
想打开首页的”developers”http://developer.android.com/ 却不行,明显被墙了。
解决方案:请移步至http://developer.android.com.nyud.net 就OK了
CorelDRAW X4打开文件时,很卡,
首先,要确保你的文件和你的软件所在的硬盘要有充足的空间,别傻X的直接在U盘里面打开文件。
最好,放在除C盘以外的其他硬盘。
其次,来吧,安装补丁立马见效。 1.下载 下载地址: http://pan.baidu.com/share/link?shareid=1297224101&uk=907556543
2.解压 解压后有两个安装文件
3.安装 分别双击安装上述两个文件即可,默认安装即可
##一、下载
下载页面http://maven.apache.org/download.cgi 找到最新的 ,本例为Maven 3.1.0
http://mirrors.cnnic.cn/apache/maven/maven-3/3.1.0/binaries/apache-maven-3.1.0-bin.zip
##二、安装
1.解压zip ,将apache-maven-3.1.0文件夹拷贝至C:\Program Files\Apache Software Foundation 目录下
2.在环境变量中添加一个用户变量(如果不成功,也可以添加到系统变量中)
变量:M2_HOME
值:C:\Program Files\Apache Software Foundation\apache-maven-3.1.0
3.在环境变量中的系统变量的path添加一个
%M2_HOME%\bin
4.校验
Cmd 模式下 输入
mvn --version
出现以下画面,则安装成功!
##三、配置
建一个文件夹作为仓位:
我的是在d:\ workspaceMaven
C:\Program Files\Apache Software Foundation\apache-maven-3.1.0\conf
目录下找到
settings.xml文件,
打开文件找到被注释的 <localRepository>/path/to/local/repo</localRepository>
将它启动,写上仓库的路径,
即为<localRepository>D:\workspaceMaven</localRepository>
如下效果
打开cmd,输入
mvn help:system
如果配置正确,将开始从中央仓库下载文件至4中配置的本地仓库。该过程持续时间因网络带宽影响可能持续时间很长。
见下图,则配置成功
仓库下会多出很多文件
##四、使用
找一个maven的项目。本例为“cat78”,放到任意目录下
2.cmd 下 执行cd cat78到该目录下
运行
mvn clean compile
此时,项目开始编译
又需要一段时间来下载相关jar包、pom文件
3.编译完成 ,会生产.bat可运行文件,双击运行就行了~
完整的使用教程,请访问使用maven编译Java项目
一、 首先电脑要具备.Net Framework 4 以上环境 二、 MySQL下载、安装、执行
选中“Skip the check for updates” ,Next
选中“custom”,Next
Next
Execute
Next
Execute
Next
Next
Next
设置root密码“root”,Next
Next
Next
Next
Finish
Databases->Query Database
连接本地实例“Local instance MySQL 56”,OK
填密码,选中保存,OK
输入查询语句,CREATE DATABASE waylau DEFAULT CHARACTER SET ‘utf8’;
use waylau;
create table users (user_no char(5) not null, user_name char(50) );
执行
刷新左侧树形栏,出现刚刚执行的库和表,则说明使用成功!!
package
{
import flash.net.NetConnection;
import flash.net.ObjectEncoding;
import flash.net.Responder;
public class Amf3ServiceInvoker
{
private var nc : NetConnection = new NetConnection();
private var responder : Responder = null;
private const amf3URL : String = “http://gcc.waylau.com:8080/messagebroker/amf”;
public function Amf3ServiceInvoker(result : Function, error : Function)
{
responder = new Responder(result, error);
super();
}
public function getWeather2(city: String) : void{
nc.objectEncoding = ObjectEncoding.AMF3;
nc.connect(amf3URL);
nc.call(“amf3ServiceInvoker.getWeather2″, responder, city);
}
}
}
一行三人,出门还有丝丝细雨。于是放弃了防晒装备(后面因此付出代价) 骑行的线路大致是酱紫滴 惠州学院对面,华康医院附近出发, 沿演达大道,向北 下演达立交,进入三环南路,经过师大立交,进入仲恺大道 下面的路段,基本上是闭着眼睛也不会走错啦~
补过,过仲恺的时候确实应该发下牢骚, 这路确实是太狗血了~啦~见图~
并且在这途中,还遗失了一位队友, 顶。~
后来 还是 找回来啦~ 咔咔
托了高铁的福,我一直叫他沿着高铁柱子走。~
继续出发
仲恺五路、仲恺六路、仲恺八路,过沥林镇,谢岗镇,樟木头镇,黄江镇一路都是笔直的 樟木头和黄江有一大坡相隔,需要冲坡!!
只要沿着大道走,就不会走X 。 出黄江镇再走一段,就要准备左转了。~ 地图导航显示的位置大概是 金朗南路的杨涌村,往西南方向走, 擦~ 全是 村间小道 ,感觉地图导航坑了我~ 不过经过新马莲村,却意外看到了一池子 好荷花! 正是好景六月中,风光不与四时同也~
一直吧,跨过那漫漫的田野, 擦~ 人迹开始罕见~ 晴空开始骄阳 除了几个工业区。 最后竟然还走到了路的尽头~
。。。汗。没路了后,只好右拐穿过莞佛高速~ 到达东莞水平商贸城,
看地图离目的地址不远,遂先填饱肚子 一碗木桶饭顶住先~
饭饱后继续前行,沿着美景西路(X241) 到达西牛陂广场 ,就要往小路往西走了~
直到 环湖路 环湖路 环的就是松山湖啊 ,亲,差不多到了~
再往西走一段路程,就能看到大门,进了门,就 尽情的绕湖吧~~~~~~~~
景区内还有马术场,不错,威远
回程路线:
绕完湖,沿着大学路朝大朗方向走,
无需约定,路程中,总能相会~
沿美景中路、美景东路,到达大朗镇,
至此与队友分别,
这些哥们实在是顶不住了。 独自再沿金朗中路、黄江方向 直线 飚回惠州, 期间口渴的不行, 买了瓶2L美年达,呼呼一口气干了二分之一,爽啊!!!!!
行吧,最后一张金华火腿
总结: 去程约77公里,全程往返154公里左右(数据来源百度地图) 花费: 康师傅矿泉水550ml 2元 木桶饭 8元 美年达 汽水2L 7元 共计17元
package
{
import flash.display.Sprite;
import org.aswing.ASColor;
import org.aswing.JScrollPane;
import org.aswing.JTable;
import org.aswing.VectorListModel;
import org.aswing.event.SelectionEvent;
import org.aswing.table.PropertyTableModel;
import org.aswing.table.sorter.TableSorter;
/**
* 一个AsWing JTable的例子
*@author waylau.com
*@data 2013-7-26
*/
public class JTableExample extends Sprite
{
private var data:Array = []; //表格数据源
private var columns:Array = []; //列项
private var table:JTable;
/**
* PropertyTableModel是JTable的表格模型之一,常常用于把一个对象列表中的对象数据,以对象为行,
* 以对象属性为列来显示,它提供默认方式把属性值以直接字符串化显示,也提供转换器(PropertyTranslator 或Function)
* 把值转换成期望的字符串格式来显示
*/
private var tableModel:PropertyTableModel;
/**
* VectorListModel是AsWing自带的ListModel 实现,它的行为类似一个Vector,
* 可以随意在任何位置插入/删除数据,并且在数据改变时,会自动触发对应的事件,使得JList 自动更新界面显示。
*/
private var modeList:VectorListModel;
/**
* TableSorter表格排序器。它是TableModel 接口的一个实现,通过包装一个现有的 TableModel 来实现排序。
* 实现原理为:以选择排序方式为基准,变换原始TableModel 类的行的值,以达到变换行顺序的目的。
* 排序所采用的值比较函数,可以通过给指定列设定列类型,然后给指定列类型设定比较函数来达到。
* 默认情况下,所有列的类型都是Object 类型,TableSorter 自带String 和Number 类型的比较函数,
* 对于没有指定比较函数的列,默认将采用String 类型的比较函数
*/
private var sorter:TableSorter;
public function JTableExample()
{
super();
init();
}
private function init():void
{
this.stage.frameRate = 25;
data = [{name:"iiley", sex:1, age:26, score:99},
{name:"Comeny", sex:0, age:24, score:100},
{name:"Tom", sex:1, age:30, score:98},
{name:"Lita", sex:0, age:16, score:36}]
;
modeList = new VectorListModel(data);
columns = ["Name", "Sex", "age", "Score"] ;
tableModel = new PropertyTableModel(modeList,columns,["name","sex","age","score"],[null,sexTranslator,null,null,]);
sorter = new TableSorter(tableModel);
this.table = new JTable(sorter);
this.table.setRowHeight(22);
//水平间隔线
table.setShowHorizontalLines(false);
//竖直间隔线
table.setShowVerticalLines(false);
//设置字体颜色,前景色
table.setForeground(new ASColor(0xffffff));
//设置选中行的时候的字体颜色
table.setSelectionForeground(new ASColor(0x123456));
//拉伸的模式,随意拉伸
this.table.setAutoResizeMode ( JTable.AUTO_RESIZE_OFF );
//只能选择一行
this.table.setSelectionMode ( JTable.SINGLE_SELECTION );
//设置表格底色
this.table.setBackground(new ASColor(0x000000));
//设置监听row选中
this.table.addEventListener(SelectionEvent.ROW_SELECTION_CHANGED,__rowSelectHandler);
var panel:JScrollPane = new JScrollPane();
panel.setSizeWH(200, 100);
panel.append(this.table);
this.addChild(panel);
panel.validate();
}
/**
* row选择执行事件
*/
private function __rowSelectHandler(e:SelectionEvent):void
{
var rowCount : int = this.table.getSelectedRow();
if(rowCount>0)
{
var row:Object = modeList.getElementAt(sorter.modelIndex(rowCount));
}
if(row!=null)
{
trace("Human"+" Name:"+row.name+",Sex:"+row.sex+",Age:"+row.age+",Score:"+row.score);
}
}
/**
* 性别转换器
*/
private function sexTranslator(info:*, key:String):String
{
if(info[key]=="1")
{
return "男";
}
else
{
return "女";
}
}
}
} 参考:
http://www.aswing.org/?tag=jtable
在Flash CS4中打开“D:\Program Files\Adobe\Adobe Flash CS4\Common\Configuration\Components\”目录下的“User Interface.fla”文件 进入文件—发布设置—Flash—勾选“导出SWC” 点“导出影片”,输入文件名,确定之后就出现了swc文件 进入Flash builder,在ActionScript项目属性中引用刚刚导出的swc文件 这时就可以在源代码中 import fl.controls.* 并使用Flash CS4中的UI组件了
另外fl.controls.DataGrid的详细应用
参见:http://edutechwiki.unige.ch/en/Flash_datagrid_component_tutorial
##一、基本概念
Thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 等等编程语言间无缝结合的、高效的服务。
Thrift最初由facebook开发,07年四月开放源码,08年5月进入apache孵化器。thrift允许你定义一个简单的定义文件中的数据类型和服务接口。以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。
###1.数据类型
基本类型: bool:布尔值,true 或 false,对应 Java 的 boolean byte:8 位有符号整数,对应 Java 的 byte i16:16 位有符号整数,对应 Java 的 short i32:32 位有符号整数,对应 Java 的 int i64:64 位有符号整数,对应 Java 的 long double:64 位浮点数,对应 Java 的 double string:utf-8编码的字符串,对应 Java 的 String 结构体类型: struct:定义公共的对象,类似于 C 语言中的结构体定义,在 Java 中是一个 JavaBean 容器类型: list:对应 Java 的 ArrayList set:对应 Java 的 HashSet map:对应 Java 的 HashMap 异常类型: exception:对应 Java 的 Exception 服务类型: service:对应服务的类
###2.服务端编码基本步骤:
实现服务处理接口impl 创建TProcessor 创建TServerTransport 创建TProtocol 创建TServer 启动Server 3.客户端编码基本步骤:
创建Transport 创建TProtocol 基于TTransport和TProtocol创建 Client 调用Client的相应方法 4.数据传输协议
TBinaryProtocol : 二进制格式. TCompactProtocol : 压缩格式 TJSONProtocol : JSON格式 TSimpleJSONProtocol : 提供JSON只写协议, 生成的文件很容易通过脚本语言解析 tips:客户端和服务端的协议要一致
##二、as3与java通信示例
test.thrift namespace java com.xzw.thrift namespace as3 com.xzw.thrift struct User{ 1:i32 userId, 2:string loginName, 3:string password, 4:string name }
exception UserNotFound{
1:string msg //as3中由于message是关键字,所以避免使用message关键字。
}
service UserService{
User getUser(1:string loginName) throws (1:UserNotFound unf),
list<User> getUsers()
} 通过命令生成java代码
thrift –gen java test.thrift
以上命令会生成gen-java的目录拷贝里面的代码到你的项目中。如图com.xzw.thrift就是
工具生成java类。
其中我们需要去实现UserService类中的IFace接口。代码如下: /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.xzw.service; |
import com.xzw.thrift.User;
import com.xzw.thrift.UserNotFound;
import com.xzw.thrift.UserService;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import org.apache.thrift.TException;
/**
*
* @author xzw
*/
public class UserServiceHandler implements UserService.Iface{
public User getUser(String loginName) throws UserNotFound, TException {
if(!"xuzhiwei".equals(loginName)){
UserNotFound e = new UserNotFound("用户无法找到!");
throw e;
}
User user = new User();
user.setUserId(100);
user.setLoginName("xuzhiwei");
user.setPassword("123456");
user.setName("user1");
Logger.getLogger("user=>"+user.toString());
return user;
}
public List<User> getUsers() throws TException {
List<User> list = new ArrayList<User>();
User user = new User();
user.setUserId(100);
user.setLoginName("xuzhiwei");
user.setPassword("123456");
user.setName("user1");
list.add(user);
User user2 = new User();
user2.setUserId(200);
user2.setLoginName("login2");
user2.setPassword("pwd2");
user2.setName("user2");
list.add(user2);
Logger.getLogger("user list=>"+list.toString());
return list;
}
}
编写servlet,servlet需要继承thrift提供的类包TServlet即可,不需要去重写doGet,doPost方法。 /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.xzw.service; |
import com.xzw.thrift.UserService;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServlet;
/**
*
* @author xzw
*/
public class UserServlet extends TServlet{
public UserServlet(){
super(new UserService.Processor(new UserServiceHandler()),new TBinaryProtocol.Factory(true, true));
}
}
以上就完成服务器端的编写了。
可以使用junit测试一下: /* * To change this template, choose Tools | Templates * and open the template in the editor. */ |
import com.xzw.thrift.User;
import com.xzw.thrift.UserService;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.THttpClient;
import org.junit.*;
/**
*
* @author xzw
*/
public class TestServlet {
@Test
public void test(){
String serveltUrl = "http://localhost:8080/test_thrift/userServlet";
try {
THttpClient thc = new THttpClient(serveltUrl);
TProtocol lopFactory = new TBinaryProtocol(thc);
UserService.Client client = new UserService.Client(lopFactory);
List users = client.getUsers();
System.out.println("-->>"+users.toString());
} catch (TException ex) {
Logger.getLogger(TestServlet.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Test
public void test2(){
String serveltUrl = "http://localhost:8080/test_thrift/userServlet";
try {
THttpClient thc = new THttpClient(serveltUrl);
TProtocol lopFactory = new TBinaryProtocol(thc);
UserService.Client client = new UserService.Client(lopFactory);
User user = client.getUser("xuzhiwei");
System.out.println("-->"+user.toString());
} catch (TException ex) {
Logger.getLogger(TestServlet.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
接下来生成as3代码
thrift –gen as3 test.thrift www.it165.net
以上代码会生成gen-as3的目录,拷贝目录下的代码到你的工程中。
编写as3客户端类:
package {
import com.xzw.thrift.User;
import com.xzw.thrift.UserNotFound;
import com.xzw.thrift.UserService;
import com.xzw.thrift.UserServiceImpl;
import flash.display.Sprite;
import flash.net.URLRequest;
import flash.text.TextField;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.THttpClient;
public class testthrift extends Sprite
{
private const SERVER_URL:String = "http://localhost:8080/test_thrift/userServlet";
private var textField:TextField;
public function testthrift()
{
init();
connServer();
}
private function init():void
{
textField = new TextField();
textField.width = 300;
textField.height = 500;
textField.autoSize = "left";
addChild(textField);
}
private function connServer():void
{ //实例化URLRequest
var urlRequest:URLRequest = new URLRequest(SERVER_URL);
//实例化THttpClient
var thc:THttpClient = new THttpClient(urlRequest);
var protocol:TProtocol = new TBinaryProtocol(thc);
var usImpl:UserService = new UserServiceImpl(protocol);
usImpl.getUser("xuzhiwei",onError,onUserSuccess);
//usImpl.getUsers(onError,onSuccess);
}
private function onError(e:UserNotFound):void{
trace(e);
}
private function onUserSuccess(user:User):void{
trace("success:");
trace(user);
textField.text = user.toString();
}
private function onSuccess(user:Array):void{
trace(user);
textField.text = user.toString();
}
}
}
写完了,测试结果
项目中,对JasperReports-4.1.2核心包进行了升级,发现,前端flex无法对JasperReports的格式进行解析了~
iReport 4.1 设计的模版可以解析,而iReport 4.6 设计的模版就不行了~
断点后,对比了从后台传过来的JasperReports 的xml数据,发现存在差异
4.1.2包生成的xml数据jasperPrint标签为:
<jasperPrint name="report13" pageWidth="842" pageHeight="842" topMargin="0" leftMargin="0" bottomMargin="0" rightMargin="0" locale="zh_CN" timezone="Asia/Shanghai"> 5.1.2包生成的xml数据jasperPrint标签为:
<jasperPrint xmlns="http://jasperreports.sourceforge.net/jasperreports/print"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/print
http://jasperreports.sourceforge.net/xsd/jasperprint.xsd" name="report13"
pageWidth="842" pageHeight="842" topMargin="0" leftMargin="0" bottomMargin="0"
rightMargin="0" locale="zh_CN" timezone="Asia/Shanghai">
后期版本的JasperReports核心包多生成了命名空间
而之前官方提供JasperReports 的flex解析包net.sf.jasperreports.flex (来自JasperReports的项目示例jasperreports-flash-4.0.0-project.zip)任然停留在2010年的版本未更新(估计JasperReports放弃了对flash的支持),导致无法对新版本的xml数据进行解析
AS3对于带命名空间的XML的解析操作上有很大的差异,例如以下来自JasperReports的ReportFactory.as
var props:XMLList = xml.property;
for each (var prop:XML in props)
{
if (prop.@name == "net.sf.jasperreports.export.xml.start.page.index")
{
report.startPageIndex = int(prop.@value);
}
if (prop.@name == "net.sf.jasperreports.export.xml.end.page.index")
{
report.endPageIndex = int(prop.@value);
}
if (prop.@name == "net.sf.jasperreports.export.xml.page.count")
{
report.pageCount = int(prop.@value);
}
}
由于新版本多了命名空间,所以 直接xml.property 是无法获取到property的。要带上命名空间
var ns:Namespace = new Namespace("http://jasperreports.sourceforge.net/jasperreports/print");
trace(xml.ns::property); //输出带名字空间的XML
由于 涉及到多个 命名空间,这种方式在该项目中不合适,且要修改后续的其他操作。
最简单的方式,就是 干掉命名空间,这样后续操作不变。
这个就涉及到XML的操作了。查XML api发现了removeNamespace(ns:Namespace):XML方法,以为轻松搞定,实验后 ,发现 不行。默认的命名空间(如 xmlns=”http://jasperreports.sourceforge.net/jasperreports/print”)无法删除。
用xml.children()方法取他孩子,发现,每个孩子也带上了命名空间。
最后用上了正则表达式。限定类型的命名表达式可以删除了。而且用了两次。汗。。
var str:String = oldxml.toString();
var str2:String = str.replace(/xmlns(.*?)="(.*?)"/gm, "").replace(/xsi(.*?)="(.*?)"/gm, "");
xml = new XML(str2);
默认情况下,Flash Builder 4.7安装了AIR SDK 3.4。如果你想使用别的SDK版本,你覆盖掉它就行了。下面就来介绍一下如何覆盖。 下载合适的AIR SDK文件:http://labs.adobe.com/downloads/asc2.html ,然后保存到AIR SDK的根目录(是SDK的根目录)。 注意了:这个AIR SDK包含了:Adobe AIR SDK、ActionScript编译器以及其它必需的组件和文件。 在进入以下步骤前,先退出Flash Builder: 在Flash Builder里更新AIR SDK的步骤: 1.(可选)备份旧的AIR SDK,把整个SDK目录都复制一份吧。AIR SDK的目录是在(因人而异,但大概一样): Windows 7: C:\Program Files (x86)\Adobe\Adobe Flash Builder 4.7\eclipse\plugins\com.adobe.flash.compiler_4.7.0.349722 Mac OS: /Applications/Adobe Flash Builder 4.7/eclipse/plugins/com.adobe.flash.compiler_4.7.0.349722
参考Adobe 原文:http://helpx.adobe.com/flash-builder/kb/overlay-air-sdk-flash-builder.html
用于实时检测FPS(实际上可以算是检测CPU)和内存占用情况。
使用方法,在application的Document Class(或者Application Class)上构建一个检测器实例(MonitorKit)并addChild即可,所含参数比较简单,不再一一赘述:
var monitor:MonitorKit = new MonitorKit(MonitorKit.MKMODE_T);
addChild(monitor);
package
{
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.Event;
import flash.system.System;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.utils.getTimer;
public class MonitorKit extends Sprite{
public static const MKMODE_T:String = "MKMODE_T";
public static const MKMODE_B:String = "MKMODE_B";
public static const MKMODE_L:String = "MKMODE_L";
public static const MKMODE_R:String = "MKMODE_R";
public static const MKMODE_TL:String = "MKMODE_TL";
public static const MKMODE_TR:String = "MKMODE_TR";
public static const MKMODE_BL:String = "MKMODE_BL";
public static const MKMODE_BR:String = "MKMODE_BR";
private static var stageInstance:Stage;
private var lastTime:uint = getTimer();
private var frames:Number = 0;
private var monitorKitTextField:TextField;
private var mode:String;
private var textColor:uint;
private var backgroundColor:uint;
private var transparent:Boolean;
public static var delay:Number = 0;
public function MonitorKit(_mode:String = MKMODE_T,
_transparent:Boolean = true,
_textColor:uint=0xffffff,
_backgroundColor:uint=0x000000) {
mode = _mode;
transparent = _transparent;
textColor = _textColor;
backgroundColor = _backgroundColor;
// Initialize it when rendered on the stage.
addEventListener(Event.ADDED_TO_STAGE, initMonitorHandler);
}
private function initMonitorHandler(event:Event):void {
// Unregister the event handler
removeEventListener(Event.ADDED_TO_STAGE, initMonitorHandler);
stageInstance = this.stage;
monitorKitTextField = new TextField();
monitorKitTextField.selectable = false;
monitorKitTextField.background = transparent;
monitorKitTextField.textColor = textColor;
monitorKitTextField.backgroundColor = backgroundColor;
monitorKitTextField.autoSize = TextFieldAutoSize.LEFT;
var format:TextFormat = new TextFormat();
format.font = "Courier New";
format.size = 15;
monitorKitTextField.setTextFormat(format);
monitorKitTextField.defaultTextFormat = format;
monitorKitTextField.text = "[ Loading... ]";
addChild(monitorKitTextField);
stageInstance.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
public function enterFrameHandler(evt:Event):void {
frames++;
var currentTime:uint = getTimer();
var deltaTime:uint = currentTime - lastTime;
var fps:Number = frames / deltaTime * 1000;
monitorKitTextField.text = "FPS: " + fps.toFixed(1);
monitorKitTextField.appendText("\nMem: " + Number(System.totalMemory/1024/1024).toFixed(3)+"(M)");
frames = 0;
lastTime = currentTime;
// Replace the monitor object
switch (mode) {
case MKMODE_T:
monitorKitTextField.x = stageInstance.stageWidth / 2 - monitorKitTextField.width / 2;
monitorKitTextField.y = 0;
break;
case MKMODE_B:
monitorKitTextField.x = stageInstance.stageWidth / 2 - monitorKitTextField.width / 2;
monitorKitTextField.y = stageInstance.stageHeight - monitorKitTextField.height;
break;
case MKMODE_L:
monitorKitTextField.x = 0;
monitorKitTextField.y = stageInstance.stageHeight / 2 - monitorKitTextField.height / 2;
break;
case MKMODE_R:
monitorKitTextField.x = stageInstance.stageWidth - monitorKitTextField.width;
monitorKitTextField.y = stageInstance.stageHeight / 2 - monitorKitTextField.height / 2;
break;
case MKMODE_TL:
monitorKitTextField.x = 0;
monitorKitTextField.y = 0;
break;
case MKMODE_TR:
monitorKitTextField.x = stageInstance.stageWidth - monitorKitTextField.width;
monitorKitTextField.y = 0;
break;
case MKMODE_BL:
monitorKitTextField.x = 0;
monitorKitTextField.y = stageInstance.stageHeight - monitorKitTextField.height;
break;
case MKMODE_BR:
monitorKitTextField.x = stageInstance.stageWidth - monitorKitTextField.width;
monitorKitTextField.y = stageInstance.stageHeight - monitorKitTextField.height;
break;
default:
break;
}
}
}
}
导入AS3项目时提示 “AIR SDK 0.0: AIR SDK location "D:\Program Files\Adobe Flash Builder 4.7\eclipse\plugins\com.adobe.flexbuilder.flex_4.7.0.349722\devsdks\AIRSDK\Win" does not exist.”
是AS3项目找不见AIR SDK. 打开项目配置 ActionScript Build Path
,路径出错。
他默认是去Flash Builder 4.7安装目录下的..\Adobe Flash Builder 4.7\eclipse\plugins\com.adobe.flexbuilder.flex_4.7.0.349722\devsdks\AIRSDK\Win
去找。
但是 我的Builder根本没有这个Win文件
##解决步骤:
###1. 先去官网下载下载和更新SDK
可参考此文http://www.waylau.com/update-air-sdk-flash-builder
###2. 如果上述方法无效
在..\Adobe Flash Builder 4.7\eclipse\plugins\com.adobe.flexbuilder.flex_4.7.0.349722\
目录下创建 devsdks文件夹,再在devsdks创建AIRSDK,再在AIRSDK下创建Win 即创建它搜索的那个路径
###3.将下载的AIRSDK中的文件复制进新建的Win文件夹下。
###4.回到配置界面ActionScript Build Path移除之前的AIRSDK,再点击“ADD AIR SDK”
一、ireport下载最新版
本例为5.1.0 http://sourceforge.net/projects/ireport/files/?source=navbar
二、安装,直接下一步
三、ireport连接数据库,创建数据源
默认数据源是空的 ,需要自己创建数据源,当然也可以选择他的测试数据库
1.点击图中按钮,弹出窗,点击 new
2.这里选择的是 Database JDBC Connection
3.iReport默认的数据库驱动为黑色字体部分,红色字体需另外导入包
4.工具à选项
5.在Classpath添加数据库驱动包
这里我们连接的是sql2000数据库,填加一个jtds-1.2.2.jar
6.再回到之前的那个数据源设置界面
net.sourceforge.jtds.jdbc.Driver 变成了黑色。选中它
7.JDBC URL中填入数据库的地址和库名,并填入正确的用户名和密码。
本例选用了一个已经存在的数据库。
点击Test,提示test succesful则说明连接成功。
输入Name, 本例为”EEMS”。
点击Save保存设置。
四、新增报表模版
1.文件 –>new file,选择blank A4 ,点击 launch report wizard
2.填入报表名称,选择输出的目录
3.直接填入查询sql语句,或者选择load query导入已有的sql文件
本例选用design query 采用可视化界面来设计sql语句
双击选中的数据库表,选择要查询的字段
点击OK,自动生成了sql语句
4.选择要参与的字段
这里向右移入所有字段
5.选择要分组的字段
这里选择loginName字段
6.出现下面提示,说明模版创建成功!
五、设计报表
报表的结构包括如下部分:Title、Page Header、Column Header、Detail、Column Footer、Page Footer、Summary.下面一一的介绍各个部分。
Title:为报表的标题部分,如果报表有多页,则只显示在第一页。
Page Header :为报表每页的一个头部名称,如果报表有多页,则每页都会显示。
Column Header:可以理解成表头,如果报表有多页,则每页都会显示。
Detail:详细记录,迭代列出所有的查询结果,有多少数据都会显示出来(分页)。
Column Footer:相当于表尾,如果报表有多页,则每页都会显示。
Page Footer:与Page Header对应,每页都会显示。
Summary:报表的一些统计信息。比如共有多少页,当前是第几页等信息。
设计报表的要求是:列出所有用户的信息,(查询语句决定。)
1.从组件面板中,拖出一个 Static Text 组件来,放置在报表的Title部分,输入”用户列表”。
2.在Page Header 也同样拖入一个 Static Text 组件,输入”管理员”
3.展开左侧的 Report Inspector,展开Fields子项,
将图所示的字段,拖入Detail项中,此时会发现,Column Header项中自动填充了Static Text的表头,如图所示:
在右侧”属性”,也可以对表头进行编辑,重命名等操作。可以调整各组件的位置、大小等信息。
4.选择 预览方式,这里选HLML
5.点击预览,选择Preview
6.显示数据库数据啦,成功啦。~
一、下载和安装
activiti下载:
本例子版本:activiti-5.12.1.zip
http://www.activiti.org/download.html
JDK 下载 JDK 6+
本例子版本:jdk7
http://www.oracle.com/technetwork/java/javase/downloads/index.html
eclipse下载 Eclipse Indigo and Juno:
本例子版本:Eclipse Juno (4.2)
解压activiti-5.12.1.zip获取activiti-explorer.war
activiti-explorer.war 拷贝至Tomcat.(或其他java web服务器,本例为Tomcat 6.0)的webapps目录下
二、运行
启动tomcat,在浏览器打开项目(本例子tomcat端口为8089)
http://localhost:8089/activiti-explorer/
见到这个界面说明项目运行成功了!
默认使用的是内存数据库 H2,下面为数据库表
Table 用户和分组
UserId |
Password |
Security roles |
kermit |
kermit |
admin |
gonzo |
gonzo |
manager |
fozzie |
fozzie |
user |
可以使用上面的账号登入系统(本例为kermit)
###flex4.6 textArea 文字换行 有 几种实现形式,
####法1:在text文字里面直接加 “ ”
<s:TextArea text="这是个 TextArea 分行的例子&#13; http://www.waylau.com "/>
####法2:采用了 TLF 标记 形式
<s:TextArea width="100%" height="340" >
<s:content >
flex 4.6 <s:span color="#FF0000" fontWeight="bold">这是个 TextArea 分行的例子 </s:span><s:br/>
<s:span color="#008800"> 采用了 TLF 标记 形式 </s:span> <s:br/>
<s:a href="http://www.waylau.com" target="_blank">技术支持:www.waylau.com </s:a>.</s:content>
</s:TextArea>
###问题: 如题 遇到 一个 奇怪的 问题, 项目右键运行 图片显示正常。 但 部署到 web服务器 就 显示不正常了。
PS:图片命名用了中文。 用了英文的貌似显示 都正常。
###解决 初步 认定 可能是 web 服务器 编码所致使
在tomcat/conf/server.xml中找到 Connector 在后面加上 URIEncoding=”UTF-8” 即可
<Connector port="8089" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8"/>
1.惠城区出发时,先骑(新S254)惠南大道 2.到了永湖镇后,左转进入(旧S254)惠澳大道,直走 3.到大亚湾的疏港大道, 4.1 快到石化大道前的一个十字路口(有指往霞冲镇的路标),转左直走就能到达霞冲镇,这是一条新路,左边有一条绿道直达霞冲镇 4.2 或到澳霞立交 左转,进入石化大道,直达霞冲镇 5.过了霞冲镇直走约3公里就是金海岸海滨浴场
简单对象访问协议(Simple Object Access Protocol,SOAP)是一种基于 XML 的协议,可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议(HTTP),简单邮件传输协议(SMTP),多用途网际邮件扩充协议(MIME),基于“通用”传输协议是 SOAP的一个优点。它还支持从消息系统到远程过程调用(Remote Procedure Call,RPC)等大量的应用程序。SOAP提供了一系列的标准,如WSRM(WS-Reliable Messaging)形式化契约确保可靠性与安全性,确保异步处理与调用;WS-Security、WS-Transactions和WS-Coordination等标准提供了上下文信息与对话状态管理。
</wbr>
相对而言,SOAP协议属于复杂的、重量级的协议,当前随着Web2.0的兴起,表述性状态转移(Representational State Transfer,REST)逐步成为一个流行的架构风格。REST是一种轻量级的Web Service架构风格,其实现和操作比SOAP和XML-RPC更为简洁,可以完全通过HTTP协议实现,还可以利用缓存Cache来提高响应速度,性能、效率和易用性上都优于SOAP协议。REST架构对资源的操作包括获取、创建、修改和删除资源的操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法,这种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。REST架构尤其适用于完全无状态的CRUD(Create、Read、Update、Delete,创建、读取、更新、删除)操作。
基于REST的软件体系结构风格(Software Architecture Style)称之为面向资源体系架构(Resource-oriented Architecture,ROA)。按照REST原则设计的软件、体系结构,通常被称为“REST式的”(RESTful),在本文中以下称之为RESTful Web服务,以便于和基于SOAP的Web服务区别。
服务器端采用J2EE,客户端采用JSP、Flex、JavaFX、AIR等可以直接调用Servlet,其他的实现技术基本上不能直接调用,但是无论是那种客户端,对于基于SOAP的Web服务或者基于RESTful Web服务务都是支持的,如AJAX的 XMLHttpRequest、Flex的HTTPService等。如下图所示:
客户端和服务器端的通讯方式
一、骑行人员装备 从上至下,依次为: 1、骑行头盔:为轻质头盔,以高强度泡沫压制而成,用于头部防护; 2、骑行头巾:多种用途,主要用于排汗遮阳阻隔灰尘; 3、骑行眼镜:按照佩带时间段,镜片可分为多种颜色,一般为深灰色、黄色、白色。深灰色-适合于中午阳光照射充足的时间佩带,以阻隔刺眼的眼光;黄色-适合清晨、黄昏阳光照射相对较暗的时候佩带;白色,适合天气阴暗或晚上佩带。其主要功能在于,阻隔阳光、阻隔风尘; 4、骑行服:骑行人员专用衣服,由多种面料制作而成,可按需选用。其功能主要功能为保暖、速干、透气; 5、骑行袖套:又称为臂套,主要和短袖骑行服搭配穿着,方便拆解,其主要功能为保暖、防晒; 6、骑行手套:为骑行人员专用手套,有半指与全指之分,手掌部位做加厚处理,高档骑行手套均垫有硅胶层,主要用于摔车时,减少伤害,防止擦破手; 7、骑行背包或腰包:骑行背包并没有做特殊规定,主要用于盛装骑行过程所需之物,满足需求即可,并不做特殊要求; 8、骑行裤:为骑行者专用裤子,有长短之分并在臀部配有坐垫,其功能主要为高弹减少腿部于自行车之间的摩擦,同时配备的坐垫减少长时间骑行屁股会疼的状况,提高骑行的舒适性; 9、骑行腿套:如直筒一般,与骑行短裤搭配使用,方便拆解,主要功能为保暖、防晒; 10、骑行袜:为骑行者专用袜子,按照COOLMAX含量可分为多种,骑行者可按照骑行时间的长短和骑行活动的强度来选用适合穿着的骑行袜; 11、绑腿:又名束带主要用于扎结裤腿角,防止裤腿绞进链条,以保障骑行的安全; 12、骑行鞋:为骑行者专用鞋子,同样可分为多种,有山地骑行鞋与公路骑行鞋之分,可按照所骑自行车款式进行选择,如自行车配备专用脚蹬,则骑行鞋必须选用锁鞋; 13、骑行鞋套:骑行鞋套用于骑行锁鞋的搭配,有减少风阻,防污保暖等用途。
二、车载装备 从自行车前头往后依次有: 1、打气桶:一般为便携装,安置于前叉部位; 2、车首包:又名车把包、车前包常见于山地车装备中。适合长途骑行装载物品之用; 3、车灯\尾灯:常见于夜间骑行的自行车中,照明警示用; 4、喇叭:有气喇叭与电喇叭之分,可按需取用,功能并无太大差别,只是发声装置不同; 5、三角包:隶属于包裹类,作用同于车首包,只是安装部位不同,另还有尾包-安装于自行车座立管部位,驮包安装于自行车后坐部位;车架包,位于车头与车管部位 6、水壶:有多种可选,无需专门配备,主要用于盛装在骑行过程中所需要饮用的水。