当前位置: 编程技术>综合
本页文章导读:
▪http代理工作原理(3) 在上一篇文章里面我们的工作人员已经具有了识别信件的功能了,但是我们发现这个工作模式还有一些问题,
他很容易出错,经常抛异常,而且每次投完信还不走,一个劲的傻等,直到用户.........
▪关注细节-TWaver Android 一款优秀的产品体现在细节,UI产品更是如此,精确到每个像素,平衡性能与效果的最佳点,是我们追求的目标,细节的实现过程会有困难,结果却让人兴奋,TWaver Android的开发正是如此,所.........
▪Spring怎样把Bean实例暴露出来? 首先书写你想要暴露的类
public class UtilBean {
private static UtilBean utilBean;
public void init() {
UtilBean .utilBean= this;
}
public static UtilBean getUtilBean() {
return utilBean;
}
//下面写其它需要的方法和属.........
[1]http代理工作原理(3)
来源: 互联网 发布时间: 2014-02-18
在上一篇文章里面我们的工作人员已经具有了识别信件的功能了,但是我们发现这个工作模式还有一些问题,
他很容易出错,经常抛异常,而且每次投完信还不走,一个劲的傻等,直到用户把它轰出来为止。对于某些信件, 他也无法正常投递。
现在我们把它进一步完善一下,主要是让他可以识别更多信封上的内容,并减少他出错的可能性。
代码如下:
他很容易出错,经常抛异常,而且每次投完信还不走,一个劲的傻等,直到用户把它轰出来为止。对于某些信件, 他也无法正常投递。
现在我们把它进一步完善一下,主要是让他可以识别更多信封上的内容,并减少他出错的可能性。
代码如下:
/**
* 某些服务器对协议头必须一次性读完, 例如QQ空间
* 因此此处先读出协议头, 并且一次写入, 写入之后必须flush
* 否则就跳转到QQ首页了
*/
long contentLength = -1L;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write(buffer, 0, buffer.length);
/**
* 读取协议头
* 也可以不读取协议头, 而是直接把inputStream写入到remoteOutputStream
* 为了兼容某些服务器, 此处简单的读取一下协议头
*/
while((buffer = readLine(inputStream)).length > 0)
{
header = new String(buffer, "UTF-8").trim();
if(header.length() < 1)
{
break;
}
if(header.startsWith("Content-Length:"))
{
try
{
contentLength = Long.parseLong(header.substring(15).trim());
}
catch(NumberFormatException e){}
}
bos.write(buffer, 0, buffer.length);
}
/** 协议头和主体之间的空行 */
bos.write(CRLF);
remoteOutputStream.write(bos.toByteArray());
remoteOutputStream.flush();
/** 如果存在contentLength */
if(contentLength > 0)
{
copy(inputStream, remoteOutputStream, 4096, contentLength);
}其他的代码就跟之前的一样了, 完整的代码如下:/*
* $RCSfile: SimpleHttpProxy.java,v $$
* $Revision: 1.1 $
* $Date: 2013-1-9 $
*
* Copyright (C) 2008 Skin, Inc. All rights reserved.
*
* This software is the proprietary information of Skin, Inc.
* Use is subject to license terms.
*/
package test.com.skin.http.proxy;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* <p>Title: SimpleHttpProxy</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2006</p>
* @author xuesong.net
* @version 1.0
*/
public class SimpleHttpProxy
{
public static final int PORT = 6666;
public static final byte[] CRLF = new byte[]{0x0D, 0x0A};
/**
* @param args
*/
public static void main(String[] args)
{
ServerSocket socketServer = null;
BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable>(1024);
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(512, 1024, 30000, TimeUnit.SECONDS, blockingQueue);
try
{
socketServer = new ServerSocket(PORT);
while(true)
{
try
{
final Socket socket = socketServer.accept();
Runnable job = new Runnable(){
public void run(){
SimpleHttpProxy.service(socket);
}
};
threadPoolExecutor.execute(job);
}
catch(SocketTimeoutException e)
{
e.printStackTrace();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
if(socketServer != null)
{
try
{
socketServer.close();
}
catch(IOException e)
{
}
}
}
}
private static void service(Socket socket)
{
Socket remote = null;
try
{
socket.setSoTimeout(2000);
socket.setKeepAlive(false);
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
/**
* 读取协议头的第一行
* 格式: GET http://www.mytest.com HTTP/1.1
*/
byte[] buffer = readLine(inputStream);
if(buffer.length < 1)
{
return;
}
String header = new String(buffer, "UTF-8");
String[] action = header.split(" ");
if(action.length < 3)
{
return;
}
String address = action[1];
/**
* 目标地址是从http协议的第一行取
* 目标主机应该从协议的Host头里面取,如果Host取不到, 从地址里面取
* 此处为了简化逻辑只从地址里面取host, 因此如果路径不是绝对路径就忽略
*/
if(address.startsWith("http://") == false)
{
return;
}
System.out.print(header);
URL url = new URL(/blog_article/address/index.html);
String host = url.getHost();
int port = (url.getPort() > -1 ? url.getPort() : 80);
remote = new Socket(host, port);
InputStream remoteInputStream = remote.getInputStream();
OutputStream remoteOutputStream = remote.getOutputStream();
/**
* 某些服务器对协议头必须一次性读完, 例如QQ空间
* 因此此处先读出协议头, 并且一次写入, 写入之后必须flush
* 否则就跳转到QQ首页了
*/
long contentLength = -1L;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write(buffer, 0, buffer.length);
/**
* 读取协议头
* 也可以不读取协议头, 而是直接把inputStream写入到remoteOutputStream
* 为了兼容某些服务器, 此处简单的读取一下协议头
*/
while((buffer = readLine(inputStream)).length > 0)
{
header = new String(buffer, "UTF-8").trim();
if(header.length() < 1)
{
break;
}
if(header.startsWith("Content-Length:"))
{
try
{
contentLength = Long.parseLong(header.substring(15).trim());
}
catch(NumberFormatException e){}
}
bos.write(buffer, 0, buffer.length);
}
/** 协议头和主体之间的空行 */
bos.write(CRLF);
remoteOutputStream.write(bos.toByteArray());
remoteOutputStream.flush();
/** 如果存在contentLength */
if(contentLength > 0)
{
copy(inputStream, remoteOutputStream, 4096, contentLength);
}
try
{
/**
* 将目标主机返回的数据写入到客户端
* 此处应该检查一下Content-Length, 并且根据Content-Length来决定要写入多少数据
* 不过很多服务器经常会不返回Content-Length,
* 没有Content-Length, read函数会一直读取
* 因此使用timeout来解决阻塞的问题
* 超时的时候自动退出线程, 否则该线程就无法释放了
*/
remote.setSoTimeout(10000);
copy(remoteInputStream, outputStream, 4096);
}
catch(SocketTimeoutException e)
{
}
catch(Exception e)
{
e.printStackTrace();
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
try
{
if(socket != null)
{
socket.close();
}
}
catch(IOException e)
{
}
try
{
if(remote != null)
{
remote.close();
}
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
public static byte[] readLine(InputStream stream) throws IOException
{
int b = -1;
ByteArrayOutputStream bos = new ByteArrayOutputStream(2048);
while((b = stream.read()) != -1)
{
if(b == '\n')
{
bos.write(b);
break;
}
bos.write(b);
}
return bos.toByteArray();
}
public static void copy(InputStream inputStream, OutputStream outputStream, int bufferSize) throws IOException
{
int length = 0;
byte[] buffer = new byte[bufferSize];
while((length = inputStream.read(buffer, 0, bufferSize)) > -1)
{
outputStream.write(buffer, 0, length);
}
outputStream.flush();
}
public static void copy(InputStream inputStream, OutputStream outputStream, int bufferSize, long size) throws IOException
{
if(size > 0)
{
int readBytes = 0;
[2]关注细节-TWaver Android
来源: 互联网 发布时间: 2014-02-18
一款优秀的产品体现在细节,UI产品更是如此,精确到每个像素,平衡性能与效果的最佳点,是我们追求的目标,细节的实现过程会有困难,结果却让人兴奋,TWaver Android的开发正是如此,所以我忍不住想分享一些细节点。
位置的细节
位置与坐标是图形界面的基础,TWaver Android中使用了绝对与相对坐标结合的思路,采用漫游模式交互,代码上与以往twaver产品会有所不同,这里列举部分特点。
绝对位置的两个要素
(location, anchor position)
位置是图形元素最基本的信息,自然想到的是点(Point)作为位置(location),比如说你的位置在(250, 360),但人不是大头针,物体总是有尺寸,一个点代表不了位置的全部信息,比如人的位置是算脚尖还是脚跟呢?于是我们引入挂载点位置(anchorPosition)参数,可以是左上角,中心或者其他位置,于是在TWaver Android中,你会看到位置的两个要素:位置(location)和挂载点(anchor position)
下面示意图中,两个网元相同的位置(100, 100),但挂载点不同,一个在中心,另一个在左上角。
(position, offset, anchor position)
对于相对位置,TWaver Android引入了第三个要素(position),twaver中网元可以组合,每个节点由一个主体(body)和一堆附件(attachments)组成,其中附件的位置就是相对与主体,称为相对位置,以文本标签为例,可以放置在主体的底部,中间或者其他
下面的代码设置文本相对位置为节点的左上角,挂载点位置为右下角
冒泡样式
圆角,阴影
下面的代码的作用是,设置网元位置(100, 100),挂载点位置为左上角(left top,初始为居中)
node.setLocation(100, 100); node.setAnchorPosition(Position.LEFT_TOP);
相对位置的三个要素
(position, offset, anchor position)
对于相对位置,TWaver Android引入了第三个要素(position),twaver中网元可以组合,每个节点由一个主体(body)和一堆附件(attachments)组成,其中附件的位置就是相对与主体,称为相对位置,以文本标签为例,可以放置在主体的底部,中间或者其他
下面的代码设置文本相对位置为节点的左上角,挂载点位置为右下角
node.setStyle(Styles.LABEL_POSITION, Position.LEFT_TOP); node.setStyle(Styles.LABEL_ANCHOR_POSITION, Position.RIGHT_BOTTOM);
再加上前面提到的挂载点位置,两者组合可以实现81种位置,详见LabelPositionDemo
推而广之,对于线形元素,81种位置同样适用,且支持沿线旋转等等
外观的细节
前面位置和组合是否让你兴奋,又或者是头晕,好吧,我可以说些更直观的东西——外观
渐变 - 彩虹
渐变旋转,偏移,再加上一尾彩虹色,是否让可爱的Demo顿时文艺
定义彩虹渐变
int[] rainbowColors = new int[]{0x00000000, 0xFFFF0000, 0xFFFFFF00, 0xFF00FF00, 0xFF00EAFF, 0xFF000390, 0xFFFF00C6, 0x00000000};
float[] rainbowPositions = new float[]{0f, 0.12f, 0.28f, 0.45f, 0.6f, 0.75f, 0.8f, 1f};
Gradient linearGradient = new Gradient(Gradient.LINEAR, rainbowColors, rainbowPositions);
Gradient radialGradient = new Gradient(Gradient.RADIAL, rainbowColors, rainbowPositions);
Gradient sweepGradient = new Gradient(Gradient.SWEEP, rainbowColors, rainbowPositions);
冒泡样式
twaver的告警冒泡样式颇受好评,如果将这种冒泡推而广之,作用于所有附件,你是否感到兴奋呢,看看TWaver Android中的冒泡效果
设置lable的冒泡效果
Gradient linearGradient = Gradient.LINEAR_GRADIENT_VERTICAL; int backgroundColor = Defaults.GROUP_BACKGROUND_COLOR; node1.setStyle(Styles.LABEL_OUTLINE, 1); node1.setStyle(Styles.LABEL_PADDING, new Insets(5)); node1.setStyle(Styles.LABEL_BACKGROUND_COLOR, backgroundColor); node1.setStyle(Styles.LABEL_CORNER_RADIUS, 10); node1.setStyle(Styles.LABEL_OFFSET, new Point(0, 10)); node1.setStyle(Styles.LABEL_BACKGROUND_SHADER, linearGradient); ...
圆角,阴影
圆角,阴影本是平常的东西,虽然申请不了圆角矩阵的专利,但我们可以稍微做好些,TWaver Android中圆角普遍被应用,而阴影效果也不错
更多
细节很多,这只是冰山一角,从模型,外观到交互设计,方方面面等待你去体验,最后静待TWaver Android的正式发布……
作者:twaver 发表于2013-1-14 12:08:33 原文链接
阅读:38 评论:0 查看评论
[3]Spring怎样把Bean实例暴露出来?
来源: 互联网 发布时间: 2014-02-18
首先书写你想要暴露的类
public class UtilBean {
private static UtilBean utilBean;
public void init() {
UtilBean .utilBean= this;
}
public static UtilBean getUtilBean() {
return utilBean;
}
//下面写其它需要的方法和属性
...
}然后再Spring的配置文件里初始化实例
<bean id="utilBean" class="com.model.UtilBean" init-method="init" lazy-init="false"> </bean>
这里配置的“init-method”就是告诉Spring在生成utilBean实例之后要调用的方法,如上我们在init方法内把刚刚生成的实例赋值给了一个静态变量,
这样在你调用时就可以直接使用而不需要做注入的配置
例:UtilBean util=UtilBean.getUtilBean();
作者:wangqianjiao 发表于2013-1-14 12:05:30 原文链接
阅读:48 评论:0 查看评论
最新技术文章: