2012年5月23日
#
在SoapUI的Request URL中,每次输入的URL中含有的大写字母会自动转换为小写字母,导致请求不了,
这个问题在SoapUI 5.1.2和5.2.1版本中都存在,具体的解决办法是在HTTP TestRequest Properties的属性中,在Endpoint中输入对应的含有大写字母的URL即可。
Java使用网易邮箱服务器发送邮件实例
1 下载发送mail需要的jar包
activation.jar 与 mail.jar
2 创建 SendMail 类
3 代码如下
import java.util.Date;
import java.util.Properties;
import javax.mail.Address;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import cn.founder.common.globals.Constants;
public class SendMail {
public int send(String tfrom, String tto, String ttitle, String tcontent) {
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.263.net");//自己到网上查找网易发邮件的smtp服务地址 你的发件邮箱如果是163 你就查找163的发件服务器
props.put("mail.smtp.auth", "true");
Session s = Session.getInstance(props, null);
s.setDebug(true);
Message message = new MimeMessage(s);
try {
Address from = new InternetAddress(tfrom);
message.setFrom(from);
Address to = new InternetAddress(tto);
message.setRecipient(Message.RecipientType.TO, to);
sun.misc.BASE64Encoder enc = new sun.misc.BASE64Encoder();
message.setSubject("=?utf-8?B?"+enc.encode(ttitle.getBytes("utf-8"))+"?=");
message.setContent(tcontent, "text/html;charset=utf-8");
message.setSentDate(new Date());
message.saveChanges();
Transport transport = s.getTransport("smtp");
//第一个参数是发件服务器 第二个是你发件的邮箱名 第三个是你发件邮箱的密码
transport.connect("smtp.263.net",”发件邮箱”,”发件邮箱密码”);
transport.sendMessage(message, message.getAllRecipients());
transport.close();
return 0;
} catch (Exception e) {
e.printStackTrace();
return 1;
}
}
/**
* getEmailServiceIp
* @return EmailServiceIp
*/
public static void main(String[] args) {
//第一个参数 发件邮箱 第二个收件邮箱 第三个 邮件内容
new SendMail().send("yunlong090614@163.com", "1063342004@qq.com", "更改密码校验", "尊敬的用户你好,您的校验码为:65432</br>xxxx");
}
<%@ taglib prefix="fmt" uri="
http://java.sun.com/jsp/jstl/fmt"%>
<jsp:useBean id="now" class="java.util.Date" />
<c:set var="currentday">
<fmt:formatDate value="${now}" type="both" dateStyle="long" pattern="yyyy-MM-dd" var="nowdate"/>
</c:set>
${nowdate} > ${result.openEndTimeOpen }=${nowdate > result.openEndTimeOpen}
安装32位的Oracle客户端( instantclient-basic-win32-11.2.0.1.0)。Win7 64位系统暂无PLSQLDeveloper,所以下一个32位的。
下载instantclient-basic-win32-11.2.0.1.0.zip (一定得是32位的,不要下错了版本,Oracle官网有下载),将其解压至Oracle安装目录的Product下(本机命名为:instantclient_11_2):D:\Oracle\app\Dell\product\instantclient_11_2
拷贝数据库安装根目录下的一个文件夹:D:\Oracle\app\Dell\product\11.2.0\dbhome_1
\NETWORK到Oracle客户端目录下D:\Oracle\app\Dell\product\instantclient_11_2(其实只需要 NETWORK\ADMIN\tnsnames.ora)
修改oracle客户端tnsnames.ora文件(目录在D:\Oracle\app\Dell\product\instantclient_11_2\NETWORK\ADMIN\tnsnames.ora)
MYACCP= (DESCRIPTION=
(ADDRESS_LIST=
(ADDRESS= (PROTOCOL=tcp)(HOST=superich-accp )(PORT=1521)) )
(CONNECT_DATA=(SERVICE_NAME = ACCP)
) )
SELECT createDate,shortName,collNum,fullName FROM college
ORDER BY CONVERT( shortName USING gbk)
近几日打印东西都是不成功,显示不能发现打印机,处理方法如下:
启动 print spooler服务 但是报1068错误,
在运行中输入“sc config spooler depend= rpcss”,确定后,我再去启用Print Spooler服务,居然成功了。我也不知道这是个什么命令,但是问题解决了,就要谢谢网络上的高手们!
Java中的三元运算符为:条件?条件为true值:条件为false的值
EL也有一样的运算符,用EL的三元运算符有时可以代替c:choose标签,为我们的工作省下很大力气。
比如gender为0显示男,其余显示女,我们可以这么写:
<c:choose>
<c:when test="${gender eq 0}">男</c:when>
<c:otherwise>女</c:otherwise>
</c:choose>
但是不是显得太麻烦了?其实我们这里就可以使用EL表达式中的三元运算符了,上面可以简化为:
${gender eq 0?"男":"女"}
这样是不是简练了很多?在JSTL和EL处理非A即B的时候,三元运算符简单了许多。
转载请注明:观测者 » JSP中EL表达式三元运算符的使用
jar -cvf safety.war *
打 war包命令
摘要: 引用地址http://www.cnblogs.com/xdp-gacl/p/3467245.html
用Jquery控制文本框只能输入数字和字母
在公司开发WinForm项目时,发现公司自主研发的textbox控件非常强大,可以实现"只能输入数字"、"只能输入字母"和"只能输入数字和字母"的三种输入限制,这样就可以精确控制用户输入的内容范围,让"用户永远没有办法输入...
阅读全文
SVN更新失败,提示locked
- 浏览:3571
- |
- 更新:
打开eclipse弹出Error:could not open D:\java\lib\i386\jvm.cfg'
运行中 输入regedit
没有修改注册表,解决办法是:
重新安装JDK时注册表中\HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environemt\1.6 项目下的JavaHome和RuntimeLib设置没有更新,将这两个项目更正即可.
分类: Java2012-07-23 09:46 1431人阅读 收藏 举报
最近在eclipse中开发android项目,用到了jquery mobile框架,则会涉及到新建html文件,发现eclipse不自带新建html文件的插件,必须得新建一个其他形式的文件,譬如xml格式的文件,然后重命名,后缀名改成html,觉得这样老麻烦的,所以在网上发现了Eclipse HTML Editor,不过此插件似乎只支持新建html文件,不支持其格式化。网上看了其他一个html格式化的插件Eclipse Tidy,不过用了后,发现格式化后的html一点都不符合代码审读标准。也不知道是不是自己哪边没设置好,还是本来就是那样。
现在就暂先不管Eclipse Tidy了,看看如何安装Eclipse HTML Editor。
1.下载GEF(依赖包):
http://www.eclipse.org/downloads/download.php?file=/tools/gef/downloads/drops/3.7.2/R201201171043/GEF-ALL-3.7.2.zip
然后解压,把解压得到的features和plugins两文件夹放到eclipse安装目录下plugins文件夹中
2.下载HTMLEditor
http://amateras.sourceforge.jp/cgi-bin/fswiki_en/wiki.cgi?page=EclipseHTMLEditor
只有一个tk.eclipse.plugin.htmleditor_2.1.0.jar文件
直接复制到eclipse\plugins里面
摘要: 基本资料:mysql> select version();+-----------+| version() |+-----------+| 5.0.16 |+-----------+ mysql> select * from t1;+----+------+| id | name |+----+------+| 1 | aa || 2 | bb || 3 | cc |+---...
阅读全文
前言:之前做的ListView实现RadioButton的功能有bug,当ListView控件的内容超出屏幕可见区域时,滑动ListView控件会报错,下面有为什么出错和解决方法进行的注解,不多说了,看源码,有更好的解决办法请指教
1,MainActivity.java
package com.excetop.listradio;
import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.CompoundButton; import android.widget.ListView; import android.widget.RadioButton; import android.widget.CompoundButton.OnCheckedChangeListener;
public class MainActivity extends Activity { private static final String TAG = "MainActivity"; private ListView listView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); listView = (ListView) this.findViewById(R.id.list); MyAdapter adapter = new MyAdapter(); listView.setAdapter(adapter); } private class MyAdapter extends BaseAdapter{ private String[] s = new String[]{"a","b","c","d","e","a","b","c","d","e","a","b","c","d","e","a","b","c","d","e"}; private int temp = -1;
@Override public int getCount() { // TODO Auto-generated method stub return s.length; }
@Override public Object getItem(int position) { // TODO Auto-generated method stub return null; }
@Override public long getItemId(int position) { // TODO Auto-generated method stub return 0; }
@Override public View getView(int position, View convertView, ViewGroup parent) { convertView = MainActivity.this.getLayoutInflater().inflate(R.layout.item, null); //解决办法: 每次都重新获取View Button button = (Button) convertView.findViewById(R.id.button); button.setText(s[position]); RadioButton radioButton = (RadioButton) convertView.findViewById(R.id.radioButton); radioButton.setId(position); //把position设为radioButton的id radioButton.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if(isChecked){ //这段代码来实现单选功能 if(temp != -1){ RadioButton tempButton = (RadioButton) MainActivity.this.findViewById(temp); if(tempButton != null){ tempButton.setChecked(false); } } temp = buttonView.getId(); Log.i(TAG,"you are women- - " + isChecked + " " + temp); } } }); //这里实现单选框选的回显,解决了单选框移出屏幕范围未选中状态 if(temp == position){ radioButton.setChecked(true); } return convertView; } // Holder holder; // if(convertView == null){ //1,当第一次加载ListView控件时 convertView为空 // convertView = MainActivity.this.getLayoutInflater().inflate(R.layout.item, null); //所以当ListView控件没有滑动时都会执行这条语句 // holder = new Holder(); // convertView.setTag(holder); // }else{ // holder = (Holder) convertView.getTag(); // } // // holder.button = (Button) convertView.findViewById(R.id.button); // holder.button.setText(s[position]); // // holder.radioButton = (RadioButton) convertView.findViewById(R.id.radioButton); // // holder.radioButton.setId(position); //2,因为这里对radioButton的id进行重新设置,滑动ListView时convertView不为空,上面的语句就没法得到radioButton对象,这条语句就会报空指针异常 // holder.radioButton.setOnCheckedChangeListener(new OnCheckedChangeListener() { // // @Override // public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { // // if(isChecked){ // if(temp != -1){ // RadioButton tempButton = (RadioButton) MainActivity.this.findViewById(temp); // tempButton.setChecked(false); // // } // // temp = buttonView.getId(); // Log.i(TAG,"you are women- - " + isChecked + " " + temp); // // } // } // }); // return convertView; // } // private class Holder{ // private Button button; // private RadioButton radioButton; // } } }
2,item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content"> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="测试"> </Button> <RadioButton android:id="@+id/radioButton" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> 3, main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <ListView android:id="@+id/list" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>
|
一,Layout
1,main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <ListView android:id="@+id/list" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>
2,item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content"> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="测试"> </Button> <CheckBox android:id="@+id/checkBox" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
二,Activity
1,MainActivity
package com.excetop.listradio;
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map;
import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.ListView; import android.widget.Toast; import android.widget.CompoundButton.OnCheckedChangeListener;
public class MainActivity extends Activity { private static final String TAG = "MainActivity"; private ListView listView; private Map checkMap; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); listView = (ListView) this.findViewById(R.id.list); checkMap = new HashMap<String, Object>(); MyAdapter adapter = new MyAdapter(); listView.setAdapter(adapter); } private class MyAdapter extends BaseAdapter{ private String[] s = new String[]{"a","b","c","d","e","a","b","c","d","e","a","b","c","d","e","a","b","c","d","e"};
@Override public int getCount() { // TODO Auto-generated method stub return s.length; }
@Override public Object getItem(int position) { // TODO Auto-generated method stub return null; }
@Override public long getItemId(int position) { // TODO Auto-generated method stub return 0; }
@Override public View getView(int position, View convertView, ViewGroup parent) { convertView = MainActivity.this.getLayoutInflater().inflate(R.layout.item, null); //解决办法: 每次都重新获取View Button button = (Button) convertView.findViewById(R.id.button); button.setText(s[position]); final CheckBox checkBox = (CheckBox) convertView.findViewById(R.id.checkBox); checkBox.setId(position); //把position设为radioButton的id checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if(isChecked){ checkMap.put(String.valueOf(checkBox.getId()), checkBox.getId()); // Toast.makeText(MainActivity.this, String.valueOf( checkBox.getId()), 0).show(); }else{ checkMap.remove(String.valueOf(checkBox.getId())); // Toast.makeText(MainActivity.this, String.valueOf( checkBox.getId()), 0).show(); } } }); if(checkMap.get(String.valueOf(position)) != null){ checkBox.setChecked(true); // Toast.makeText(MainActivity.this, String.valueOf(String.valueOf(position)), 0).show(); } //这里实现单选框选的回显,解决了单选框移出屏幕范围未选中状态 return convertView; } } } |
处理多个fragment之间replace刷新问题[转]
每次创建fragment对象都会重新走onCreateView方法,所以多个fragment互相替换会重新刷新界面, 在application中创建一个View,保持onCreateVIew中创建的View 每次走onCreateView的时候判断application中是否保持了View,如果为null,重新inflater走initView和initData方法,不为nul得到父类,移除子View,不然有父id无法再加入布局中, 以下是代码: @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { GalaxyApplication galaxyApplication = (GalaxyApplication) getActivity().getApplication(); View recommendView = galaxyApplication.getRecommendView(); if(recommendView != null){ ViewGroup group = (ViewGroup) recommendView.getParent(); group.removeAllViews(); return recommendView; } View fmRootView = inflater.inflate(R.layout.fragment_recommend, container,false); initView(fmRootView); initData(); galaxyApplication.setRecommendView(fmRootView); Logger.d("fragment: ", "onCreateView"); return fmRootView; }
如有好的方法,处理onCreateView刷新问题 欢迎留言。 |
创建重复的背景图片
在drawable目录下创建一个repeat_bg.xml: src是引用图片的名称
1
2
3
4
5
6
7
8 |
1
<?xml version= "1.0" encoding= "utf-8" ?>
2
3
android:src= "@drawable/bg"
4
android:tileMode= "repeat" />
|
然后在布局的xml文件中可以这样引用:
1
2
3
4
5
6
7
8 |
1
<LinearLayout android:layout_width= "fill_parent"
2
android:layout_height= "fill_parent"
3
android:background= "@drawable/repeat_bg" >
4
</LinearLayout>
|
通常情况下,SQL Server里面的生成SQL脚本,只会包含数据库及表的字段结构,而不会包含表的数据,也就是SQL脚本里面只有Create database,Create table 这样的语句,没有insert into。
因为SQL Server并不包含这个功能,只能靠第三方的代码了。
以下存储过程可以实现:
CREATE PROCEDURE dbo.UspOutputData
@tablename sysname
AS
declare @column varchar(1000)
declare @columndata varchar(1000)
declare @sql varchar(4000)
declare @xtype tinyint
declare @name sysname
declare @objectId int
declare @objectname sysname
declare @ident int
set nocount on
set @objectId=object_id(@tablename)
if @objectId is null -- 判断对象是否存在
begin
print 'The object not exists'
return
end
set @objectname=rtrim(object_name(@objectId))
if @objectname is null or charindex(@objectname,@tablename)=0 --此判断不严密
begin
print 'object not in current database'
return
end
if OBJECTPROPERTY(@objectId,'IsTable') < > 1 -- 判断对象是否是table
begin
print 'The object is not table'
return
end
select @ident=status&0x80 from syscolumns where
id=@objectid and status&0x80=0x80
if @ident is not null
print 'SET IDENTITY_INSERT
'+@TableName+' ON'
declare syscolumns_cursor cursor
for select c.name,c.xtype from syscolumns c where
c.id=@objectid order by c.colid
open syscolumns_cursor
set @column=''
set @columndata=''
fetch next from syscolumns_cursor into @name,@xtype
while @@fetch_status < >-1
begin
if @@fetch_status < >-2
begin
if @xtype not in(189,34,35,99,98) --timestamp不需处理,image,text,ntext,sql_variant 暂时不处理
begin
set @column=@column+case when len(@column)=0 then'' else ','end+@name
set @columndata=@columndata+case when len(@columndata)=0 then '' else ','','','
end
+case when @xtype in(167,175) then
'''''''''+'+@name+'+''''''''' --varchar,char
when @xtype in(231,239) then
'''N''''''+'+@name+'+''''''''' --nvarchar,nchar
when @xtype=61 then '''''''''+convert(char(23),'+@name+',121)+''''''''' --datetime
when @xtype=58 then '''''''''+convert(char(16),'+@name+',120)+''''''''' --smalldatetime
when @xtype=36 then '''''''''+convert(char(36),'+@name+')+''''''''' --uniqueidentifier
else @name end
end
end
fetch next from syscolumns_cursor into @name,@xtype
end
close syscolumns_cursor
deallocate syscolumns_cursor
set @sql='set nocount on select ''insert
'+@tablename+'('+@column+') values(''as ''--'','+@columndata+','')'' from
'+@tablenameprint
'--'+@sqlexec(@sql)
if @ident is not null
print 'SET IDENTITY_INSERT
'+@TableName+' OFF'
GO
使用方法:
exec UspOutputData 你的表名
选择【执行模式】为“以文本显示结果”,然后将运行后的结果存成.sql,加上用SQL Server生成的数据库脚本就可以了。
另外可以利用第三方工具,导出数据可以用powerbuilder。在database painter里面,用SQL选出,或者直接打开表,点击生成的list datawindow,然后在菜单file->save rows as->选择SQL,那么生成的SQL语句就包括建表和insert数据的SQL了。
转载:
http://blog.sina.com.cn/s/blog_49b531af0100i74v.html
前言
本章内容是android.widget.CompoundButton,翻译来自德罗德,再次感谢德罗德 !期待你一起参与Android API 的中文翻译,联系我over140@gmail.com。
转载
正文
一、结构
public abstract class CompoundButton extends Button implements Checkable
java.lang.Object
android.view.View android.widget.TextView android.widget.Button android.widget.CompoundButton
二、概述
一个带有选中/未选中状态的按钮。当按钮按下或点中时自动改变状态。
三、公共方法
public boolean dispatchPopulateAccessibilityEvent (AccessibilityEvent event)
在子视图的构建时分派一个辅助事件。(译者注:通过源码可以看出,视图构建时设置其选中状态。)
参数
event 事件
返回值
如果事件全部完成返回True。
public boolean isChecked ()
(译者注:是否选中)
public void onRestoreInstanceState (Parcelable state)
允许视图重新应用以前通过onSaveInstanceState()生成代表内部的状态。这个函数决不调用一个空的状态。
参数
state 返回以前调用onSaveInstanceState()保存下来的状态。
public Parcelable onSaveInstanceState ()
允许视图生成一个代表内部的状态,以后可用于创建一个与之相同的新的实例。这种状态应该只包含非持久或以后不能够重建的信息。例如,你决不存储你当前在屏幕上的位置,因为这会在视图的层面上重新计算放置一个新的实例。
你可以存储到这里的一些例子:一个文本框中当前光标的位置(但通常不是文字本身,文字通常保存在内容提供者(content provider)或其他持久的储存中),一个列表视图中的当前选中项。
返回值
返回一个包含视图当前状态的Parcelable对象,或没有什么状态保存时返回null。默认实现返回null。
public boolean performClick ()
如果视图定义了OnClickListener监听器,调用此方法来执行。
返回值
定义了的OnClickListener被调用返回True,否则返回False
public void setButtonDrawable (Drawable d)
给按钮背景设置一个可绘制对象(如:图像)
参数
d 用作背景的可绘制对象(如:图像)
public void setButtonDrawable (int resid)
通过资源Id给按钮背景设置一个图像
参数
resid 作为背景图像的资源id
public void setChecked (boolean checked)
改变按钮的选中状态
参数
checked true选中,false非选中
public void setOnCheckedChangeListener (CompoundButton.OnCheckedChangeListener listener)
注册一个在按钮状态发生改变时执行的回调函数
参数
listener 当选中状态改变时调用的函数
public void toggle ()
改变选中状态为当前状态的逆状态
四、受保护方法
protected void drawableStateChanged ()
在视图状态的变化影响到所显示可绘制的状态时调用这个方法。
确保在重载时中调用父类方法
protected int[] onCreateDrawableState (int extraSpace)
为当前视图生成新的可绘图区状态。这个方式当缓存的图像绘图区状态确定失效时通过视图系统调用。你可以使用getDrawableState()方法重新取得当前的状态。
参数
extraSpace 如果为非零,这是你应该返回的数组在你可以存放你的状态的额外条目的数量。
返回值
返回一个记录着视图中当前绘图区状态的数组
protected void onDraw (Canvas canvas)
实现你自己的绘制。
参数
canvas 在画布上绘制背景
protected boolean verifyDrawable (Drawable who)
如果你的视图子类显示他自己的可视化对象,他将要重写此方法并且为了显示可绘制返回true。此操作允许进行绘制时有动画效果。
确认当重写从方法时,需调用父类相应方法。
参数
who 需判断的可绘制对象(Drawable)。如果是你要显示的对象,返回True,否则返回调用父类的结果。
返回值
boolean 如果可绘制对象(Drawable)已经在视图中显示,返回True否则返回false。并且此处不允许使用动画。
别人觉得你是不是在打工,这个不重要。重要的是你自己千万别把自己当成打工的,换个角度去看,是公司给你发工资,替你交学费,练着你自己的能力和经验。你遇到产品经理、技术高手,或者公司创始人,从他们身上学到成功的经验,甚至是失败的教训。
我觉得有的人对创业的理解有误区。他们把创业理解成几个哥们开一个公司,回去印几盒名片,我叫董事局主-席,你叫首席执行官,自己的同学脖子上都挂上个CXO,名字很洋气,也不知道什么意思。如果把这个理解为创业就大错特错。
我希望大家这样来理解创业,把创业看成是一种心态,为了实现一个目标,孜孜不倦的去追求。只要你不满足于现状,想法设法去突破,那就是创业。如果你是一个在校学生,是搞电脑,如果你不满足于只是把学分学好,不满足于把考试应付好,而是花了很多时间提高你的编程能力,下了很大功夫来研究很多软件,那这也是创业。学习是这样,工作也是这样,只要你勇敢的正视问题,积极的去解决问题,敢于去承担未来的风险,这其实就是创业心态。
如果我们把创业都理解成我今天出去成立一个公司,明天上市,后天市值超越Facebook,对不起,从来没有过这样成功的例子。天底下哪里有这么一帆风顺的事?把你放在一马平川的大平原上,你凭着直觉沿着直线走,其实从高空看下去,你走出来的路是弯的,是曲折的。创业也是一样,虽然心里有个目标,但是要达到那个目标,你得解决一个个实际的问题。人的路都是一步一步走出来的,而且这个路一定不是直线。
在中国更是这样,环境确实太复杂了。特别是在创业早期,你没有经验,没有资源,你头脑里的创新可能仅仅就是一个想法,一个主意,但如果实现不了,那它就什么都不是。但是,要实现这个想法,这个主意,你需要有判断力,需要有经验,需要有知识。所以,我一直提倡大学生刚毕业的时候,不要头脑一热就攒出一个公司来,最好的方法是加入一家创业公司,甚至可以加入风险很大的种子公司,去学习创业,感受创业。
很多人说,我加入别人的公司,那我不就成了一个打工的了吗?给别人打工,谁认真干呀。错了,如果你觉得自己是打工的,那你一辈子都是打工的。别人觉得你是不是在打工,这个不重要。重要的是你自己千万别把自己当成打工的,换个角度去看,是公司给你发工资,替你交学费,练着你自己的能力和经验。你遇到产品经理、技术高手,或者公司创始人,从他们身上学到成功的经验,甚至是失败的教训。
如果你加入这个公司,这个公司两年之后死了,恭喜你,你一分钱没损失,你参与一个活生生的公司从生到死的例子,你以后就可以避免重蹈覆辙。你一分钱没花,你让一个公司死了一回,你学到了如何避免失败的教训,这是一个多么值的事。这比你拿多少工资,比你到一个有名的大公司,有用多了。
别人一见你,都说你在北京某大公司工作,太了不起。那都是虚荣心,一点意义没有。所以我一直强调,如果你怀着创业的心态,那么你在什么状态都可以叫创业。等到有一天,当你有一股强烈的冲动要办公司去创业的时候,有可能你会发现,人各有所长,你不一定是做CEO的料,但你可能是优秀的CTO,你可能是很好的销售主管,这个时候你就知道找什么样的合伙人去创业了。
所以,我鼓励大家创业,其实是鼓励大家培养创业的精神,我不主张各位一定要出去成立一个公司,那只是一个形式。美国硅谷很多人不是先装模作样地成立一个公司,而是在家里的车库,利用业余时间先搞出来一个产品,这也是创业的一部分。
我不希望传授什么成功学,我最希望大家能够想清楚未来几年自己心里想要什么。在你创业的时候,不论遇到诱惑还是遇到挑战,都能够记住我说的那句话:拒绝平庸,与众不同。你不一定要追随当时的主流,也要能耐得住寂寞,甚至要有一种韧性,敢于屡败屡战,在未来长达五年或者八年、十年的时间里一直坚韧不拔地去探索,我相信五年以后、十年以后,可能中国新一代的企业家,中国新一代的创新领袖应该从各位里面诞生。
android library projects cannot be launched
properties 在android选项中将 is library中将前面的勾去了
BaseAdapter方式
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android1="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ListView
android1:id="@+id/listView1"
android1:layout_width="match_parent"
android1:layout_height="wrap_content"
android1:layout_weight="1" >
</ListView>
</LinearLayout>
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="center_vertical"
android:id="@+id/waibubuju"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/bianhao"
android:text="编号"
android:textColor="#88ff0000"
android:gravity="center"
android:textSize="18sp"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="@+id/neibubuju"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="姓名"
android:id="@+id/username"
/>
MainActivity.java
package com.hyl.listViewpack;
import java.util.ArrayList;
import android.R.string;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.TextView;
public class MainActivity extends Activity {
protected static final String TAG = "MainActivity";
private ListView listView1;
ArrayList<ArrayList<String>> arr ;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView1=(ListView) findViewById(R.id.listView1);
arr=new ArrayList<ArrayList<String>>();
for(int i=0;i<=50;i++){
ArrayList<String> a=new ArrayList<String>();
a.add("编号:"+i);
a.add("姓名:"+i);
a.add("电话:"+i);
arr.add(a);
}
listView1.setAdapter(new BaseAdapter() {
public View getView(int position, View convertView, ViewGroup parent) {
//父窗体 挂载
View view=View.inflate(MainActivity.this, R.layout.list_item, null);
Log.e(TAG, "测试创建对象位置:"+position);
ArrayList<String> a=arr.get(position);
TextView tvbianhao=(TextView) view.findViewById(R.id.bianhao);
tvbianhao.setText( a.get(0));
TextView tvUserName=(TextView) view.findViewById(R.id.username);
tvUserName.setText( a.get(1));
TextView tvTel=(TextView) view.findViewById(R.id.tel);
tvTel.setText( a.get(2));
return view;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public int getCount() {
return arr.size();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="电话"
android:id="@+id/tel"
/>
</LinearLayout>
</LinearLayout>
ArrayAdapter方式
//上下文对象 布局列表对象 显示的TextView的ID 数组对象
listView1.setAdapter(new ArrayAdapter<String>(this, R.layout.list_item, R.id.bianhao, new String[]{"选项一","选项二","选项三","选项四","选项五"}));
SimpleAdapter方式
listView1=(ListView) findViewById(R.id.listView1);
ArrayList<Map<String, Object>> list=new ArrayList<Map<String,Object>>();
Map<String, Object> map1=new HashMap<String, Object>();
map1.put("icon", R.drawable.ic1);
map1.put("name", "功能一");
list.add(map1);
Map<String, Object> map2=new HashMap<String, Object>();
map2.put("icon", R.drawable.ic2);
map2.put("name", "功能二");
list.add(map2);
Map<String, Object> map3=new HashMap<String, Object>();
map3.put("icon", R.drawable.ic3);
map3.put("name", "功能三");
list.add(map3);
Map<String, Object> map4=new HashMap<String, Object>();
map4.put("icon", R.drawable.ic1);
map4.put("name", "功能四");
list.add(map4);
Map<String, Object> map5=new HashMap<String, Object>();
map4.put("icon", R.drawable.ic5);
map4.put("name", "功能五");
list.add(map5);
listView1.setAdapter(new SimpleAdapter(this, list, R.layout.list_item, new String[]{"icon","name"},new int[]{R.id.tubiao,R.id.gongneng} ));
创建一个显示的界面xml
<ListView
android:id="@+id/lv_show_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginTop="16dp" >
</ListView>
再创建一个item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="
http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="250dip"
android:layout_height="wrap_content"
android:id="@+id/title"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/timelength"
/>
</LinearLayout>
导入AsyncHttpClient需要的类
之后
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_list_activy);
lv_show_view = (ListView) findViewById(R.id.lv_show_view);
AsyncHttpClient client=new AsyncHttpClient();
String url = "http://192.168.1.100:8080/videogetxml/GetParamServlet?userName="
+ "测试方法";
client.get(url, new AsyncHttpResponseHandler() {
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
List<Video> list=new ArrayList<Video>();
try {
Toast.makeText(ShowListActivy.this,statusCode+"", 1).show();
String json = new String(responseBody);
JSONArray array = new JSONArray(json);
for(int i=0 ; i < array.length() ; i++){
JSONObject item= array.getJSONObject(i);
String id = item.getString("id");
String title = item.getString("title");
String timelength = item.getString("time");
Log.e("jsonget", id+title+timelength);
list.add(new Video( id, title, Integer.parseInt(timelength)));
}
List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
for (Video v : list) {
Map<String, Object> it = new HashMap<String, Object>();
it.put("id", v.getId());
it.put("title", v.getTitle());
it.put("timelength", v.getTime());
data.add(it);
}
SimpleAdapter adapter = new SimpleAdapter(ShowListActivy.this, data,R.layout.item, new String[] { "title", "timelength" },new int[] { R.id.title, R.id.timelength });
lv_show_view.setAdapter(adapter);
} catch ( Exception e) {
Log.e("MainActivity", e.toString());
}
}
public void onFailure(int statusCode, Header[] headers,
byte[] responseBody, Throwable error) {
Toast.makeText(ShowListActivy.this,"shibai", 1).show();
}
});
显示出传过来的json结果:
本文章只是自己学习笔记,大家要慎重借鉴
package com.shxt.controller;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DownLoadServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("application/x-msdownload");
PrintWriter out = response.getWriter();
response.reset();// 可以加也可以不加
response.setContentType("application/x-download");
String filedownload = request.getRealPath("/images")
+ "\\02_开发第一个无状态会话bean.avi";// "想办法找到要提供下载的文件的物理路径+文件名";
System.out.print(filedownload);
String filedisplay = "okokok.avi";// "给用户提供的下载文件名";
filedisplay = URLEncoder.encode(filedisplay, "UTF-8");
response.addHeader("Content-Disposition", "attachment;filename="
+ filedisplay);
OutputStream outp = null;
FileInputStream in = null;
try {
outp = response.getOutputStream();
// 你可以指定你的ftp输入流
in = new FileInputStream(new File(filedownload));
byte[] b = new byte[1024];
int i = 0;
while ((i = in.read(b)) > 0) {
outp.write(b, 0, i);
}
outp.flush();
} catch (Exception e) {
System.out.println("Error!");
e.printStackTrace();
} finally {
if (in != null) {
in.close();
in = null;
}
if (outp != null) {
outp.close();
outp = null;
}
//out.clear();
//out = pageContext.pushBody();
}
}
}
摘要: 转自:转载请标明出处:http://blog.csdn.net/anyoneking/archive/2008/05/23/2472145.aspx1.回传一个普通的String字符串.2.回传一个组织好的Javascript字符串.3.回传一个Json对象.(需要引入json.jar)4.回传一个XML对象.基本实现如下:其中测试页面为:
<%@page language="j...
阅读全文
经过试验后发现HTML锚点在JSP中并不兼容。两者表示锚点的方法有所不同
HTML锚点
<a href="#1">goto1</a>
.
.
.
.
<a name="1">111</a>
这样从goto1可以定位到111
JSP锚点
<a href="javascript:void(0)" onclick="document.getElementById('1').scrollIntoView();">goto1</a>
。
。
。
<a id="1">1111</a>
HTML to PDF conversion for your website or application
http://www.htm2pdf.co.uk/
通过js事件获取元素中的属性值
<div id="c-title1" onclick="openAndClose(this)" value="content1" >报告概览</div>
function openAndClose(myelement) {
alert(myelement.attributes["value"].value );
}
js中动态生成表格
function createTable() {
var t = document.getElementById("myT");
for ( var i = 0; i < 3; i++) {
var r = t.insertRow();
for ( var j = 0; j < 2; j++) {
var c = r.insertCell();
if (j == 0) {
c.innerHTML = "姓名:"+i+","+j;
} else {
c.innerHTML = "<input type='text' name='n' />";
}
}
}
t.setAttribute('border', '1');
}
function deleteTable() {
var objTable = document.getElementById("myT");
objTable.setAttribute('border', '0');
for ( var i = 0; i <= objTable.rows.length+1; i++) {
objTable.deleteRow(0);
}
}
jsp中的表单引发事件
<input type="button" onclick="createTable()" name="ty" value="试题类型" />
<input type="button" onclick="deleteTable()" name="re" value="清除表格" />
<table id="myT">
</table>
JSTL获取list的大小,jstl获取list 的长度,EL表达式获取list的长度,EL表达式获取list大小 在jsp页面中不能通过${list.size}取列表长度,而是 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> <c:out value="${fn:length(list)}"></c:out>
Spring MVC使用动态代理实现事务控制
applicationContext.xml文件中配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"
default-lazy-init="true">
<!--
spring在启动的时候,会默认加载会默认加载整个对象实例图,从初始化ACTION配置、到
service配置到dao配置、乃至到数据库连接、事务等等。这样可以减少web服务器在运行时的负担,但是对于开发者来说无疑是效率极低的一个设置了。
还好,spring提供了default-lazy-init属性,其配置形式如下,applicationContext.xml中: <
beans default-lazy-init ="true" > < bean class ="org.xxxx.bean" >
。。。。。。 </beans>
spring配置默认default-lazy-init为false,当配置为true时sping不会再去加载整个对象实例图,大大减少了初始化的时间,减少了spring的启动速度。
这样做只是为了在开发过程中节约启动时间,在部署到实际环境中,倒是没必要设置default-lazy-init为true。毕竟部署到实际环境中不是经常的事,每次启动1分钟倒不是大问题,而且可以提高服务器效率。
当然,也不是所有的beans都能设置default-lazy-init成为true.对于scheduler的bean不能用lazy-init
< beans default-lazy-init ="true" > < bean class
="org.springframework.scheduling.quartz.SchedulerFactoryBean" > <
property name ="triggers" > < list > < ref bean ="buildHtmlTrigger" />
< ref bean ="askTrigger" /> < ref bean ="mailSenderTrigger" /> < ref
bean ="topicDetailBuildTrigger" /> < ref bean ="forumBuildTrigger" />
< ref bean ="topicBuildTrigger" /> </ list > </ property > </ bean >
</ beans > 这样的话。所有的scheduler就都不管用了。所以请大家要注意。
-->
<!-- 使用annotation 自动注册bean, 并保证@Required、@Autowired的属性被注入 -->
<context:component-scan base-package="com.edufe">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<context:property-placeholder
ignore-resource-not-found="true"
location="classpath*:/application.properties,
classpath*:/application.development.properties" />
<!-- 创建数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- 使用嵌入式数据库H2 -->
<!--
<jdbc:embedded-database id="dataSource" type="H2"> <jdbc:script
location="classpath:sql/h2/schema.sql" /> <jdbc:script
location="classpath:sql/h2/import-data.sql" />
</jdbc:embedded-database>
-->
<!-- 创建jdbcTemplate对象 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 在容器文件中配置bean(service,dao,domain,action,数据源), -->
<!--
bean的作用是, 当我们spring框架加载的时候,spring就会自动创建一个bean,并放入内存 即产生UserService
user=new UserService(); user.setName("张三");
-->
<!--
<bean id="userService" class=""> 这里就体现出了注入的概念 <property name="name">
<value>张三</value> </property> 在UserService中引用ByeService的对象ref是个引用
<property name="byeS" ref="byeService" /> </bean>
-->
<!-- 处理事务 -->
<!-- 生成一个事务管理对象 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg index="0" ref="dataSource">
</constructor-arg>
</bean>
<!-- 生成默认事务定义对象 -->
<bean id="def" class="org.springframework.transaction.support.DefaultTransactionDefinition"></bean>
</beans>
在dao中
@Autowired
private DataSourceTransactionManager transactionManager;
@Autowired
private DefaultTransactionDefinition def;
public int excuteTrac() {
int temp = 0;
// 批插入
String sql1[] = new String[4];
// 向第一个表插入的语句
sql1[0] = "insert into usermbo( ID, USERNAME, age) values('122','22','22')";
sql1[1] = "insert into usermbo( ID, USERNAME, age) values('133','33','33')";
sql1[2] = "insert into usermbo( ID, USERNAME, age) values('144','44','33')";
sql1[3] = "insert into usermbo( ID, USERNAME, age) values('155','55','33')";
String[] sql2 = new String[3];
// 向第二个表插入的语句
sql2[0] = "insert into address (NO, NAME) values('33','33')";
// 此条数据是错误数据 插入会出现异常
sql2[1] = "insert into address (NO, NAME) values('eee','44')";
sql2[2] = "insert into address (NO, NAME) values('144','44')";
TransactionStatus status = transactionManager.getTransaction(def);
try {
int[] a = jdbcTemplate.batchUpdate(sql1);
int[] b = jdbcTemplate.batchUpdate(sql2);
try {
transactionManager.commit(status);
} catch (Exception e) {
System.out.println("事务提交异常");
}
} catch (Exception ex) {
System.out.println("出现事务异常");
try {
transactionManager.rollback(status);
} catch (IllegalTransactionStateException e) {
System.out.println("回滚数据异常");
}
temp = -1;
}
return temp;
}
JdbcTemplate使用事务控制批处理
//在dao中写的一个方法
public int excuteTrac() {
int temp = 0;
// 批插入
String sql1[] = new String[4];
//向第一个表插入的语句
sql1[0] = "insert into usermbo(USERNAME,age,PASSWORD) values(' 23 ','3','45')";
sql1[1] = "insert into usermbo(USERNAME,age,PASSWORD) values('22 ','22','22')";
sql1[2] = "insert into usermbo(USERNAME,age,PASSWORD) values(' 44 ','44','4')";
sql1[3] = "insert into usermbo(USERNAME,age,PASSWORD) values(' 55 ','55','55')";
String[] sql2 = new String[3];
//向第二个表插入的语句
sql2[0] = "insert into address(NO,NAME) values('21','33')";
// 此条数据是错误数据 插入会出现异常
sql2[1] = "insert into address(NO,NAME) values('ee','44')";
sql2[2] = "insert into address(NO,NAME) values('44','44')";
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(
jdbcTemplate.getDataSource());
TransactionStatus status = transactionManager.getTransaction(def);
try {
int[] a = jdbcTemplate.batchUpdate(sql1);
int[] b = jdbcTemplate.batchUpdate(sql2);
for (int x : a) {
System.out.println(x);
}
for (int x : b) {
System.out.println(x);
}
} catch (Exception ex) {
System.out.println("出现事务异常");
// transactionManager.rollback(status);
temp = -1;
} finally {
transactionManager.commit(status);
}
return temp;
}
监听键盘按下键的值(兼容IE与其他浏览器)
function getKeyPressCode(event) {
/*
//此种方法不可取
if(event.keyCode!=0) // IE
{
keynum = event.keyCode;
}
else if(event.which!=0) // Netscape/Firefox/Opera
{
keynum = event.which;
}
alert(keynum);
*/
//此种方法可行
var keycode;
if (navigator.appName == "Microsoft Internet Explorer") { // IE
keycode = event.keyCode;
} else { // Netscape/Firefox/Opera
keycode = event.which;
}
alert("按键码: " + keycode );
}
<script type="text/javascript">
function noNumbers(e)
{
var keynum;
var keychar;
var numcheck;
if(window.event) // IE
{
keynum = e.keyCode;
}
else if(e.which) // Netscape/Firefox/Opera
{
keynum = e.which;
}
keychar = String.fromCharCode(keynum);
numcheck = /\d/;
return numcheck.test(keychar);
}
</script>
<form>
Type some text (numbers not allowed):
<input type="text" onkeypress="return noNumbers(event)" />
</form>
博鳌亚洲论坛
央视记者何岩柯与比尔盖茨对话
何岩柯:
你好!比尔盖茨先生,能够和您对话是我们的荣幸。
盖茨:
我也很荣幸
何岩柯:
首先我想跟您确定一件事,你更喜欢被看作是一个企业家,还是一个慈善家
盖茨:
我现在大部分时间都用于盖茨基金的工作,但是我仍然是微软的主席,我要向他们提出意见,所以我两方面都有所涉及,我的员工和团队都很优秀,我觉得很幸运。
何岩柯:
我们发现你们做慈善的方式,和别人不同,很多慈善组织只是给钱,而你们是给别人一种方法,去谋生,为什么?
盖茨:
我觉得最好的慈善,(扶了扶眼镜)是你为人们提供种子教育,如果你觉得问题有可能解决,你缺少的就是让科学家了解这些问题,获取所需的资源,我们了解了很多关于健康方面的知识,为什么贫困国家的儿童有这么高的死亡率?为什么非洲国家的生产率比美国低这么多?
如果你了解这些状况,你就知道把好的做法普及到世界上最贫困的地方,。
何岩柯:
习近平主席在开幕式上,做了主旨演讲,你也在现场,我在想有关这个演讲,哪点让你最深刻?
盖茨:
我觉得习主席一直都强调,中国的角色是要帮助世界上其他国家,关于中国梦的主题,在其他演讲中也都有提到,我觉得这是很重要的信息,中国是消除贫困、疾病和在教育领域投资的很好典范,中国有越来越多的科学家,他们的研究不仅对中国有价值,对全世界都很有价值,包括他第一次出访,就去了非洲最需要帮助的国家,他夫人也去了,我觉得非常的兴奋,这是很好的开始。
何岩柯:
智能手机,触屏技术以及云技术,这些新的技术,极大改变我们的生活,但这些技术都不是
微软所发展的,作为微软的创立者,会感到有些失望吗?
盖茨:
微软无疑也做的很好,It领域有件很棒的事情,就是同时有很多优秀的公司,我们在做Xbox识别人脸,你看 比如微软的Office,微软在这方面无疑是领先者,尽管谷歌在搜索引擎方面做的很好,但我们也有我们的搜索引擎必应,我们的研究团队对此很有贡献,他在行业中也是领先者,微软会全力以赴做到行业领先,但是这个行业最优秀成功的,不可能来自一个
公司,微软公司正是,这些优秀公司的其中之一。
何岩柯:
您认为微软还是很有竞争力?
盖茨:
当然,我们有很棒的人才,很棒的北京实验室,我们在北京的实验室对此很有贡献。
何岩柯:
我突然想起一个很有意思的说法,当苹果失去乔布斯,就失去了味道,当微软失去了比尔盖茨,也不再是以前的微软,你怎么看这个说法?你同意吗?
盖茨:
技术公司是一直在持续变化,无论你的创意,在十年前五年前有多棒,现在都不适用了,所以你必须有革新意识,你比别人多想一步,即便是微软办公室的白板,我们想办法改变它变化他,有很多领域,微软都想去进行革新,一个公司不是靠一个人可以支撑的,也适用于苹果公司,所以微软会继续做的很棒,我现在全职在盖茨基金会工作,我相信这样同样很重要,我会全力以赴。
何岩柯:
你在人民日报发表了篇文章,有关中国的农业革新,你提到了中国的杂交水稻之父袁隆平,他为世界做出了很多贡献,这一次袁隆平也在参加博鳌论坛,有机会和他交流一下吗?
盖茨:
很遗憾,没机会见到他,杂交水稻是帮助最贫困人群的一个很好的例子,但是现在杂交水稻主要只有中国有,现在的问题是如何普及到世界上的其他国家,比如说非洲,谁来提供种子,
如何让价格合理。
何岩柯:
您如何看待中国的创新能力?
盖茨:
中国的创新能力每年都在增长,中国的大学都很致力于自身提高,比如清华大学已经做的很优秀了,在IT方面有很多的投入,有很多的工程师毕业,生物领域也做的很好,这很令人兴奋。
何岩柯:
我们听说盖茨基金会和中国政府,建立了不少合作项目,这些合作进展如何?
盖茨:
我们最早是和卫生部合作,防治艾滋病,如何减少吸烟,因为吸烟会引起癌症,这些合作很顺利,现在我们正在和科技部合作,因为他们能找到创新者,很多人领域是普通人没有想到的,比如说给动物的疫苗,在这些论坛上,我能够见到很多中国的领导者,我们可以交流下彼此的梦想,我们就可以发现,我们有很多的共同点。
2013年4月8日
ORA-12541:TNS:无监听程序的错误,
如何启动oracle的监听。
1.打开Net Configuration Assistant
2.选择监听程序配置,下一步
3.选择重新配置,下一步
4.选择监听程序,默认,下一步
注:如果你的监听已启动,则出现提示框,选择是
5.选择协议,使用默认的TCP协议,下一步
6.选择端口号,使用标准端口号1521,下一步
7.不配置另一个监听程序,选择否,下一步
8.监听程序配置完成,下一步
到此基本就可以运行了,你重新开启oracle的服务,测试看能否连上plsql
重配服务名,测试连接
1.选择Net服务器配置,下一步
2.选择重新配置,下一步
3.选择数据库名,下一步
4.填写服务名,也就是你创建数据库时的全数据库名,下一步
5.选择TCP协议,下一步
6.填写主机名(可填写你的IP地址,也可填写你的主机名),使用标准端口号1521,下一步
7.进行测试,下一步
8.选择更改登录
9.填写用户名和口令,确定
10.测试连接成功,下一步
11.网络服务名,默认(和之前的数据库名一样),下一步
12.不配置另一个Net服务名,选择否,下一步
13.Net服务名配置完毕,下一步,完成
启动PL/SQLDeveloper,输入用户名和口令,登录成功
小结:很多错误都有很明显的提示,要根据提示去找相关的解决办法。
<script type="text/javascript">
window.parent.dialogArguments.document.execCommand('Refresh');
</script>
浮层内嵌iframe及frame集合窗口,刷新父页面的多种方法
<script type="text/javascript">
window.parent.location.reload();
</script> 弹出子页面<script type="text/javascript">
window.opener.location.reload();
</script>
子窗口刷新父窗口
<script type="text/javascript">
window.self.opener.location.reload();
</script>
刷新以open()方法打开的窗口[上面的弹出子页面也可以完成]<script type="text/javascript">
window.opener.location.href=window.opener.location.href;
</script>
javascript对象冒充示例
<script type="text/javascript">
function Animal(name,age){
this.name=name;
this.age=age;
this.eat=function(){
alert("动物可以吃东西");
}
}
function Dog(name,age){
//把Animal构造函数赋给this.an
this.an=Animal;
//运行调用@!!!!非常重要
this.an(name,age);
}
var dog=new Dog("小白",2);
alert(dog.name);
dog.eat();
</script>
<input name="keyword" type="text" value="请输入关键字" onFocus="this.value=''" onBlur="if(!value){value=defaultValue;}"/>
<a href="javascript:void(0)" onclick="changeMa()">看不清</a>
onclick事件会被引发,但是不会发生任何跳转,相当于一个死链接
<select id="myCol" onchange="getChange()">
<option value="1">
大连交大
</option>
<option value="2">
东北财经
</option>
<option value="3">
大连海事
</option>
</select>
<select id="myGet">
</select>
<script type="text/javascript" >
function getChange() {
//获取到第一个select表单value值
var myCol = document.getElementById("myCol").value;
//拼接成要获取值的url
var url = "getCateGory?myCol=" + myCol; //url
//利用jquery的ajax方法,使用此方法要引jquery包
htmlobj = $.ajax( {
url : url,
async : false
});
//此处利用json处理值,还需要引json包,在服务器端可以使用GSON转化数据,响应当前页面
/*服务器端:
//需要引GSON包
//创建一个Gson对象
Gson gson = new Gson();
//返回一个json格式的字符串
String pStr = gson.toJson(user);
System.out.println(pStr);
out.print(pStr);
*/
//接取响应值,并且转化成JSON对象
var obj = JSON.parse(htmlobj.responseText);
//此变量是为拼接而做
var options = "";
var myGet = document.getElementById("myGet");
//myGet.removeChild("option");
//删除现有option节点
for ( var i = 1; i <= myGet.length; i++) {
myGet.remove(i);
}
myGet.remove(myGet.selectedIndex);
//利用循环,在此将新的option添加上
for(var i=0;i<obj.length;i++){
alert(obj[i].uUserName);
var myOption=document.createElement("option");
myOption.setAttribute("value",obj[i].uId);
var testN=document.createTextNode(obj[i].uUserName);
myOption.appendChild(testN);
myGet.appendChild(myOption);
//此种方法最简单,但是没有技术含量
//options+="<option value='"+obj[i].uId+"'>"+obj[i].uUserName+"</option>";
}
// myGet.innerHTML=options;
}
</script>
这里的级联查询仿照Hibernate中的一对多关系映射,写个例子留个笔记
(地址表主表,用户表从表)
用户表(类)User
成员变量如下,并且对应有get和set方法
private String uId;
private String uUserName;
private String uPassWord;
private String uTelephone;
private int uAge;
private Date uBirthday;
对应的表如下:
地址表(类)Address成员变量如下:
private int no;
private String name;
private List<User> userList;
对应的UserDao中先写:
public List<User> findByAddressId(int a){
String sql="select * from usermbo where address=?";
List<User> users = new ArrayList<User>();
Object[] params=new Object[]{a};
users = jdbcTemplate.query(sql,params, new UserRowMapper() );
return users;
}
private class UserRowMapper implements ParameterizedRowMapper<User>{
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
User user = new User();
user.setuUserName(rs.getString("username"));
user.setuAge(rs.getInt("age"));
user.setuId(rs.getInt("id")+"");
user.setuTelephone(rs.getString("telephone"));
return user;
}
}
此部完成以后,再写AddressDao
@Autowired
private UserDao userDao ;
public List<Address> getAddress(){
String sql="select * from address";
List<Address> addresss = new ArrayList<Address>();
addresss = jdbcTemplate.query(sql, new AddressRowMapper() );
return addresss;
}
private class AddressRowMapper implements ParameterizedRowMapper<Address>{
public Address mapRow(ResultSet rs, int rowNum) throws SQLException {
Address address=new Address( );
address.setNo(rs.getInt("no"));
address.setName(rs.getString("name"));
address.setUserList( userDao.findByAddressId(rs.getInt("no")));
return address;
}
}
Service层再配一下(此层不配也行直接将
@Autowired
private AddressDao addressDao ;引入Controllar中即可)
在Controllar中再写
addressService.getAddress()就可以查出结果
[Address [name=计算力, no=1, userList=[User [uAddress=null, uAge=12, uBirthday=null, uId=11, uPassWord=null, uTelephone=1234567, uUserName=张三]]], Address [name=大连, no=2, userList=[]], Address [name=海南, no=3, userList=[User [uAddress=null, uAge=34, uBirthday=null, uId=12, uPassWord=null, uTelephone=2323232323, uUserName=李四], User [uAddress=null, uAge=33, uBirthday=null, uId=13, uPassWord=null, uTelephone=2323, uUserName=王武]]]]
SPRING-MVC访问静态文件,如jpg,js,css
如何你的DispatcherServlet拦截 *.do这样的URL,就不存在访问不到静态资源的问题。如果你的DispatcherServlet拦截“/”,拦截了所有的请求,同时对*.js,*.jpg的访问也就被拦截了。
目的:可以正常访问静态文件,不要找不到静态文件报404。
方案一:激活Tomcat的defaultServlet来处理静态文件
Xml代码
<servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.jpg</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.js</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.css</url-pattern> </servlet-mapping> 要配置多个,每种文件配置一个
要写在DispatcherServlet的前面, 让defaultServlet先拦截,这个就不会进入Spring了,我想性能是最好的吧。
Tomcat, Jetty, JBoss, and GlassFish 默认 Servlet的名字 -- "default"
Google App Engine 默认 Servlet的名字 -- "_ah_default"
Resin 默认 Servlet的名字 -- "resin-file"
WebLogic 默认 Servlet的名字 -- "FileServlet"
WebSphere 默认 Servlet的名字 -- "SimpleFileServlet"
方案二: 在spring3.0.4以后版本提供了mvc:resources
mvc:resources 的使用方法:
Xml代码
<!-- 对静态资源文件的访问 --> <mvc:resources mapping="/images/**" location="/images/" />
/images/**映射到 ResourceHttpRequestHandler进行处理,location指定静态资源的位置.可以是web application根目录下、jar包里面,这样可以把静态资源压缩到jar包中。cache-period 可以使得静态资源进行web cache
如果出现下面的错误,可能是没有配置<mvc:annotation-driven />的原因。
报错WARNING: No mapping found for HTTP request with URI [/mvc/user/findUser/lisi/770] in DispatcherServlet with name 'springMVC'
使用<mvc:resources/>元素,把mapping的URI注册到SimpleUrlHandlerMapping的urlMap中,
key为mapping的URI pattern值,而value为ResourceHttpRequestHandler,
这样就巧妙的把对静态资源的访问由HandlerMapping转到ResourceHttpRequestHandler处理并返回,所以就支持classpath目录,jar包内静态资源的访问.
另外需要注意的一点是,不要对SimpleUrlHandlerMapping设置defaultHandler.因为对static uri的defaultHandler就是ResourceHttpRequestHandler,
否则无法处理static resources request.
方案三 ,使用<mvc:default-servlet-handler/>
Xml代码
<mvc:default-servlet-handler/>
会把"/**" url,注册到SimpleUrlHandlerMapping的urlMap中,把对静态资源的访问由HandlerMapping转到 org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler 处理并返回.
DefaultServletHttpRequestHandler使用就是各个Servlet容器自己的默认Servlet.
补充说明:多个HandlerMapping的执行顺序问题:
DefaultAnnotationHandlerMapping的order属性值是:0
<mvc:resources/ >自动注册的 SimpleUrlHandlerMapping的order属性值是: 2147483646
<mvc:default-servlet-handler/>自动注册的SimpleUrlHandlerMapping的order属性值是:2147483647
spring会先执行order值比较小的。当访问一个a.jpg图片文件时,先通过DefaultAnnotationHandlerMapping 来找处理器,一定是找不到的,我们没有叫a.jpg的Action。再按order值升序找,由于最后一个SimpleUrlHandlerMapping 是匹配"/**"的,所以一定会匹配上,再响应图片。
访问一个图片,还要走层层匹配。真不知性能如何?改天做一下压力测试,与Apache比一比。
最后再说明一下,如何你的DispatcherServlet拦截 *.do这样的URL,就不存上述问题了。
转载至:http://hi.baidu.com/blueskyfaith/item/a47483a91d5cfce015329b98
在JSP编程的过程中会遇到各种各样的问题
JSP常见问题1:
表单request汉字处理:
- request.setCharacterEncoding("GB2312")
JSP常见问题2:
在JSP网页中获取页面的名称:
- request.getRequestURI() ;//文件名
- request.getRequestURL() ;//全部url
JSP常见问题3:
页面不保留缓存:
- response.setHeader("Pragma","No-cache");
- response.setHeader("Cache-Control","no-cache");
- response.setDateHeader("Expires", 0);
-
JSP常见问题4:
日期时间(服务器端)
- String datestr ;
- java.text.DateFormat df = new java.text.SimpleDateFormat("MM月dd日 HH:mm E"); //这里格式化
- datestr = df.format(new java.util.Date()) ;
- out.println(datestr);
-
或者
- % java.util.Date shijian= new java.util.Date();%>
- %=shijian.getYear()+1900%>%=shijian.getMonth()+1%>%=shijian.getDate()%>
- %=shijian.getHour()%>%=shijian.getMinute()%>
-
JSP常见问题5:
java中运用正则。
jdk需是1.4以上 import="java.util.regex.*
JSP常见问题6:
点后退显示网页过期
在里面加以下代码
- META http-equiv=Pragma content=no-cache
- META http-equiv=Cache-Control content=no-cache
- META http-equiv=Expires content=0
-
和 3 原理一样。
JSP常见问7:
swtich不能作用在long上和String上:
switch(expr1)中,expr1是一个整数表达式。传递给 switch 和 case 语句的参数应该是
int、 short、 char 或者 byte。long,string 都不能作用于swtich。
JSP常见问题8:
计算执行所花费的时间
代码开始取时间,结束后取时间,相减
- long t1 = System.currentTimeMillis();
- .... ...... .... ...your code
- long t2 = System.currentTimeMillis() ;
- long time = t2-t1;
-
JSP常见问题9:
四舍五入,保留小数点后两位小数?
- import java.text.*;
- NumberFormat nf=NumberFormat.getNumberInstance();
- nf.setMaximumFractionDigits(2);
- nf.setMinimumFractionDigits(2);
- nf.format(numb);
或者(+0.005 - 0.01)再取.后两位
JSP常见问题10:
form的默认方法是get.
post方式是向服务器传送大容量数据时使用的方法。(再打开一个socket.?)
JSP常见问题11:
防止用户直接输入url进去页面:
◆是在要访问的页面中加入控制.这个一般用session。
◆是从web服务器控制,对某一目录的所有访问要通过验证.(有人说把jsp放到web-inf下)
JSP常见问题12:
数据库是datetime 型 ,插入当前时间到数据库:
- java.sql.Date sqlDate = new java.sql.Date();
- PreparedStatement pstmt = conn.prepareStatement("insert into foo(time) values(?)");
- pstmt.setDate(1,sqlDate);
- pstmt.executeUpdate();
-
其实一般数据库都有自己的系统时间函数。
insert into foo(time) values(sysdate)
JSP常见问题13:
session存取int类型的变量:
- session.setAttribute("int", i+""); //注意这里i+""
- int i = Integer.parseInt(session.getAttribute("int"));
-
session的一些概念。
用户在浏览网页时,由于Http 协议是一种无状态的协议,往往在不同的页面之间存在数据交换的问题,这就需要在这些不同的页面之间共享数据。常见的实现方法是把要共享的数据保存到 Session 中。比如在用户登录的页面中把一些用户的信息保存到Session 之中,然后在其他的页面中读取用户的信息。这些共享的数据可以是字符串或者与Java 的原始数据类型相关的对象,也可以是一个Java 对象。
Session 只能保存对象,不能保存原始的数据类型,比如:
session.setAttribute(“count”,10)
是非法的语句,如果要把值为10 的整数保存到Session 中,需要使用以下的方法:
session.setAttribute(“count”,new Integer(10));
然后在另一个页面中使用:
(Integer)session.getAttribute(“count”)
来把这个整数读取出来。
was中设置可以把session放在系统的数据库中,但这样影响效率。session大小最好不要太大
JSP常见问题14:
把字符转化成ASCII码
int a='A'; out.println(a);
JSP常见问题15:
String s = new String("xyz");创建了两个String Object对象,一个是“xyx”,一个是指向“xyx”的引用对象s。
还有典型的equals() 与 == 这个参考在堆栈原理。
JSP常见问题16:
Hashtable和HashMap
Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现HashMap允许将null作为一个entry的key或者value,而Hashtable不允许
Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap就必须为之提供外同步。
师者,所以传道授业解惑也。”一千多年前韩愈在《师说》里讲的这句话,几乎成了教师职业的定义,直到今天,我们很多中小学老师仍然常常以“传道授业解惑”者自居,却不知韩老先生说的“传道授业解惑”,本不是指的中小学老师。
韩愈在《师说》中说得很清楚:“彼童子之师,授之书而习其句读者也,非吾所谓传其道、解其惑者也。”(那些小孩子的老师,是教孩子读书,掌握句读的,并不是我所谓的传授道理、解答疑难的人)古代所谓的“童子”,大致相当于今天的未成年人,也就是中小学生。这些孩子的老师的工作,在韩愈眼里,是谈不到“传道授业解惑”的。可见,今天中小学教师以传道授业解惑者自居,并不符合韩老先生的本意。
韩愈的这种态度说明了什么呢?我想,这一方面说明了韩愈对基础教育的轻视,另一方面也说明了他的清醒。我国古代的教育,基本上是成人教育,孔子的学生好像没有未成年人,都是大老爷们。所以我国古代的教育思想,都是成人教育思想,那时的教育家们,对于儿童心理和儿童的成长规律,比较生疏,也不屑于研究,这应该说是一个缺点。这也提醒我们,在继承古代教育思想的时候,要注意有所分析、改造和取舍,不能盲目传承。
今天的中小学教师,张口就说什么“传道授业解惑”,这是比较盲目的。同时我们应该看到,韩愈的这种态度自有一定的合理性。他对未成年人的教育,期望值不算高,相较于今日每天高喊“人文主义”的教育者们,我觉得韩愈的头脑没有发热,他并不指望孩子小小年纪就能入“道”。韩愈的要求或许低了点,基础教育确有影响学生世界观价值观的作用,但是,把“立人”的千钧重担都放在或主要放在中小学教师的身上,显然缺乏合理性。
不过,传道授业解惑这种提法,用于今日,毛病还是很大的。传,授,解,分明是一副教师中心,居高临下的姿态,抹杀了受教育者的主体性,有明显的灌输色彩。这种教育姿态,无论在成人教育、高等教育还是基础教育中,都是落后的。
要“解惑”当然必须学习,但学习不等于必须“从师”,“从师”而学只是学习的一部分,或者一小部分。离开学习就没有老师,离开老师却有学习。“惑而不从师,其为惑也,终不解矣”,等于宣布学生不可能超过老师,也就等于否定了革新和创造,剩下的只有继承。这是一种将人际关系凌驾于智慧之上的思维方式,是学习领域中的“人治”。它当然会抑制智慧的发展。这是一种封闭的思维方式,它只有单向的传递,没有双向的交流。它当然会抑制科学的进步。西方的哲人却另有一种思维方式:“我爱老师,但更爱真理!”这是一种真理高于人际关系的思维方式。这是一种开放的、双向的思维方式。它推动了西方智慧的发展,科学的进步。
往事越千年。在我们的学校里,绝大部分老师至今还姓“韩”,学生还是在等着老师来“解惑”,甚至连他们的“惑”都是老师提出的,只是一种“解惑表演。”(考试不就是这样吗)我见到有的博士生,一接触到和导师不同的见解,立刻噤若寒蝉,一副“若为尊师故,真理亦可抛”的架式。你看这人际关系有多么厉害!要想鼓励创新,只好对“惑而不从师 ,其为惑也,终不解矣”的思维方式进行改革,没有办法。
转载至:http://hnpx.cersp.com/article/browse/102634.jspx
摘要: 摘要:虽然session机制在web应用程序中被采用已经很长时间了,但是仍然有很多人不清楚session机制的本质,以至不能正确的应用这一技术。本文将详细讨论session的工作机制并且对在Java web application中应用session机制时常见的问题作出解答。目录:一、术语session二、HTTP协议与状态保持三、理解cookie机制四、理解session机制...
阅读全文
WebSocket是一种比HTTP协议更加高效的网络传输协议,它有效地减少了HTTP头中的冗余信息和网络延时,能够提供客户端-服务器和服务器-客户端的双通道实时通信,同时具有很好的安全机制。基于WebSocket的URL通常以WS://...开头,类似于HTTPS,安全的WebSocket连接URL通常以WSS://...开头。要实现WebSocket通信,需要客户端浏览器支持WebSocket,服务器端也必须支持WebSocket。
WebSocket还具有广播功能,当有多个监听者连接时,广播服务器发送的消息都可被接收到。
2.浏览器支持检测
function loadDemo()
{
if (window.WebSocket)
{
document.getElementById("support").innerHTML = "HTML5 WebSocket is supported in your browser.";
} else
{
document.getElementById("support").innerHTML = "HTML5 WebSocket is not supported in your browser.";
}
}
3.WebSocket对象
WebSocket在DOM中是window对象的子对象,它具有:
•WebSocket(url)构造函数。
•readyState。只读属性,其值可以是CONNECTING(0),OPEN(1),CLOSED(3)。
•boolean send(in DOMString data)和void close()两个方法,分别用于发送消息和关闭WebSocket连接
•onopen, onmessage, 和onclosee三个事件属性,分别对open, message和close三个WebSocket事件。
3.使用WebSocket的步骤
//建立连接
url = "ws://localhost:8080/echo";
w = new WebSocket(url);
//事件监听
w.onopen = function() {
log("open"); w.send("thank you for accepting this websocket request");
}
w.onmessage = function(e) {
log(e.data);
}
w.onclose = function(e) {
log("closed");
}
//发送消息
document.getElementById("sendButton").onclick = function() {
w.send(document.getElementById("inputMessage").value);
}
//关闭连接。一般情况下不关闭,以保持实时通信
w.close();
在HTML5的Canvas上绘制椭圆的几种方法
概述
HTML5中的Canvas并没有直接提供绘制椭圆的方法,下面是对几种绘制方法的总结。各种方法各有优缺,视情况选用。各方法的参数相同:
context为Canvas的2D绘图环境对象,
x为椭圆中心横坐标,
y为椭圆中心纵坐标,
a为椭圆横半轴长,
b为椭圆纵半轴长。
参数方程法
该方法利用椭圆的参数方程来绘制椭圆
//-----------用参数方程绘制椭圆---------------------
//函数的参数x,y为椭圆中心;a,b分别为椭圆横半轴、
//纵半轴长度,不可同时为0
//该方法的缺点是,当lineWidth较宽,椭圆较扁时
//椭圆内部长轴端较为尖锐,不平滑,效率较低
function ParamEllipse(context, x, y, a, b)
{
//max是等于1除以长轴值a和b中的较大者
//i每次循环增加1/max,表示度数的增加
//这样可以使得每次循环所绘制的路径(弧线)接近1像素
var step = (a > b) ? 1 / a : 1 / b;
context.beginPath();
context.moveTo(x + a, y); //从椭圆的左端点开始绘制
for (var i = 0; i < 2 * Math.PI; i += step)
{
//参数方程为x = a * cos(i), y = b * sin(i),
//参数为i,表示度数(弧度)
context.lineTo(x + a * Math.cos(i), y + b * Math.sin(i));
}
context.closePath();
context.stroke();
};
均匀压缩法
这种方法利用了数学中的均匀压缩原理将圆进行均匀压缩为椭圆,理论上为能够得到标准的椭圆.下面的代码会出现线宽不一致的问题,解决办法看5楼simonleung的评论。
//------------均匀压缩法绘制椭圆--------------------
//其方法是用arc方法绘制圆,结合scale进行
//横轴或纵轴方向缩放(均匀压缩)
//这种方法绘制的椭圆的边离长轴端越近越粗,长轴端点的线宽是正常值
//边离短轴越近、椭圆越扁越细,甚至产生间断,这是scale导致的结果
//这种缺点某些时候是优点,比如在表现环的立体效果(行星光环)时
//对于参数a或b为0的情况,这种方法不适用
function EvenCompEllipse(context, x, y, a, b)
{
context.save();
//选择a、b中的较大者作为arc方法的半径参数
var r = (a > b) ? a : b;
var ratioX = a / r; //横轴缩放比率
var ratioY = b / r; //纵轴缩放比率
context.scale(ratioX, ratioY); //进行缩放(均匀压缩)
context.beginPath();
//从椭圆的左端点开始逆时针绘制
context.moveTo((x + a) / ratioX, y / ratioY);
context.arc(x / ratioX, y / ratioY, r, 0, 2 * Math.PI);
context.closePath();
context.stroke();
context.restore();
};
三次贝塞尔曲线法一
三次贝塞尔曲线绘制椭圆在实际绘制时是一种近似,在理论上也是一种近似。 但因为其效率较高,在计算机矢量图形学中,常用于绘制椭圆,但是具体的理论我不是很清楚。 近似程度在于两个控制点位置的选取。这种方法的控制点位置是我自己试验得出,精度还可以.
//---------使用三次贝塞尔曲线模拟椭圆1---------------------
//此方法也会产生当lineWidth较宽,椭圆较扁时,
//长轴端较尖锐,不平滑的现象
function BezierEllipse1(context, x, y, a, b)
{
//关键是bezierCurveTo中两个控制点的设置
//0.5和0.6是两个关键系数(在本函数中为试验而得)
var ox = 0.5 * a,
oy = 0.6 * b;
context.save();
context.translate(x, y);
context.beginPath();
//从椭圆纵轴下端开始逆时针方向绘制
context.moveTo(0, b);
context.bezierCurveTo(ox, b, a, oy, a, 0);
context.bezierCurveTo(a, -oy, ox, -b, 0, -b);
context.bezierCurveTo(-ox, -b, -a, -oy, -a, 0);
context.bezierCurveTo(-a, oy, -ox, b, 0, b);
context.closePath();
context.stroke();
context.restore();
};
三次贝塞尔曲线法二
这种方法是从StackOverFlow中一个帖子的回复中改变而来,精度较高,也是通常用来绘制椭圆的方法.
//---------使用三次贝塞尔曲线模拟椭圆2---------------------
//此方法也会产生当lineWidth较宽,椭圆较扁时
//,长轴端较尖锐,不平滑的现象
//这种方法比前一个贝塞尔方法精确度高,但效率稍差
function BezierEllipse2(ctx, x, y, a, b)
{
var k = .5522848,
ox = a * k, // 水平控制点偏移量
oy = b * k; // 垂直控制点偏移量
ctx.beginPath();
//从椭圆的左端点开始顺时针绘制四条三次贝塞尔曲线
ctx.moveTo(x - a, y);
ctx.bezierCurveTo(x - a, y - oy, x - ox, y - b, x, y - b);
ctx.bezierCurveTo(x + ox, y - b, x + a, y - oy, x + a, y);
ctx.bezierCurveTo(x + a, y + oy, x + ox, y + b, x, y + b);
ctx.bezierCurveTo(x - ox, y + b, x - a, y + oy, x - a, y);
ctx.closePath();
ctx.stroke();
};
光栅法
这种方法可以根据Canvas能够操作像素的特点,利用图形学中的基本算法来绘制椭圆。 例如中点画椭圆算法等。
其中一个例子是园友“豆豆狗”的一篇博文“HTML5 Canvas 提高班(一) —— 光栅图形学(1)中点画圆算法”。这种方法由于比较“原始”,灵活性大,效率高,精度高,但要想实现一个有使用价值的绘制椭圆的函数,比较复杂。比如,要当线宽改变时,算法就复杂一些。虽然是画圆的算法,但画椭圆的算法与之类似,可以参考下。
总结
基本上所有的方法都不可能达到100%精确,因为受显示器分辨率的限制。
其实最好的方法应该是arc()+scale()。canvas绘图库KineticJS就是用的这种方法。
在其他绘图软件中,不像HTML5的canvas那样提供固有的arc()+scale()方法,通常用贝塞尔曲线模拟近似椭圆,无论是几条贝塞尔曲线都是近似而已。关于用贝塞尔曲线模拟椭圆,可以参考这份资料:Drawing an elliptical arc using polylines, quadratic or cubic Bezier curves。
由于arc()+scale()是浏览器已经实现的方法,理论上精度最高,所以从效率、精确度和简单易用程度上来讲,都是最佳的。
在用arc()+scale()绘制完椭圆后,context.stroke()和 context.restore()两个方法调用的先后顺序不同,产生的结果会很有意思的。通常应该先restore()再stroke()。
Demo
下面是除光栅法之外,几个绘制椭圆函数的演示,演示代码如下:
<div id="CanvasWrap" style=" background:#fff; width: 600px; height: 600px; border: 1px solid black;"></div>
<script type="text/javascript">// <![CDATA[
var canvas,
context;
var div = document.getElementById("CanvasWrap");
div.innerHTML = "";
canvas = document.createElement("canvas");
canvas.style.width = "600px"
canvas.style.height = "600px"
canvas.width = 600;
canvas.height = 600;
context = canvas.getContext("2d");
div.appendChild(canvas);
function execDraw()
{
//解决Chrome下的线宽小于等于1的问题
context.lineWidth = 1.1;
context.strokeStyle="black"
ParamEllipse(context, 130, 80, 50, 50); //圆
ParamEllipse(context, 130, 80, 100, 20); //椭圆
EvenCompEllipse(context, 130, 200, 50, 50); //圆
EvenCompEllipse(context, 130, 200, 100, 20); //椭圆
BezierEllipse1(context, 470, 80, 50, 50); //圆
BezierEllipse1(context, 470, 80, 100, 20); //椭圆
BezierEllipse2(context, 470, 200, 50, 50); //圆
BezierEllipse2(context, 470, 200, 100, 20); //椭圆
//检测相似性(重合的程度)
ParamEllipse(context, 300, 450, 250, 50);
context.strokeStyle = "yellow";
BezierEllipse1(context, 300, 450, 250, 50);
context.strokeStyle = "blue";
BezierEllipse2(context, 300, 450, 250, 50);
};
function clearCavnas()
{
context.clearRect(0, 0, 600, 600);
};
// ]]></script>
<p>
<br />
<button onclick="execDraw();" type="button">执行</button>
<button onclick="clearCanvas();" type="button">清理</button>
</p>
注意,要成功运行代码,需要支持HTML5的Canvas的浏览器。
本文转载至:http://www.cnblogs.com/shn11160/archive/2012/08/27/2658057.html
客户端跳转与服务器端跳转的区别
客户端跳转时用HttPservletResopse对象的sendRedirect函数实现,服务器端跳转是使用RequestDispather对象的forward方法实现的。这两者之间的区别主要体现在三个方面:
1. 使用服务器端跳转时,客户浏览器的地址栏并不会显示目标地址的URL,而是用客户端跳转时,地址栏当中会显示目标资源的URL;
2. 服务器端跳转是由客户端发送一个请求,请求一个服务器资源——如JSP和Servlet——,这个资源又将请求转到另一个服务器资源,然后再给客户端发送一个响应,也就是说服务器端跳转是客户端发送一次请求,服务器端给出一次响应;
客户端跳转的流程则不同。客户端同样是发送一个请求给服务器端资源,这个服务器资源会首先给客户端一个响应,客户端再根据这个响应当中所包含的地址,再次向服务器端发送一个请求,也就是说客户端跳转是两次请求,两次响应;
3. 在进行客户端跳转和服务器端跳转时,都需要指定目标资源的URL,如果这个路径以“/”开始。在客户端跳转当中“/”代表的是应用服务器根目录,而在服务器端跳转当中代表的是应用程序根目录。
page = 页面级别
request = 请求级别(与服务器端跳转配合使用)
session = 会话级别(客户端跳转(服务器端跳转也可,但是客户端跳转更加突出了session的作用范围))
application = 应用级别
客户端跳转:服务器端将请求结果返回给客户端,客户端向服务器发出另一次请求。在客户端跳转过程中是两次不同的请求。在地址栏中显示的是最后一次请求地址。
客户端跳转可以进行站外跳转。
1、链接跳转:<a href=””></a>
2、表单提交
3、Response.sendRedirect(“3.jsp”);
4、<mata http-equiv=”refresh”, content=”3;2.jsp”/>
5、response.setHeader(“refresh”,” 3;2.jsp”);
6、客户端跳转“/”代表服务器跟路径(localhost:8080)
7、客户端跳转“.”代表当前工程项目根路径(http://localhost:8080/addressbook)
服务器端跳转(容器内跳转):能够自动的在服务器内部进行跳转,这种跳转对用户来说是透明的。两次跳转时同一个request,在地址栏中显示的事第一次页面地址。
只能进行站点内跳转。
1、<jsp:forward page=””/> --写在jsp页面内的跳转
2、pageContext.forward(); --写在jsp页面内的跳转
3、 request.getRequestDispatcher("1.jsp").forward(request,response);
4、 服务器端跳转“/”代表当前请求根路径(http://localhost:8080/addressbooktest/GoServlet)
5、 服务器端跳转“.”代表当前请求根路径(http://localhost:8080/addressbooktest/GoServlet)
JAVA_OPTS="-Xms1024m -Xmx1024m -Xmn512m -Xss256K -XX:PermSize=120M -XX:NewSize=512m -XX:MaxNewSize=512m -XX:MaxPermSize=120m -XX:ParallelGCThreads=15 -XX:MaxTenuringThreshold=5 -XX:ParallelCMSThreads=15 -XX:+UseConcMarkSweepGC -XX:+UseCMSCom
包含分页的JDBC工具类
package com.shxt.tool;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
/**
* @Author:何云龙
* @Version:JDBC封装1.1 2012-11-29 下午06:38:55
* @Description:jdbc的封装
*/
public class DBUtil {
private String url = "jdbc:mysql://localhost:3306/sduentdb";
private String userName = "root";
private String passWord = "root";
private Connection conn = null;
private Statement st = null;
private PreparedStatement ps = null;
private ResultSet rs=null;
// 加载驱动,只加载一次即可
static {
try {
// System.out.println("加载驱动正在进行");
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("加载驱动遇到异常");
e.printStackTrace();
}
}
public Connection getConnection() {
// 创建连接
try {
conn = DriverManager.getConnection(url, userName, passWord);
return conn;
} catch (SQLException e) {
System.out.println("创建连接出现异常!!");
e.printStackTrace();
}
return null;
}
public int update(String sql) {
// row是指受影响的行数
int row = -1;
try {
// 当前连接如果是空或者被关闭,需要重新创建一个连接
if (conn == null || conn.isClosed()) {
conn = getConnection();
}
st = conn.createStatement();
row = st.executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
}finally{
//关闭资源
release();
}
return row;
}
public int update(String sql, Object[] obj) {
int row = -1;
// 当前连接如果是空或者被关闭,需要重新创建一个连接
try {
if (conn == null || conn.isClosed()) {
conn = getConnection();
}
ps = conn.prepareStatement(sql);
// 参数结构数据对象
ParameterMetaData pmd = ps.getParameterMetaData();
int varCount = pmd.getParameterCount();
// 给sql语句中的问号?附上值
for (int i = 0; i < varCount; i++) {
ps.setObject(i + 1, obj[i]);
}
row = ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally{
//关闭资源
release();
}
return row;
}
public ArrayList<Map<String, Object>> queryToList(String sql) {
ArrayList<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
// 当前连接如果是空或者被关闭,需要重新创建一个连接
try {
if (conn == null || conn.isClosed()) {
conn = getConnection();
}
st = conn.createStatement();
rs = st.executeQuery(sql);
ResultSetMetaData rsmd = rs.getMetaData();
int col = rsmd.getColumnCount();
while (rs.next()) {
Map<String, Object> map = new HashMap<String, Object>();
for (int i = 1; i <= col; i++) {
map.put(rsmd.getColumnName(i),
rs.getObject(rsmd.getColumnName(i)));
}
list.add(map);
}
// System.out.println(list);
return list;
} catch (Exception e) {
e.printStackTrace();
}finally{
//关闭资源
release();
}
return null;
}
public ArrayList<Map<String, Object>> queryToList(String sql,String[] str) {
ArrayList<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
// 当前连接如果是空或者被关闭,需要重新创建一个连接
try {
if (conn == null || conn.isClosed()) {
conn = getConnection();
}
ps = conn.prepareStatement(sql);
// 参数结构数据对象
ParameterMetaData pmd = ps.getParameterMetaData();
int varCount = pmd.getParameterCount();
// 给sql语句中的问号?附上值
for (int i = 0; i < varCount; i++) {
ps.setString(i + 1, str[i]);
}
rs = ps.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
int col = rsmd.getColumnCount();
while (rs.next()) {
Map<String, Object> map = new HashMap<String, Object>();
for (int i = 1; i <= col; i++) {
map.put(rsmd.getColumnName(i),
rs.getObject(rsmd.getColumnName(i)));
}
list.add(map);
}
return list;
} catch (Exception e) {
e.printStackTrace();
}finally{
//关闭资源
release();
}
return null;
}
private int pageSize;//页容量
private int rowsCount;//总记录数
private int start;//开始位置
private int end;//结束位置
private int pageNow;//当前页
public static int pageCount;//总页数
public ArrayList<Map<String, Object>> getPage(int pageSize,int pageNow,String sql){
rowsCount=queryToList(sql).size();//获取到总记录数
pageCount=rowsCount%pageSize==0?rowsCount/pageSize:(rowsCount/pageSize+1);//获取到总页数
start=pageNow*pageSize-pageSize;//开始位置
String sqlPage="select * from ("+sql+") as t limit "+start+" , "+pageSize;
ArrayList<Map<String, Object>> list=queryToList(sqlPage);
return list;
}
//关闭资源 释放资源
public void release(){
try {
if(rs!=null){
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(st!=null){
st.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(ps!=null){
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(conn!=null){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
怎么样在30岁前年薪超过50万(转载自网易斩建通)
靳建通有不少朋友发邮件给我,向我请教如何学习.NET,又或者是想拜我为师,长期进行交流学习。很遗憾,由于时间有限,这些邮件我都没有回复。但我确实想帮一帮这些朋友们,所以我觉得还是写一篇文章,将我这些年的经历像讲故事一样告诉大家。如果大家能有所启发,又或者有所进步,那我也算是聊以慰藉、得偿所愿了。靳建通
我是1982年12月8日出生的,靳建通到今年整整30岁了。古人说“三十而立”,我想不论从思想上还是财富上,我应该都算是勉强达到了吧。这篇文章的标题是“如何在30岁前年薪超过30万”,其实只是一个噱头罢了,尽管我确实达到了这么多靳建通,但这不是我所在意的,这篇文章主要是谈谈我的一些历程而已。
小学、初中(1989~1998)
我从小就很贪玩,虽也称不上孩子王,但只要涉及娱乐项目(街机、丢沙包、踢毽子、拍洋片、跳大绳),从来不会少了我的身影。在这个阶段,靳建通我最感谢的是我的父亲和班主任,他们对我管教的非常严,挨打、下跪是常有的事,所以学习成绩还算保持的不错。小学毕业时候,年级第2名(共4个班,每个班30多个学生),初中毕业时年级第62名(共11个班,每个班45个学生)。
高中(1998~2001)
我的初中和高中是同一所学校,陕西省西安市黄河中学,在当地算不错的学校,也就是大人们常念叨的省重点。上了高中以后,我的个头已经超过了父亲,他也不再像从前那样管教我;而由于班上学生很多,又有一些刺头,老师也就顾不上关注我了。但我的贪玩却是一如既往,可能好多人大学时候才接触电脑,可我高一时候就开始去电脑厅通宵上夜机了(借口是:去某某家学习)。靳建通那时可不是编什么程序,而是打游戏。就这样,到了高一下学期期末,我在班里排40多名(共50多人),年级150名靠后(共4个班,220多人)。
上了高二以后,我算是有所反省,收敛了一些,在读书上多花了点心思。靳建通到了高三临近高考前,我的成绩保持在年级30名左右。按照往年的水平,这个名次刚刚够进西安交通大学。于是,我就报考了这所大学。可能是老天对我的惩罚吧,事后老师告诉我们,我们这一届是黄河中学近10年来最烂的一届,所以进入西安交通大学的名次也提升到了年级前20名。于是,我滑到了一所二流学校――西安理工大学。
大学(2001~2005)
至少在那个时候,我还没有那么高的觉悟,不知道珍惜时间。再加上高中阶段的压抑得以释放,所以大学四年基本上是放羊式的。一般来说,一门课程我只上两堂课,第一堂和最后一堂。上第一堂纯粹是给老师面子,上最后一堂则是想看看会不会透露一些必考点。省出的时间基本上泡在网吧,又或者是追求某个MM了。于是,大学的挂科几乎是接连不断,到了大四下学期还有巨恶心无比的、靳建通从大一补考到大四的《工科化学》没过。不过,好在最后一次清考过了,顺利拿到了毕业证和学位证。
大学实在是没什么可圈可点之处,我想大多数人可能和我一样也就这么过来了。让我感到欣慰和庆幸的是:大学期间我考了驾照,过了四六级,而且六级考了82分。
后大学时代(2005下半年)
大学毕业以后,平时比较努力的同学都找到了工作,好一些的进了华为、中兴、靳建通大唐电信等比较有名的公司。像我这样的,简历投出去都是没音讯的,所以我自然想到了很多人都想到的一招――考研。可我的考研完全是一个笑话:我和一个初高中一起玩大的哥们儿在网吧旁边的城中村租了一个房间,结结实实打了半年的网游。
我的学生时代就这样结束了,说了上面这么多,其实想说的意思就一个:我和很多人一样不肖,甚至更差。但这些都不要紧,只要从现在开始努力,你的人生一样可以开始转变。靳建通
西安上半期(2006~2007年中)
我想在大学时代干的还算不错的一件事就是考过了六级,托它的福,我找到了第一份工作。这家公司是做国际旅游的,面向的是海外的顾客,所有的网站和系统都是英文的。我想可能是之前受过找不到工作的打击,所以这份工作我很努力。公司是早上8点30上班,我每天7点30之前就到公司开始工作了,并且坚持了一年。这段时间我才开始学习Asp、JavaScript、CSS,那个时候还没有接触到太多的.NET。尽管不多,但付出还是有回报的,这一年我的工资上涨了4次,从最初的1800,涨到了2600。
促使我离开这家公司的原因是:我想学习并应用.NET,因为我比较看好它。可这家公司的所有系统都是用ASP做的,并且没有升级到.NET的打算。于是,我递交了辞呈。这时,我的薪水是3000块。靳建通
西安下半期(2007年中~2008年中)
离开之后的一个月,我辗转了两家公司,一家是工资太低,只肯出1800;一家是工作环境太差,办公室简直就是一个仓库。于是,我又回到了上一家公司。我的部门经理也还算开明,给我了一个新的项目,并允许我用.NET开发。这个时期是我最困惑和低迷的时候,因为我找不到出路,我不知道该怎样才能突围出去,不知道该怎样才能获得提升和进步,不知道该怎样才能让自己的收入更体面一些。幸运的是,我找到了方法。
这个方法很简单,和电影《阿甘正传》里阿甘的做法是一样的,核心就四个字:专注、执着。既然我决定要用.NET,就把.NET钻研到至精至强。
实际上,我发现越是真理,就越是趋于简单,关键是,你愿不愿,你能不能这样去做。所以,当一个人找不到出路的时候,最好的办法就是将当前能做好的事情做到极致,做到无人能及。靳建通
想通了这个道理以后,我每天6点30起床,每晚1点钟睡觉,周六周日无休,只要有时间就研究.NET,浏览国内外的技术站点,写范例程序。也是在这段时间,我加入了博客园,写了不少的博文,其实都是我研究和学习的心得。
到了2008年7月,我仍然觉得这家公司不适合我继续待下去,原因很简单:这家公司的老板不值得追随,赚了钱全是他的,下面的人只要还不至于你离职,能给你开多低的工资,就给你多低的工资。
离开时,我的月薪是3500。
闭关修炼期(2008年下半年)
由于一年多的时间都浸淫在.NET的世界里,还没有从这种状态里跳出来,靳建通既然现在辞职了,不如借此机会,继续深入一下.NET。于是这半年我都待在家里学习.NET。
大学临近毕业的时候,对于我们计算机专业的学生来说,比较流行“计算机软件技术水平考试”。分为了程序员、软件设计师、系统分析师三个等级,在我印象里,全系100多人,只有十几个考过了软件设计师,而考过的这些人,多半进了华为中兴。
可能是为了证明自己不比别人差,而现在又正好有时间,不如捎带着也考一个软件设计师。于是,这段时间除了.NET以外,我又把大学时候丢下的课本拿起来复习了一遍。
四个月后,已在深圳的我收到消息,我已经通过了这门考试。
离开西安(2008年12月底)
选择去深圳是偶然也是必然。在家里闭关修炼那些天,有一天我心血来潮,查了一个热门词汇:GDP,我当时还不知道这玩意儿干嘛的,所以就想了解一下。查过之后,通俗地讲,我知道它代表了一个地区或者国家的富裕程度。然后我又查询了一下国内省会城市的GDP排名,想看看从小长大的西安排名第几。结果大出所料,西安属于垫底的,好像是二十五往后去了(总共才排了30多个城市)。
于是,我就强烈地想感受一下排名前几位的城市是什么样的,这时我还是孤家寡人一个,此时不闯荡更待何时。可还有一个问题:北京、上海、广州、深圳,去哪个?经过一番思考,我决定去深圳。因为:
北京:冷,我虽然是北方人,但我怕冷;北京空气污染很严重;北京交通成本很高。
上海:地区歧视;交通成本也很高。
广州:都讲粤语,不好融入。
深圳:移民城市,大家都是外地的,自由平等;温暖,海滨城市。
12月23日,我乘上了飞往深圳的班机。
深圳(2009~2011年上半年)
在深圳的三年我都在一家公司,并且以后很长一段时间都会继续待下去。之所以将深圳的经历分成两段来写,是因为我在这两段的表现完全是两个人。
深圳的工作是朋友介绍的,到深圳的头一个星期我就获得了这份工作。加入这家公司的时候,公司刚刚成立一年,连我算上也只有9个人。问及我想要多少薪水的时候,我当时认为我在.NET领域已经算不错了,所以我报了税后8000块。老板很慷慨,欣然答应了,税前8600。
我到这家公司的时候,技术部已经有一位员工了,可能因为他的表现不好,所以老板让我做了部门经理,当了他的上司。三个月后,我又招聘了一名同事,这样技术部就有3个人了。
之后整整两年多的时间里,我一直掉到了一个死胡同里出不来,因为我还和之前一样,持有技术为王的思想。实际上这个时候我的角色已经变了,我不再是一个人,我有了下属,我需要和他们做沟通,我需要带领他们。但这个时候我完全没有这方面的想法,我只想着只要我技术够强,只要我可以把我负责的那部分工作做好,我到哪里都能吃得开。我完全是个人英雄的想法,没有团队协作的概念。
可是我错了。到了2011年的时候,我后来招的那位同事已经完全丧失了工作的积极性,士气低落到每天上班就是混日子,有时候甚至打开优酷看电影。直到最后,老板把他开掉了。而比我来得更早的那位同事,更是不待见我,最后干脆辞职走掉了。这时,我成了名副其实的光杆司令。
他们两个人离开以后,工作的担子全压了过来,我一个人支撑了三个人的工作量,并且坚持了三个月,直到我后来又招了两位同事。
这三个月里,我除了天天加班做事以外,还不断反省我究竟错在了哪里。直到后来,我终于想明白了。这里,我想先讲一个故事:楚汉争霸的时候,刘邦阵营里有一个将领,大家都听过的,叫做韩信。每次打完仗,刘邦就把那些降兵、老兵、残兵、弱兵丢给韩信,自己带领精兵。而这些最没有战斗力的士兵,到了韩信手里,不出两年就全部成了精兵。结果刘邦两次跟项羽打了败仗后都去向韩信借兵,有一次,甚至是半夜里溜进韩信的帐营,窃取了韩信的兵权。
这才是真正的将领,这才是真正有本事的领导。领导的能力不在于自己能做多少事,自己能把事情做得有多好,一个人的能力再强,能干两个人的活,能干三个人的活,但是能抵得过十个人吗?领导的能力在于能多大程度地发挥下属的潜能,如何能让下属做得更出色,如何能让所有人戮力同心朝一个方向前进。
想明白了这些事情后,我突然感到很悲伤,我觉得愧对之前的两位同事。他们本来是可以做得很好的,是因为我这个领导不好,所以才导致了最后这样的结局。从这个时候起,我也给自己设定了一个规则:如果有哪个下属表现不好,我不会怪罪他,我知道这一定是我的责任,一定是我没有训练好他,一定是一些该说的话没有说。我要做像韩信那样的领导,即便是60分的人到了我这里,我也会将他变成80分的人。一个人的强大不是真的强大,整个部门强大、整个公司强大才是真正的强大。
这个时候,我的收入是年薪20万。
深圳(2011年~现在)
上面可以说是一个转折点,从那以后,我将自己的工作主要内容定义为:帮助部门同事将工作做得更好、帮助部门同事解决棘手的问题、帮助部门同事获得技术和思想上的提高。我不再独孤求败式的追求自我的进步,我追求的是部门下属的进步。我也不再关心我自己年薪多少,我更期盼是我的下属有朝一日也一样年薪二三十万。
他们两个离开后,我陆续又招聘了4位新的下属。而这段期间,我的思想也逐渐变得成熟,关于工作态度和职场上如何做事,我写下了《职场上做人做事做管理》。这篇文章也发表了在我的博客上。
我还将这些年积累的经验进行了汇总,编写了技术部的员工培训手册,组织会议向他们讲解。帮助他们在思想上有更高的认识,帮助他们规划人生的发展方向。在这里,我也很乐意向大家分享这两个培训手册,这两个手册的内容远比这篇文章更为深入,可以从下面的链接下载,希望能给大家带来帮助。
点击下载(或者“目标另存为…”):《技术部员工培训1》
点击下载(或者“目标另存为…”):《技术部员工培训2》
当我做了这些事以后,现在的结果和之前完全形成了鲜明的对比。尽管4个新同事最短的来了还不到两个月,但整个技术部团结的就像一个人,做事效率更是奇高无比,也超越了公司的其他两个部门。我可以很自豪地说,我们5个人,完全抵得上大多数公司的七八个人。
当然,我所做的这一切,公司所有其他人都看在眼里,老板更是连涨我的薪水。我知道他们不是敬畏我,而是敬畏我们整个部门。
现在,我的收入是年薪32万。
展望未来
公司目前每年的增长速度是40%,这个速度是很多公司望尘莫及的。我自己的收入也是水涨船高。其实算算看,在西安的三年,由1800到3500,翻了一番;在深圳的三年,由年薪10万到年薪30万,翻了一番多。可以预见,未来三到五年,年薪50万、甚至100万都是有可能的。当达到这样的收入以后,实际上经济上已经自由了,除了私人飞机、私人游艇以外,物质上的需求大多都能实现。那个时候,工作和生活的意义又在哪里? 我想,许多已经达到这种程度的人应该都已经想明白了,那就是成就一番事业。
所以,我想,我以后的责任,就是将现在的这家公司打造成一流的公司。同时,我要让我的下属有朝一日能够以加入这家公司为荣,以成为技术部的一员为荣。
谢谢大家,希望这篇文章能给你带来帮助!
http://service.bbs.163.com/bbs2009/article.jsp?boardid=tyro&articleid=290319973&userid=2nbMt
网易上斩建通文章分享下
我想博客园里大多数的程序员都和我一样,二十多岁的样子,谁都不愿意默默无闻终此一生,那么我们最关心的话题自然是成功、何谓成功、以及如何才能够成功。可能因为自己逐渐长大,慢慢得对于一些事情有了自己的看法,而近期我对脑子里原本模糊不清的思绪进行了些许整理,写下了这些文字。虽然我还不能称为一名成功人士,靳建通但我还是想谈谈自己对成功的看法,希望能和大家做点交流。
何谓成功
成功的相对性
在开始之前,靳建通我们先讨论下什么才能称得上算是成功?这个定义似乎从来就没有统一过:拜金主义者认为有钱、富甲一方就是成功;靳建通官僚主义者认为有势、权倾朝野就是成功;功利主义者认为有名、海内皆知就是成功;浪漫主义者认为有情、靳建通金屋藏娇就是成功;而更多的人,认为能够平平安安过一生就是成功。由于每个人的世界观不同,对于成功就会有着截然不同的看法。所以,你眼里的成功人士,可能并不觉得自己成功。比如说一个立志成为音乐家的人,由于种种原因,成为了一名闻名于世的画家,在所有人的眼里,他都是成功的,只有他本人会觉得很失败,靳建通他会想自己本应是一个闻名遐迩、才华横溢的音乐家才对啊。从这个角度来看,成功几乎总是相对的。
成功的绝对性
但是,成功也有绝对的一面。不管你是拜金主义也好靳建通、官僚主义也好、浪漫主义也好,当你成功的时候,总是你的目标实现的时候。所以,当你为自己设定的目标实现了,就可以说自己是成功的。而因为每个人的目标都不一样,所以你几乎永远不需要和别人攀比,衡量自己是否成功不是有没有达到别人的标准,而是自己订立的目标有没有实现。而我们一生最大的目标,实际就是我们常常谈论的理想。在我刚上高中的时候,学校聘请了一个人为全校师生进行演讲,演讲的话题是励志,靳建通目的是为了激励我们更加用功地学习。这个人的名字以及演讲的内容我已经完全不记得了,靳建通但我记住了一句话,他告诉我们什么叫幸福,他说“理想的实现是人生最大的幸福”。实际上,靳建通他的意思和我这里是一样的,远大的目标即为理想,理想的实现便可称为成功,成功了自然会幸福。
如何成功
在学校的时候,我不时会看到清晨在操场上怒吼“我要成功!”的人;在书店里一买就是三五本“成功学著作”的人;以及将“吃得苦中苦,方为人上人”这样的字句贴在墙上的人。我从来就不看成功学方面的书籍,我认为成功并不是太复杂的事情,成功的方法其实很简单,只要能掌握下面三点就足够了,问题的关键是:必须贯彻到底。靳建通
坚持
这里的坚持不仅仅只是坚持的本意,还包括两点:执着、专注。我有一个朋友,人很瘦,1.75M 的身高,却只有 112 斤重,见面得时候我常开他玩笑,说他找个女朋友都让人家没有安全感。有一天,他对我说“我决定开始健身,让自己变得壮一点”。三个月后我再见他,体重已经有130斤,身材也变得魁梧了许多,尤其是两块胸肌格外的明显。我惊讶他的变化,问他究竟是怎么练的,他告诉我:靳建通“没有什么诀窍,只有三点:1、我隔一天去一次,但是从不间断,如果某天有事,那么就连着去两天把上次的补回来;2、我只专注于练上半身的四个器械,其他器械碰都不碰;3、每个器械做2组,每组15个靳建通,不管再累,只多不少。”。坚持的要求就是决定做一件事情,就一往无前地做下去,决不动摇。
顽强
顽强也就是受挫能力和抗打击性,有的人是越挫越勇,有的人则会在几次挫折之后一蹶不振。对于一些人来说,顽强和坚持从某种意义上来说是一体的。很多人之所以没能坚持下去,就是因为不够顽强,或者说是经受不了挫折。我有一位同学,人很聪明,但是也很贪玩,大学毕业后找了家还算不错的私人企业做Web开发(Asp)。一年以后觉得公司没有太大的发展前景,就离职了,先是去华为面试,由于大学时期的功底不扎实,C++又长期没有接触,所以面试是大败而归。之后又找了家普普通通的私企开始做Asp.Net,一年以后,又觉得没什么前途,再次离职。然后又去了西安葡萄城应聘.Net开发,因为只有一年的.Net经验,再加上算法功底欠缺,面试再次失败。前段时间我跟他通电话,问他有什么打算,他说“我已经知道了我哪里不足,我决定停下半年不找工作,恶补数据结构、算法,年底考软件工程师。另外对.Net进行深入地学习”。我没有多说什么,但是心里明白,这样的人,成功是迟早的事情。靳建通
自律
自律应该是最难得的一个品质。自律的意思是说:当你为自己规定了一份计划,你会不会因为别的事情而改变。当你决定明早7点40起床读书的时候,会不会一觉睡到自然醒?当你在做程序的时候,会不会忽然想看看网易有什么新闻,或者是论坛有没有什么新帖?当你决定下午洗完衣服去锻炼身体的时候,会不会放不下手头的游戏放弃了最初的打算?我有个同事,他有个嗜好,就是“下电影”,为什么说“下电影”而不是“看电影”呢?因为他下电影的时间远远多于看电影的时间,当然不是因为网速慢,而是只要有新电影他就克制不住地想要下载下来,然后快进着看看好不好看,如果不好看就立马删掉。靳建通结果是真正认认真真看完的电影没有几部,时间全耗在了浏览电影网站和快进式的浏览电影上。有一天他终于觉得这样做把时间都浪费掉了,他决定不再下电影,但是采用的方法却很奇特:拔网线。如果有足够的自律,用不着这么做(他也意识到自己的自律不够,所以采用了强制手段)。靳建通自律的要求就是对自己定制的计划能够贯彻落实下去,不因诱惑和干扰而改变。
当你能够做到 坚持和顽强 的时候,会发现 自律 是最难做到的。有这样一个真实的故事:是说一个人对于自然界有着天生的兴趣,最后成为了一名博物学家,当人们称赞他是一位科学家的时候,他说:“不,我只能算是一名学者,还称不上是科学家”。人们很奇怪,问他为什么会这么认为。他回答“科学家身上有一个我不具备的品质,就是自律”。
http://service.bbs.163.com/bbs/tyro/290322105.html
网易上斩建通写的很好的文章分享下
大道至简,越是根源和基本的问题,道理实际上越简单。关于如何做人、做事、做管理的书很多,我看得不多,但是我觉得这些书更多是侧重技术和实现细节上的,而很少从人的思想和观念去讲。实际上,从根本上去说,如何做人做事是世界观的问题,也是一个哲学话题。很多人和我一样,已经到了快30的年纪,是需要去思考一下应该如何做人如何做事的,也需要一套简单、有效、完整的体系来指导自己,而这套体系将是让自己安身立命于这个世界的基石。靳建通
职场上如何做人
关于在职场上如何做人,靳建通我只谨记两个字--服务。你要把自己当成一个品牌去爱惜,当成一家公司去经营,你要牢牢记住你之所以能在一家公司立足,靳建通是因为公司需要你的服务。我们经常会抱怨某某银行的工作人员服务态度不好、某某商品的售后服务不好,但从来不去思考自己对公司的服务好不好?公司的任务有没有如期完成,是不是没有哪个任务是提前完成的,几乎所有任务都拖到“最后期限”?工作完成的够不够彻底,是不是答复已经完成了,结果日后又出状况?靳建通完成后有没有向上级反馈,是不是等到上级问你完成了没有,你才去报告进度?拖延的任务有没有持续跟进,是不是上级不追了这个任务最后就不了了之了?上面这些问题我都是反复遇见的,其实根本原因就是没有意识到你其实在做一项服务,你在公司的发展前景,全都取决你对公司的服务够不够好。设想一下,如果交给你的每件事情都可以迎刃而解、化险为夷,让人感觉稳妥、放心、踏实,你自然会收到更多更重要的“订单”。当你的单多到你忙不过来的时候怎么办?招下属啊,呵呵,恭喜你,你已经是领导了。反之,如果给你一件事情你要拖延,给你一件事情你办不好,给你一件事情就没了下文了,让人不放心,久而久之你就“无单可做”了,靳建通那么公司重新请一个人就可以了,干嘛非要用你呢?
服务不光是对于自己供职的公司,对于公司的客户也是一样的。每一次去客户那里出差前,我总是再三叮嘱自己,我此次之行是为客户做服务的,是去为客户解决问题的。这个心态非常重要,我们做软件系统的,去见客户除了做演示、做培训,很多时候就是处理现场问题,难免遇到客户对系统的投诉,比如系统速度慢、bug多等问题。当你有了这样的心态,你就会谦虚地接受客户的批评,细致地记录客户提出的问题,然后一项项地去思考如何解决,并且应该给客户一份详尽的解决方案。有了这样的心态,你会不自觉地、自然而然地与客户站在一边,让他感到你是在为他着想,帮助他去解决问题的。在你面对客户时,应该有这样一个虔诚的信念:我是去为客户服务的,为他解决他所解决不了的问题的。如果你没有这样的心态,面对投诉很可能就会产生厌烦,而且容易为自己的问题进行辩解。靳建通这种做法给客户的感觉就是你竭力在证明你是对的他是错的,这样你就站在客户的对面了。
在客户面前的表现对你的职场发展也是非常有好处的,靳建通尤其是接触到一些跨国企业时,你优良的职业素养会为你赢来客户的认同与尊敬。这样当你哪天希望寻找更高的平台,只要放个口风出去,立即就会有Offer了。所以认真服务好客户只赚不赔。
职场上如何做事
关于如何做事,也有很多的理论,比如要事第一,靳建通把事情分为紧急、重要等等,这些我都不讨论了,我只就我自己的经验来谈一谈。
对于如何做事,我也恪守一个信条:不焦不燥,把心沉下去,将注意力集中于要解决的问题上。
我看过这样一个故事,是说从前有一户人家,家里的菜园中有一块大石头,经常会有人不小心撞到;儿子就问:为什么不把他挖走呢?他的爸爸说:这个石头爷爷的时代就有了,就是因为它那么大,不好挖才一直在那里;又过了一代人,家里的一个媳妇实在受不了,就扛着锄头去挖了,她已经做好了心理准备要挖几天的时间,结果一天就挖完了... ...原来那个石头的中间是空的。
我们遇到的很多事情也是一样的,看似棘手、难以解决,实际上只要你认真地去分析、去思考,然后放手去做,往往并没有想象中的那么困难。你需要克服心中的顽石。我发现一些人遇到问题后,很轻易地就会说:这个我做不了,这个实现不了,这个我也没办法。其实就好像看到这块大石头一样,被它的“外表”吓住了,而放弃了应有的行动。
而且我发现了一个有趣的现象,不管多么困难的问题,只要你沉下心去思考如何解决,就好像在冥冥之中上苍在看着你一样,当你拼到最后就要打算认输的时候,往往会出现新的契机和方法。
另外,我发现有些人遇到问题的时候,他想的是这件事如何困难如何难以完成,这样的思维方式是有问题的,是一种保守且退缩的思维;遇到问题的时候,想的应该是如何才能够完成。我一般采取这样几个步骤:1、列出所有的可能性;2、分析各种可能性;3、选择一种实现起来最简单、快速的可能性;4、去实现。
除此以外,我发现一些人在做事的时候,会以“这样做很麻烦”来作为不采纳方案的理由,而不是“这样是否必要”或者“这样是否更好”来作为标准,实际上“麻烦”应该是排在“是否必要”、“是否更好”后面进行考虑的。如果一种实现方式,虽然麻烦,但是很有必要,且对客户来说更好,那么就算麻烦也要去做。但是程序员往往关心的是会不会很麻烦,是不是要修改很多地方,是不是给自己带来很多工作量... ...告诉你,你关心的这些不是最重要的。
职场上如何做管理
和上面一样,做管理也有很多的细节,我也都不谈了,因为这些都是一本书一本书的讲,而我觉得要简单、有效、好操作,所以我也只说三点。
我觉得做好一个技术经理,只要下面的三点就好了:
1、德行
德行其实就是品德,简单地讲就是要善良、诚恳。最重要的,你做事的出发点要是好的,对别人是没有坏心的。为什么说出发点一定要是好的呢?我们还是以服务客户的例子来说,在为客户解决问题的时候,如果我们的出发点是好的,是站在客户一边尽心尽力去为客户解决问题的,那么即便由于方法、能力、条件等各方面的原因,事情搞砸了或者没有做好,也很容易获得客户的理解和原谅。很可能的情形是,你就算做失败了也一样赢得客户;相反,如果你的出发点是“省麻烦”,“赶紧交差了事”,“完成任务”,如果事情做成了也就算了,一旦失败了,你看看客户会怎么样?告诉你,好的客户会批评你、投诉你,因为他对你还有期望;更多的客户是什么话也不说,直接换个供应商就是了,才懒得理你。记住永远不要把客户当成傻瓜,你是如何做事情的,客户是很容易感受得到的。所以,面对和服务客户没有那么多的技巧,你不需要有多好的口才和魅力,也用不着忽悠和夸大其词(我发现很多销售人员都是这样,你可以骗客户一次,但就没有第二次了),你只需要放下身段,兢兢业业地为客户着想,设身处地地解决他的问题就可以。对待下属也是一样的,你对他的奖励也好,惩罚也好,出发点一定要是好的。我对待下属遵循的原则就是:我是在帮助你,帮你把工作做的更好,帮你获得更大的提高,而不是说找你茬儿,跟你过意不去,或者是挤兑你压迫你。德行是基本的,有一个好的德行,至少可以保证你的下属不会讨厌你。
2、敬业
如果有人问我,下属和经理的区别是什么。我会告诉他:下属等着别人交代事情做,经理想着还有哪些事情可以做。这其实是一个积极心态的问题,作为一个中层干部,你需要将公司的事情当成自己家的事情来处理,当你有这样的心态,你就是再怎么加班都不会有怨言的,即便分文不取... (有谁见过给自己家装修叫苦不迭的?)如果你可以长期保持这样的状态,靳建通你的这种献身精神和敬业精神,会很轻易地感染你的下属和你的同事,你会感觉到在公司左右逢源,而且你也会更有话语权,大家会更重视你的意见,同事和下属也会对你报以更多的信任。当这种情况出现时,管理起下属还会困难吗?但需要注意的是,你的敬业精神不是说体现在无休止的加班上,工作异常繁忙、经常性加班其实是工作没有做好的表现之一,加班只应该出现在紧急情况发生的时候,而不应该是一种常态。
3、技术
如果有人问我,技术人员和其他人员最大的区别是什么。靳建通我会告诉他:技术人员个个自以为是,认为别人的技术都不如自己。呵呵,可能大家不爱听,但我观察到的现象就是这样的。很少有人愿意去读别人的代码,彼此都觉得写得好烂。所以,如果想赢得技术人员的钦佩,你需要有压倒性的技术能力。这个压倒性的优势,不是下属70分,你80分,而是下属70分,你要做到100分;下属100分,你要做到150分。所以,缺乏技术能力的人去管理技术人员往往是吃力不讨好的,可能下属表面上服从你,心里根本不当你一回事儿,这样管理起来就存在障碍了。当然,如果你的德行非常好,也非常敬业,技术就显得不那么重要了;而如果你已经满足了前面两条,同时技术也很精湛,那自然是锦上添花了。
http://service.bbs.163.com/bbs/tyro/290320999.html
看斩建通在网易上写的文章写的非常好,分享大家一下
http://service.bbs.163.com/bbs/tyro/290320402.html 婚礼
端午节,我最好的一个朋友,也就是常说的死党,结婚了。我从深圳专程飞回西安参加他的婚礼。虽然比不上开着跑车的富二代,但朋友家庭条件也算不错,婚礼举办得很隆重:
花车,宝马760Li;
迎亲车队,30辆黑色奥迪A6;当然,朋友自己的蒙迪欧今天就闲在车库里了。
婚房,高档社区,精装修,180平,四房两厅。事后这哥们还补了一句,这房子以后还得空着,我老婆家还有一套房,上班近点儿,住那边。
婚宴,顶级酒店,金碧辉煌,60余桌。乐队演奏,歌舞助兴。
当然,也少不了提及一下新娘了,新娘身材高挑,模样标致,最重要的是气质很好。在我看来,女人的气质比模样更重要,模样很快会变老,但气质会让你魅力依旧。
再说说这哥们儿的工作吧,国家电网,月薪5000块左右。不过这种单位,都是极其清闲而且福利大于收入的。据说,这工作也是他爹帮他搞定的。
看到没有?这就是爹的威力,仅凭我朋友自己的本事,是很难实现上面的哪怕一项的。所以,人们会说:这是一个拼爹的时代。(我们的父辈是不拼爹的,因为我们的爷爷辈都是没有最穷只有更穷的。之所以现在拼爹,是因为有一部分爹,属于小平同志说的先富起来的那一部分人)然而,有什么样的爹又是由上帝决定的,自己无从选择。于是,我们只能再自我安慰一下,有这样的差距,不是因为我技不如人,而是投错了胎。
婚宴
婚礼来了很多的同学,我们自然而然地凑到了一桌。多年未见,就有一句没一句地聊起了近况。其中,有一位同学,和我同在深圳,他从2005大学毕业后就去了华为,到现在已经7年了。
常听人说华为的工作很辛苦,现在好不容易有位华为的老员工和我们坐在一桌,自然免不了想要求证一下传说是不是真的。于是,在我们的询问下,他便开口跟我们大致描述了一下:假期很少,有几年的时间,都是大年三十才回到西安家里;工作强度高,几乎每天晚上都会工作到10点以后;压力很大,有N多的人挤着进华为,内部的人,做不好有会被淘汰的危险。
听他说完,我们又产生了新的好奇,那就是:这样拼命地工作,会有什么样的回报呢?
然后,他又含蓄地告诉我们:他两年前就买房了,年薪大概40多万吧。而刚毕业到那里的时候,也不过每月5000多而已。
思考
听完上面的两个故事,我想是时候思考一下了。
对于爹很猛的那一类,我们除了羡慕嫉妒恨,似乎也没什么好办法,总不能去重新认个爹吧?不如就由他去吧。
而我的另一位同学,也属于拼爹惨败,家境平庸的,我想大部分的人都是向他看齐的。但是,在现有的社会价值观下,经过了7年以后,他已经比同席的所有人情况都要好了。
可惜的是,我们不在华为,那我们要怎么样才能赶上或者超越呢?
契约精神
我想把话题先暂时绕的远一点,谈谈什么是契约精神。
我们的社会风气已经很堕落了,很多人将契约精神丢弃了,其实,大家耳熟能详的毒奶粉、地沟油、蛆火腿,统统是契约精神的丧失,他们做事的标准就是能不能赚到钱,而不是能否很好地履行契约。
我们和公司签订的劳动合同就是一份契约。在签订这份契约之前,公司和员工是可以讨价还价的。比如说,低于10K,我就不在这里工作。但是,一旦这份合同正式签订了,其实就代表了你认可了合同所规定的内容,那么接下来就要尽职尽责地履行这个契约。这个时候,你做事的动机,不能再是钱了,因为钱的问题在签合同时就已经解决了。这时候,你的动机应该是更好地完成契约。否则,就和做地沟油的没什么区别了。
你不能做的:
虽然公司开的工资少了点,但是好像也没找到更好的,就在这里混日子吧。
工作一年了,年底才加了那么点薪水,那今年我就混一混吧。
... ...
你可以做的:
在这里付出和回报不成比例,我还是辞职不干了。
经理压在上面,升迁希望不大,我还是辞职好了。
... ...
换言之,你可以选择不再继续履行契约,但是你不能敷衍它。这是一种精神,我希望有人能够明白这些。
当然,契约也是双向的,对于公司来说,也要具有这样的契约精神,要为员工提供有竞争力的薪资、福利,除此以外,还要保证每年都有适度的增长。
对于销售人员来说,和客户签订的合同也是一种契约,在签订之前,你可以和客户讨价还价,觉得客户难缠、觉得客户报价低,可以不做这个客户。
但是,一旦签订了合同,那么不管这个客户是小客户也好,大客户也罢,报价低也好,报价高也罢,都要尽心尽力地服务好这个客户。
你不能:这个客户报价低了,做个差不多就行了;那个客户报价高,我们服务再好点儿。
换言之,契约签订之后,你做事的动机就不能再是钱了,而是完好地履行这个契约。
我公司的客户里,有一家是美国陶氏化学。藉由这个客户,我认识了陶氏化学的一位年薪超过百万的高级职业经理人。跟他聊天的时候,他告诉我,他对公司没有太高的认同感,但是这并不妨碍他把工作做得出色。那个时候我并不明白他说这话的意思,不过现在我懂了。
而做毒奶粉的,显然丧失了这样的精神。虽然消费者没有和奶粉厂签合同,但这种买卖一样是一种契约。在我看来,对于奶粉厂来说,利润低我可以倒闭不做了,但是,如果我要做,那即便是不赚钱甚至亏本,也一定要把它做好。
拼命工作
我是不在乎能赚多少钱的,我一直觉得钱只要够花就行了,再多也没啥意思。但我作为一家之主,至少要让我的妻子和小孩有一个安居之所,这是我的责任。也就是说,我需要在深圳买一套房子。无奈的是,房价已经在云端了。迫不得已,我只能想办法多赚一点钱。我想很多人和我的情况都是差不多的,那么...How?
注意本节标题的用词,是拼命工作而不是努力工作或者认真工作。
这次回西安的时候,我从书架上取了一本书,以便在候机和乘机的时候打发一下时间。书名叫《More Joel on Software》,中文译名叫做《软件随想录-程序员部落酋长Joel谈软件》。
在这本书的第208页,作者说了这样一句话,我把它摘录在这里:“展望未来的几年,不管你的起步是多么地微不足道,只要你拼命地工作,每过12~18个月,你的收入就没有理由不翻一番(此处省略详细的数字计算过程――作者按)。”。
在原文中,作者指的是自己开一家软件公司。另外我觉得12-18个月放在美国说不定还行,放在中国或许有点夸张了,那么我们把它延长到24个月。然后把我那位华为同学的收入放进去算一下:
6万(5000/每月) x 2年(24个月) x 2年(24个月) x 2年(24个月) = 48万
虽然说不是完全准确,但也是相当接近了。
现在我们又回到了老问题,我们没在华为,那我们怎么办?其实答案已经有了:
1、你要将契约精神的概念融入到你的骨髓里。
2、你要拼命工作,就当自己是在华为一样。
我们来想象一下如果你做到了,会发生什么样的情况:
因为你拼命工作了,除非你特别蠢,不然你的工作成效一定明显高于其他人。
除非你的领导特别蠢,否则他一定会注意到你。
因为你的工作成效明显高于其他人,领导将会面临两个选择:优待你,给你更高的工资;偷着乐,但是什么也不做。
领导优待你,给你更高的工资,你的状况开始有所改善,当然不能见好就收,继续保持下去,这样就形成了一个良性循环。
领导无视你,你发现这家公司付出和回报不成比例,你可以不履行契约,换言之,你可以辞职(领导气量不大的公司大多数也是前途堪忧的,靳建通因为留不住优秀的人)。
更重要的,在你拼命工作的过程中,靳建通你的技术水平将会获得大幅的提高,可以能人所不能,这样你重新换工作的过程中,进入更好的公司概率也会更高一些。
那么拼到什么时候才是个头呢?如果一辈子都在拼搏却无暇享受拼搏的成果,靳建通那又有什么意义呢?我觉得,年轻时的拼搏是为了年老时的安逸。应当以35岁作为一个分水岭,靳建通当你努力奋斗到35岁的时候,顺利的话,已有了超过50万的年薪,并且房子、车子、婚姻等问题都已经解决了。这时候大可以放慢一下脚步,在周末约上几个旧时的好友,找个农家乐,钓钓鱼打打牌,享受一个悠闲的下午。
有人或许会问:拼到身体跨了无福消受又有什么意义呢?下面引用一位朋友的话来回答这个问题:
1,身体健康最重要,没有了健康的身体,你就什么都没有;
2,在身体健康能保持的情况下,应该全力去拼搏,靳建通否则你真的什么都没有。
有人或许会说:别人的成功只是运气比较好,而自己恰巧不走运罢了。我不否定机遇的重要性,但我否定过分相信机遇而放弃应有的努力,只去等待机遇来临。因此我宁可不相信运气,断了留给自己的这条后路,全心投入到奋斗当中。而且,我还发现一个有意思的现象,靳建通就是努力的人往往运气特别好。
当然...
有人会说,我的爹比你朋友的爹还强大。靳建通呵呵,这些话不是说给你们听的...
有人会说,我不想活得这么累。呵呵,这些话也不是说给你们听的...
我是说给那些现在还是屌丝,靳建通但希望儿子是高富帅的人听的
看到别人写的
对资产和幸福感的感悟 写的不错
随着阅历的加深,我关注的事物和接受的知识也在不断地发生着变化。大学毕业已经四年了,过去的半年中,我接触了一些看似不连贯的信息,因为觉得它们有用,就把这些信息全部记在了脑子中。直到最近,才发现一个片段正在解释和说明着另一个片段,而当我把这些片段信息串起来思考的时候,忽然有了一种开朗的感觉。我有一个习惯,就是当我感悟到一些东西的时候就把它写下来,因为在记录的过程中,我也会有一个更加系统和清晰的思路,靳建通于是也就有了这篇文章。
片段一:
这是有一次开会时,我的老总跟我们说了这样一个事例:通常来说,医生是很高尚的职业(暂不考虑国内医生的负面新闻),尤其是牙科医生,他们有着体面的工作并且收入不菲。但是,不管牙科医生的收入有多么高,一旦他某天停止拔牙,就没有了任何收入,所以他不得不每天上班;牙医要工作,因此需要有一个可以工作的场所,他可能会在你们家小区附近租一个店面。靳建通而这家店面的房东每个月什么事都不用做,也不需要拔牙,但每月都可以向牙医收取一定的租金。
老总只说了上面这么多,那他实际想告诉我们什么呢?靳建通我们继续深究一下,房东的租金从何而来呢?表面上看,是牙医支付给房东的;那牙医的钱又从哪里来呢?牙医的钱是拔牙赚得的。所以我们可以看出:牙医的一部分工作实际是在给房东打工(这一部分工作的收入支付了房租)。但是房东为什么会拥有这个店面呢?因为房东之前花钱购买了这家店面。所以这个事件的实质是:牙医为了赚钱而工作,房东的钱(已转换为了店面)在为房东赚钱。所以区别就是:为了钱而工作和让钱为你工作。
所以,我们应该想办法成为一个“房东”,而不是一个“牙医”,靳建通当然,这里的房东和牙医都是广义上的。
片段二:
老总有一次单独跟我谈话,他是这么说的:只要你有能力,将来你可以接替我做公司的老总,公司我只占小部分的股份,大部分的股份都给你和其他的经营者。随后他给我透露了两个思想,靳建通第一个思想是从蒙牛老总牛根生那里学来的,大致是这样:假设公司每年的盈利是200万,老总占80%的股份,员工占20%,那么老总的收益是每年160万;如果老总只占20%的股份,员工占80%的股份,那么会极大的调动员工的积极性和热情,因为员工的收入高了,并且公司的盈利状况会切实反映到员工的收入水平上,此时假设公司每年的盈利增长到了1000万,那么老总的收入20%则是200万。所以,尽管占得比例小了,靳建通但因为公司总体的效益很大,实际的收入反而上涨了,这体现了一个“财散人聚”的道理。华为2008年的销售额是200亿美元,即便华为老总任正非只占华为股份的1%,也将是一笔巨额的财富,不是么?
他透露的第二个思想就是:聪明人雇佣聪明人。从上一段可以看到,靳建通当公司整体效益上升的时候,即便你所占据的公司的股份降低了,你的收益也会上涨。同样的道理,当你在招聘的时候,尽可能去选拔比你更优秀的人,而不是比你差的人。就好像我现在一样,我是技术部经理,靳建通技术部人员的招聘由我负责,但是如果我遇到比我更优秀,更适合当技术部经理的人,我毫不犹豫就让贤,而不是将他卡在门外,怕他抢了我的饭碗。从表面上看,如果比我更优秀的人进到公司,取代了我的职位,造成的结果是我的职位降低了,我的收入甚至不及新入职的人高,但是,我更轻松了,因为他比我优秀,我的很多工作由他来做,而且比我做得更好,他可以带领着公司向更强大的方向发展。当公司更加强盛时,即便我的收入比他低,但是因为公司整体效益的上涨,我的收入反而比他来之前更高,这样公司的发展就会进入一个良性的循环。可惜的是,我发现很多人没有这样的胸襟和气魄,或者是没有这样的想法,对于比自己优秀的人不是珍惜和挽留,而是一味的排挤打压,最后人家只得另谋高就,这点我深有体会,呵呵靳建通。
片段三:
《炒股的智慧》里有这样一句话:“人的感情基本上是被恐惧和贪婪控制的”。靳建通我在现实中发现了活生生的例子,恐惧和贪婪支配了人的感情,而这种感情又反应在了行动上。
我们先来看贪婪的例子,就拿买车来说,假设你每月有10,000块的收入,并且手头有5万块的存款,你打算买辆什么车?(汽车首付最低通常为裸车价的30%~35%)你一定不会买辆奇瑞QQ或者捷达,因为你认为“有失身份”,因为你想要更好的,你的贪婪完全支配了你,所以你会买辆10万块以上甚至15万块的车,比如说福克斯、克鲁兹等。好的,现在再假设你每月有30,000块的收入,并且手头有12万块的存款,你打算买辆什么车?你绝对不会再考虑福克斯或者克鲁兹,这个时候你的目光一定是盯着奥迪、靳建通宝马或者是奔驰,这些车30万入门,你刚够首付。
我高中毕业的时候,我父亲给我了2000块钱,供我暑假用。因为暑期阳光很强烈,我就想买一幅太阳镜,我记得很清楚,我当时是这么想的“太眼镜这种东西又用不坏,一次就买副好的,以后都不用换了”,所以就花了200多块,买了一副自认为很高档的;我刚参加工作的时候,有一次在商场里逛,看到了一款“oh yeah”(欧也)的眼镜,很时尚,也很贵,有600多块。那时候我又在想“上副眼镜已经用了4年了,这次一步到位,以后再也不买太阳镜了”。狠了狠心,在我月薪只有1800块的时候,买了一副600块的眼镜;工作三年以后,我的收入上了一个台阶,有一天在海岸城(深圳的一个购物广场)逛的时候,看中了一款眼镜,雷朋的,一问价格,2600块,我怀着和上两次同样的想法刷了信用卡。
从这两件事,至少可以看到,我们经常会陷入一个误区,这个误区就是“我目前的经济状况不好,那么我只要努力工作赚更多的钱就可以解决问题了”。实际上,从买车的例子已经可以看出,即使收入已经很高了,你一样会负债,而且赚的越多,债务也背得越大!所以仅仅是努力工作、加薪、跳槽并不能解决实质问题,因为你贪婪的本性会促使你不断追求更高的目标。
再来看一个恐惧的例子,这个例子是我的父亲。我的父亲已经56岁了,现在还在工作,经营着一家个体商户。为什么到了退休的年龄,而我也已经长大成人并且有了自己的工作,他还要继续去工作?因为恐惧,他恐惧什么?他恐惧我某一天和同事或者老总出现矛盾而丢了工作,恐惧我身体不是很好的妈妈什么时候又需要住院治疗,恐惧我还在读书的妹妹新学期又要交多少的学费,靳建通所以他要去工作,因为一旦停止了工作,他的收入就只有可怜的一点退休金。不光他有恐惧,我们也有,有没有想过我们为什么要去上班,如果不上班会怎么样?就拿我来说,我很恐惧失掉现在的工作,因为我月底要交房租、要还信用卡、要还车贷,所以我努力工作,拼命赚钱,并且坚信自己一旦收入达到某某程度,靳建通这些问题统统都会解决掉。实际上这都是我的幻觉,我收入即便再高一些,我的负债也会同比增长,靳建通就好像片段一中所描述的那样。我们看到很多光鲜靓丽的都市白领,他们拥有很高的收入,但是很可能也背负着沉重的负债,他们所取得的成就,很多时候是恐惧和贪婪相互作用的结果。因为恐惧,所以拼命努力,因为贪婪,又再度陷入恐惧,周而复始。
片段四
片段四是一则新闻,看着我都发笑,因为这则新闻验证了上面那些话的正确性:“时下,在人民大学周边、五道口、通州等地区,活跃着一群开车练摊族。他们中有外语流利的海归、出入大厦的职员、培训学校的教师,下班后打开车后备厢,就成了地摊老板。 一位城管支队的队长告诉记者,“这些小白领摆摊尤其难对付”,称他们的出现给城市管理出了个难题。(《北京日报》6月15日)”
片段四没有什么好说的,只是印证了前面片段中描述的情况。靳建通白领为什么要去摆地摊?因为他们深陷债务泥潭无法自拔。
片段五
我记得有次在图书馆看报纸还是看书,看到了这样一句话“很多人搞不清楚什么是资产,什么是负债。实际上很好区分,你只要以这样一个尺度去衡量就行了:资产是为你创造收入的事物,负债是让你产生支出的事物”。
这个定义可以简化片段一中描述的事情,房东的钱,实际上是购买了资产,也就是那个店面,因为店面是可以为他创造收入的事物。而信用卡贷款、车贷、房贷则是你的负债,以汽车为例,你虽然拥有了一辆汽车,但它不是你的资产,因为它无法为你创造收入,靳建通反而你要为它每月支出,所以它是你的负债。那房子是不是资产呢?我们可以这样衡量一下,当房子的租金大于你支付的月供,或者房子有强烈的升值预期,并且你打算一旦升值就卖掉时,它就是你的资产,反之,就是你的负债。现在很多年轻人跟风买房,不作为投资,而作为自住,是很蠢笨的一种做法,你以为房子是你的资产,实际上房子是你的负债,因为你既然不出租,所以它无法为你创造收入,而你却要在未来20年背负沉重的债务。(这里会和很多人产生分歧,因为中国的传统观念是结婚要有房子,所以很多年轻人逼不得已硬着头皮买了房子,我只是发表我的个人看法。)
写到这里我觉得基本上可以把一个人的钱划分为五部分:1、正常收入,也即你每月工作的工资;2、正常支出,即吃穿住行;3、负债支出,即信用卡还款、车贷、房贷;4、资产支出,比如你一次性付清房款,然后拿去出租;5、资产收入,你每月获得的房租。
注意,上面的资产也是房子,我特别注明了是“一次性付清,然后拿去出租”,当然,不是只有房子才是资产,资产有很多种,比如说股票、基金。
当新婚的你们把所有的积蓄买了一套房子,为了体面又买了车子,实际上是平添了你们的负债。而本来这部分钱是可以用来做投资的,让你的钱为你工作,而不是整天为了钱去工作。举个例子,假如你现在有1万块钱,如果你把它放在家里,它是你的收入,不是你的资产,因为它无法为你创造收入;而如果有个人现在跑来问你借钱,承诺年底还你,并支付你10%的利息,你将钱借给他,然后持有他的欠条,那么这张欠条就变成了你的资产,因为它可以为你创造1000块钱。靳建通表面上看是你的1万块变成了11000块,实际上是别人在为你打工,和牙医的例子雷同了。
资产收入与正常收入的一个最大区别是:你不需要参与。如果你参与了,那就是你的职业了,产生的收入既是正常收入又是资产收入。就好像你发现每天上班的白领没有地方买早餐,于是你打算在楼下租间店面专门制作和卖早餐。作为投资,你应该租下这个店面,并且招募制作早餐、卖早餐,以及管理这家店的人员,但你不用自己去经营,因为你一旦去经营,那么这就是你的职业了。你只要做好基础设施,然后让这些人为你去赚钱就可以了。其实大家已经明白我要说什么了,公司也是资产,这家早餐店也是资产,因为它们可以为你创造收入。
所以为什么你的老板有钱,而你要每天工作还时常恐惧?靳建通因为他把钱用来买资产了,而你把钱用来买负债了,但是你把负债当成了资产。
如果你看过一些成功者早年的奋斗故事,你会听到他们常会说到这样一个词:“第一桶金”。实际上,很多年轻人买房子首付的钱比这些人所说的“第一桶金”要多得多,为什么不可以拿这些钱去做更重要的事情呢?举个例子,我在深圳,想明白这些之前也打算买房子,我看中的房子200万,首付40万,我打算好好奋斗2年然后就买。现在我觉悟了,我不会再干这种事,因为当我买下这个房子后,我即将背负160万的负债,这些负债足以压得我难有翻身之日,我将没有太多的钱去购买资产。那么这40万去做什么好呢?举个例子,我家乡西安的房产泡沫现象不大,而高新区很多白领需要租住房间,40万足够买两套单身公寓,而房子从长远来看是会升值的,那么我就在西安高新区买两套单身公寓然后拿去出租就好了。每套月租1200块,一个月有2400块的收入,这就是上面所列的资产收入了。但是投资公寓并不一定好,因为它的投资回报率并不高,但是一旦我需要用这笔钱,公寓可以随时卖掉。变富的途径就是不断地买入资产。
有人肯定会说,那照这样看来,除非一次付清,不然房子永远都不用买了,因为只要自住,就要产生负债。这种情况可以简单的用对冲来解决,对冲的方式就是用你的资产收入去对冲你的负债,也就是说,当你的资产达到一定数目,你的资产收入就可以抵消你的正常支出和负债支出。一旦到了这个时候,你甚至不需要再去工作,也不再有所恐惧(记得资产不需要你参与)。
赚钱和幸福感
我们不是为了赚钱而工作、投资,我们的最终目的只有一个:提升我们的幸福感。那么什么是幸福感呢?幸福感是一个比例,它的分子是“你已经拥有的东西”,分母是“你想要拥有的东西”,所以,提升幸福感有两个途径,一个是提高分子,那就是得到自己想得到的东西;还有一个就是降低分母,也就是降低自己的目标和要求。上面的所有内容都是在告诉你如何去赚钱,但是忽略了幸福感,比如说,你想买辆车,但是因为你知道买车是负债,所以你不去买(幸福感分子小),但是你又很想要(幸福感分母大),所以你不快乐。面临这种情况时你就需要做出一个权衡:究竟是增大投资减少负债降低幸福感呢?还是减少投资增大负债提升幸福感?这就看你更看重哪一个方面了。
http://service.bbs.163.com/bbs/tyro/290320725.html
用java的图形用户界面实现文件浏览功能(需要导包)
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Group;
import org.eclipse.wb.swt.SWTResourceManager;
public class TestShell {
protected Shell shell;
private Text text_file;
public static void main(String[] args) {
try {
TestShell window = new TestShell();
window.open();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Open the window.
*/
public void open() {
Display display = Display.getDefault();
createContents();
shell.open();
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
/**
* Create contents of the window.
*/
protected void createContents() {
shell = new Shell();
shell.setSize(500, 200);
shell.setText("解析WSDL");
text_file = new Text(shell, SWT.BORDER);
text_file.setBounds(80, 33, 290, 24);
//实现文件浏览功能
Button browseButton = new Button(shell,SWT.PUSH);
browseButton.setText("浏览...");
browseButton.setFont(SWTResourceManager.getFont("Tahoma", 12, SWT.NORMAL));
browseButton.setBounds(383, 33, 80, 24);
browseButton.addSelectionListener(new SelectionAdapter(){
/* (non-Javadoc)
* @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
*/
public void widgetSelected(SelectionEvent e){
FileDialog dialog = new FileDialog (shell, SWT.OPEN);
dialog.setText("Source Folder Selection");
dialog.setFilterExtensions(new String[] {"*.txt","*.jpg","*.*"});
String filePath = dialog.open();
if(dialog!=null){
text_file.setText(filePath);
}
}
});
Button button_exe = new Button(shell, SWT.NONE);
button_exe.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
MessageBox msgbox = new MessageBox(shell,
SWT.ICON_QUESTION | SWT.OK);
msgbox.setText("提示");
String file = "";
file = text_file.getText();
if(file.equals("") || file == null){
msgbox.setMessage("WSDL文件不能为空");
msgbox.open();
return;
}else{
msgbox.setMessage("文件获取到了!!!");
System.out.println(file);
msgbox.open();
}
}
});
button_exe.setFont(SWTResourceManager.getFont("Tahoma", 12, SWT.NORMAL));
button_exe.setBounds(214, 133, 87, 23);
button_exe.setText("\u6267\u884C");
Group group = new Group(shell, SWT.NONE);
group.setBounds(10, 10, 472, 117);
Label label = new Label(group, SWT.NONE);
label.setBounds(10, 23, 105, 24);
label.setFont(SWTResourceManager.getFont("Tahoma", 12, SWT.NORMAL));
label.setText("源文件:");
}
}
Spring中的JDBCTemplate使用
数据库准备:
创建数据库
创建表:
Java代码:
1、创建web 工程 springJdbcTemplate
2、添加Spring能力 在此需要将jdbc包也同时加入
3、配置上mysql的连接驱动(拷贝mysql驱动包,如果不拷贝报错很诡异)
在applicationContext.xml中进行配置
在beans标签中填写
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref local="dataSource" />
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/myspringjdbcdb</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>root</value>
</property>
</bean>
4、创建包结构并且写出类(每个类中可以没内容)
5、每个类中的源代码
UserDao.java
UserDaoImp.java
此项写完填写在applicationContext.xml中进行配置
在beans标签中填写
User.java
每个成员变量都写上get和set方法
并且在此类中还要加入
此项写完填写在applicationContext.xml中进行配置
在beans标签中填写
测试类TestAction.java
打印出结果:
Remote Object Service
对于主流的Flex数据服务器,目前都支持AMF3/RemoteObject,今天我们就来谈一谈BlazeDS的远程服务。
1. 编写远程服务类
编写BlazeDS的Java远程服务类有三个要求:
1) 所有被调用的方法必须是public;
2) 所有的编译类必须能够通过BlazeDS的classpath访问得到;
3) 类必须是stateful/stateless的。
大家可以参考工程文件中的SimpleService.java。
2. 配置remoting-config.xml
Java服务类写好后,还需要配置,BlazeDS的Remote Service也是在服务器端对应了一个配置文件:remoting-config.xml,配置好Remote Service 后,Flex在运行时才能找到相应的服务类并调用其方法。下面就是本工程的Remote Service配置文件。
第2~3行指定服务的ID和对应的类,第5~7行设置适配器(adapters)的ID和对应的类。第9~11行指定默认的通道(channels)及其参照,该通道是在 services-config.xml中定义的。适配器和通道可以设置多个,采用第一个优先的原则。前面这几项设置适用于proxy-config.xml、remoting-config.xml和我们后面要讲的 messaging-config.xml。
第13~18行设置的服务终端(destination),该属性必须和RemoteObject组件的服务终端属性一致。按照服务的种类,服务终端又可以分为代理服务终端、远程服务终端和消息服务终端。上一次讲述的代理服务终端,需要指定该终端的url,而这次我们讲述的远程服务终端,需要指定该目标的source和scope。source对应 RemoteObject要调用的远程服务的全限定类名,不像FluorineFX,它不能在RemoteObject组件中指定。scope表示当前远程服务的作用范围,即远程服务类是stateful还是stateless,有application、session和request三个选项。
注意:我们提倡在配置文件中设置,这样更安全也方便后期维护。
3. 使用RemoteObjec组件
对于RemoteObjec组件,请参看
下面的Flex RemoteObject类参考相关内容。一句话,Flex的RemoteObject与后台语言是无关的。在工程文件中的BasicRemoteObject.mxml,调用了SimpleService类的三个方法,当通过BlazeDS从J2EE服务器返回RemoteObjec时,Java数据被序列化成ActionScript数据。其中Java字符串对应ActionScript字符串,Java的数组列表对应ActionScript ArrayCollection。
Flex RemoteObject类参考
<mx:RemoteObject>标记允许使用AMF3访问远程服务类的方法,要知道在Flex中怎样使用Flash Remoting访问数据,应该先了解一下RemoteObject类。
要知道在Flex中怎样使用Flash Remoting访问数据,应该先了解一下RemoteObject类。
包 mx.rpc.remoting 类 public dynamic class RemoteObject
继承 RemoteObject → AbstractService → Proxy → Object
子类 RemoteObject
一、<mx:RemoteObject>标记
它允许使用AMF3访问远程服务类的方法。
1. <mx:RemoteObject>允许的标记属性有:
1
2
3
4
5
6
7
8
9
10
11
12
13 |
< mx:RemoteObject
Properties
concurrency = "multiple|single|last"
destination = "No default."
id = "No default."
endpoint = "No default."
showBusyCursor = "false|true"
source = "No default." (currently, Macromedia ColdFusion only)
makeObjectsBindable = "false|true"
事件
fault = "No default."
result = "No default."
/>
|
2. <mx:RemoteObject>标记可以包含多个 <mx:method> 标记,<mx:method>允许的标记属性有:
1
2
3
4
5
6
7
8
9 |
< mx:method
Properties
concurrency = "multiple|single|last"
name = "No default, required."
makeObjectsBindable = "false|true"
事件
fault = "No default."
result = "No default."
/>
|
3. <mx:RemoteObject>标记可以也只能包含一个<mx:arguments> 子标记,该子标记是一个序列数组对象。
二、公有属性
1. concurrency : String
表示对同一服务怎样进行多次调用。类似于XMLConnector/WebServiceConnector/RemotingConnector的multipleSimultaneousAllowed属性。它的默认值为multiple,允许下列值:
- Multiple:同一时间可以执行多个请求。已有的请求不会被取消;
- Single:同一时间调用只能执行一个请求,多个请求会报错;
- Last:最后一次请求会覆盖已有的请求。
2. endpoint: String
允许开发人员快速为RemoteObject destination(目标)指定endpoint(端点)。而该destination既没有在编译时,也没有在用代码新建ChannelSet(通道集)时参照services-config.xml。如果设定了该属性,它会覆盖已有的ChannelSet。
如果endpoint 的url 以“https”开关,将使用 SecureAMFChannel, 否则使用普通的AMFChannel。{server.name}和{server.port}标记,可以用在endpoint的url中,表明Channel应该使用用来加载SWF文件的服务名称和端口。
3. showBusyCursor:Boolean
表示服务正在执行时是否显示一个表示忙碌的鼠标指针。
三、公有方法
1. RemoteObject () 构造方法
创建一个新的RemoteObject对象。
参数
destination:String (默认为 null) —RemoteObject 的destination属性必须匹配 services-config.xml 中的destination的ID属性值。
2. initialized ()
public function initialized(document:Object, id:String):void
只要设定RemoteObject标记就会通过MXML编译器自动调用该方法。如果使用ActionScrip新建RemoteObject实例,则可以自行调用该方法,这对验证其参数很有用。
参数
- document:Object —RemoteObject 所在的MXML文档
- id:String —RemoteObjec在上述文档中的ID
在Flex中使用ActionScript,其实和在网页中使用Javascript等脚本文件类似,主要有三种方式。
Flex的核心是MXML和ActionScript。MXML是用于为Flex应用程序进行用户界面组件布局,它属于表示层,最终要编辑成ActionScript 并生成ActionScript 类文件在Flash Player上运行。如果你是个Java开发者就很好理解这一点,MXML 就好比是JSP/Struts/JSF,它们最终都会编辑成Java类文件并在具备Java虚拟机环境的浏览器上运行。所以说,Flex 最核心的还是ActionScript 。在Flex中,ActionScript是 类库的方式出现的,该类库包含组件 (容器和控件)、管理器类、数据服务类和所有其他功能的类。本文将谈一谈在Flex中使用ActionScript的方法。
其实和在网页中使用Javascript等脚本文件类似,主要有三种方式。
1. 内联方式
这种方式直接将AS方法作为事件的属性值,当然这种方法一般只有一行,相对简单。如果要给方法传递对数,这种方法就不可取了。
1
2
3
4
5
6
7
8
9
10
11
12
13 |
<? xml version = "1.0" encoding = "utf-8" ?>
< mx:Application xmlns:mx = "http://www.adobe.com/2006/mxml" layout = "vertical" >
< mx:Button label = "Say Hello" click = "sayHello('Flying')" />
< mx:Script >
<![CDATA[
import mx.controls.Alert;
private function sayHello(param_name:String):void {
Alert.show("Hello, "+param_name);
}
]]>
</ mx:Script >
</ mx:Application >
|
2. 级联方式
这种方式将AS方法放入<mx:Script></mx:Script>代码块中,然后将方法作为事件的属性值,并可以在调用方法时传递参数,从而做到了AS方法在一个文件中的重用。
1
2
3
4
5
6 |
<? xml version = "1.0" encoding = "utf-8" ?>
< mx:Application xmlns:mx = "http://www.adobe.com/2006/mxml" layout = "vertical" >
< mx:Script source = "myFunction.as" />
< mx:Button label = "Say Hello" click = "sayHello('Flying');" />
</ mx:Application >
|
3. 外联方式
1
2
3
4
5 |
mx.controls.Alert;
private function sayHello(param_name: String ): void {
mx.controls.Alert.show( "Hello, " +param_name);
}
|
上述方式为AS方法单独新建一个as文件,然后设置该方法为被调用文件的Script元素的source属性值,并可以在调用方法时传递参数,此文件可以在多个文件调用,从而实现了AS方法在多个文件中的重用。
Flex跳转到JSP或者其他非Flex页面
Html代码
var url:String="http://"+URLUtil.getServerNameWithPort(Application.application.url)+"/DZDJ/index.jsp?id=" + 1;
ExternalInterface.call('window.open',url,'_top');
_top是可变的,_top表示在当前页面打开,关闭远页面。
导入类:
import flash.net.URLRequest;
import flash.net.navigateToURL;
关闭当前浏览器:
var url:URLRequest = new URLRequest("javascript:window.close()");
navigateToURL(url,"_top");
(注意:要在服务器上测试,否则会报安全沙箱冲突);
在浏览器上跳转页面
navigateToURL(new URLRequest("http://www.baidu.com"),"_top");
打开一个新的浏览器:
var request:URLRequest = new URLRequest("http://www.baidu.com/);
navigateToURL(request);
Flex跳转到Flex
FLEX和JSP不一样,没有所谓的这个页面跳转到另外的一个页面。一般都是用ViewStack进行页面切换,其他模块就需要loadmoudle进行函数设置了。
<mx:ViewStack x="0" y="0" id="viewstack1" width="619" height="700">
<mx:Canvas id="View1" width="100%" height="100%">
<mx:Button label="View2 " click="viewstack1.selectedChild=View2"/>
</mx:Canvas>
<mx:Canvas id="View2" width="100%" height="100%" color="#3FCFE9">
</mx:Canvas>
</mx:ViewStack>
摘要: 线程和进程
一,线程的一些基本知识。进程与线程所有的操作系统都支持同时运行多个任务,一个任务通常就是一个程序,每个运行中就是一个进程,当一个程序运行时,内部可能包含了多个顺序执行流,每个顺序执行流就是一个线程。
进程(process)当一个程序进入内存运行即变成一个进程,进程处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调用的独立单位,进程切换开销大。
多进程在操作系...
阅读全文
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class FileDownLoadTest {
private static final int TCOUNT = 10;
private CountDownLatch latch = new CountDownLatch(TCOUNT);
private long completeLength = 0;
private long fileLength;
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
new FileDownLoadTest().download("http://localhost:8080/test/IESSAction.docx");
}
public void download(String address) throws Exception{
ExecutorService service = Executors.newFixedThreadPool(TCOUNT);
URL url = new URL(address);
URLConnection cn = url.openConnection();
cn.setRequestProperty("Referer", "http://www.test.com");
fileLength = cn.getContentLength();
long packageLength = fileLength/TCOUNT;
long leftLength = fileLength%TCOUNT;
RandomAccessFile file = new RandomAccessFile("d:\\test.docx","rw");
//计算每个线程请求文件的开始和结束位置
long pos = 0;
long endPos = pos + packageLength;
for(int i=0; i<TCOUNT; i++){
if(leftLength >0){
endPos ++;
leftLength--;
}
service.execute(new DownLoadThread(url, file, pos, endPos));
pos = endPos;
endPos = pos + packageLength;
}
System.out.println("waiting........................................");
long begin = System.currentTimeMillis();
latch.await();
file.close();
System.out.println("end........................................");
System.out.println(System.currentTimeMillis() - begin + "ms");
service.shutdown();
}
class DownLoadThread implements Runnable{
private URL url;
private RandomAccessFile file;
private long from;
private long end;
DownLoadThread(URL url, RandomAccessFile file, long from, long end){
this.url = url;
this.file = file;
this.from = from;
this.end = end;
}
public void run() {
long pos = from;
byte[] buf = new byte[512];
try {
HttpURLConnection cn = (HttpURLConnection) url.openConnection();
cn.setRequestProperty("Range", "bytes=" + from + "-" + end);
if(cn.getResponseCode() != 200 && cn.getResponseCode()!=206){
run();
return;
}
BufferedInputStream bis = new BufferedInputStream(cn.getInputStream());
int len ;
while((len = bis.read(buf)) != -1){
// synchronized(file){
file.seek(pos);
file.write(buf, 0, len);
// }
pos += len;
completeLength +=len;
System.out.println("threadName: " + Thread.currentThread().getName()
+ "persent: " + completeLength * 100 /fileLength + "%");
}
cn.disconnect();
latch.countDown();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
JAVA直接操作excel
/**
* @Author:何云龙
* @Version: 2012-11-16 下午03:45:16
* @Description:
*/
import jxl.*;
import java.io.*;
import jxl.write.*;
/**
* <p>
* java读取Excel表格,复制、更新Excel工作薄
* </p>
*/
public class Test {
public static void main(String[] args) {
jxl.Workbook rwb = null;
try {
// 构建Workbook对象 只读Workbook对象
// 直接从本地文件创建Workbook
// 从输入流创建Workbook
InputStream is = new FileInputStream("D://Book1.xls");
rwb = Workbook.getWorkbook(is);
// Sheet(术语:工作表)就是Excel表格左下角的Sheet1,Sheet2,Sheet3但在程序中
// Sheet的下标是从0开始的
// 获取第一张Sheet表
Sheet rs = rwb.getSheet(0);
// 获取Sheet表中所包含的总列数
int rsColumns = rs.getColumns();
// 获取Sheet表中所包含的总行数
int rsRows = rs.getRows();
// 获取指这下单元格的对象引用
for (int i = 0; i < rsRows; i++) {
for (int j = 0; j < rsColumns; j++) {
Cell cell = rs.getCell(j, i);
System.out.print(cell.getContents() + " ");
}
System.out.println();
}
// 利用已经创建的Excel工作薄创建新的可写入的Excel工作薄
jxl.write.WritableWorkbook wwb = Workbook.createWorkbook(new File(
"D://Book2.xls"), rwb);
// 读取第一张工作表
jxl.write.WritableSheet ws = wwb.getSheet(0);
// 获取第一个单元格对象
jxl.write.WritableCell wc = ws.getWritableCell(0, 0);
// 决断单元格的类型,做出相应的转化
if (wc.getType() == CellType.LABEL) {
Label l = (Label) wc;
l.setString("The value has been modified.");
}
// 写入Excel对象
wwb.write();
wwb.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 操作完成时,关闭对象,翻译占用的内存空间
rwb.close();
}
}
}
方法1:[第一种方法比后一种生成的缩略图要清晰]
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.io.InputStream;
import java.io.File;
import java.io.FileOutputStream;
public class Test {
public static BufferedImage resize(BufferedImage source, int targetW, int targetH) {
// targetW,targetH分别表示目标长和宽
int type = source.getType();
BufferedImage target = null;
double sx = (double) targetW / source.getWidth();
double sy = (double) targetH / source.getHeight();
//这里想实现在targetW,targetH范围内实现等比缩放。如果不需要等比缩放
//则将下面的if else语句注释即可
if(sx>sy)
{
sx = sy;
targetW = (int)(sx * source.getWidth());
}else{
sy = sx;
targetH = (int)(sy * source.getHeight());
}
if (type == BufferedImage.TYPE_CUSTOM) { //handmade
ColorModel cm = source.getColorModel();
WritableRaster raster = cm.createCompatibleWritableRaster(targetW, targetH);
boolean alphaPremultiplied = cm.isAlphaPremultiplied();
target = new BufferedImage(cm, raster, alphaPremultiplied, null);
} else
target = new BufferedImage(targetW, targetH, type);
Graphics2D g = target.createGraphics();
//smoother than exlax:
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY );
g.drawRenderedImage(source, AffineTransform.getScaleInstance(sx, sy));
g.dispose();
return target;
}
public static void saveImageAsJpg (String fromFileStr,String saveToFileStr,int width,int hight)
throws Exception {
BufferedImage srcImage;
// String ex = fromFileStr.substring(fromFileStr.indexOf("."),fromFileStr.length());
String imgType = "JPEG";
if (fromFileStr.toLowerCase().endsWith(".png")) {
imgType = "PNG";
}
// System.out.println(ex);
File saveFile=new File(saveToFileStr);
File fromFile=new File(fromFileStr);
srcImage = ImageIO.read(fromFile);
if(width > 0 || hight > 0)
{
srcImage = resize(srcImage, width, hight);
}
ImageIO.write(srcImage, imgType, saveFile);
}
public static void main (String argv[]) {
try{
//参数1(from),参数2(to),参数3(宽),参数4(高)
Test.saveImageAsJpg("E:/Document/My Pictures/3.gif","c:/6.gif",50,50);
} catch(Exception e)
{
e.printStackTrace();
}
}
}
方法2:
import java.io.*;
import java.util.*;
import com.sun.image.codec.jpeg.*;
import java.awt.image.*;
import java.awt.*;
import java.net.*;
import java.applet.*;
import java.sql.*;
//缩略图类,
//本java类能将jpg图片文件,进行等比或非等比的大小转换。
//具体使用方法
//s_pic(大图片路径,生成小图片路径,大图片文件名,生成小图片文名,生成小图片宽度,生成小图片高度,是否等比缩放(默认为true))
public class Tes {
String InputDir; //输入图路径
String OutputDir; //输出图路径
String InputFileName; //输入图文件名
String OutputFileName; //输出图文件名
int OutputWidth = 80; //默认输出图片宽
int OutputHeight = 80; //默认输出图片高
int rate = 0;
boolean proportion = true; //是否等比缩放标记(默认为等比缩放)
public Tes() {
//初始化变量
InputDir = "";
OutputDir = "";
InputFileName = "";
OutputFileName = "";
OutputWidth = 80;
OutputHeight = 80;
rate = 0;
}
public void setInputDir(String InputDir) {
this.InputDir = InputDir;
}
public void setOutputDir(String OutputDir) {
this.OutputDir = OutputDir;
}
public void setInputFileName(String InputFileName) {
this.InputFileName = InputFileName;
}
public void setOutputFileName(String OutputFileName) {
this.OutputFileName = OutputFileName;
}
public void setOutputWidth(int OutputWidth) {
this.OutputWidth = OutputWidth;
}
public void setOutputHeight(int OutputHeight) {
this.OutputHeight = OutputHeight;
}
public void setW_H(int width, int height) {
this.OutputWidth = width;
this.OutputHeight = height;
}
public String s_pic() {
BufferedImage image;
String NewFileName;
//建立输出文件对象
File file = new File(OutputDir + OutputFileName);
FileOutputStream tempout = null;
try {
tempout = new FileOutputStream(file);
} catch (Exception ex) {
System.out.println(ex.toString());
}
Image img = null;
Toolkit tk = Toolkit.getDefaultToolkit();
Applet app = new Applet();
MediaTracker mt = new MediaTracker(app);
try {
img = tk.getImage(InputDir + InputFileName);
mt.addImage(img, 0);
mt.waitForID(0);
} catch (Exception e) {
e.printStackTrace();
}
if (img.getWidth(null) == -1) {
System.out.println(" can't read,retry!" + "<BR>");
return "no";
} else {
int new_w;
int new_h;
if (this.proportion == true) { //判断是否是等比缩放.
//为等比缩放计算输出的图片宽度及高度
double rate1 = ((double) img.getWidth(null)) /
(double) OutputWidth + 0.1;
double rate2 = ((double) img.getHeight(null)) /
(double) OutputHeight + 0.1;
double rate = rate1 > rate2 ? rate1 : rate2;
new_w = (int) (((double) img.getWidth(null)) / rate);
new_h = (int) (((double) img.getHeight(null)) / rate);
} else {
new_w = OutputWidth; //输出的图片宽度
new_h = OutputHeight; //输出的图片高度
}
BufferedImage buffImg = new BufferedImage(new_w, new_h,
BufferedImage.TYPE_INT_RGB);
Graphics g = buffImg.createGraphics();
g.setColor(Color.white);
g.fillRect(0, 0, new_w, new_h);
g.drawImage(img, 0, 0, new_w, new_h, null);
g.dispose();
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(tempout);
try {
encoder.encode(buffImg);
tempout.close();
} catch (IOException ex) {
System.out.println(ex.toString());
}
}
return "ok";
}
public String s_pic(String InputDir, String OutputDir, String InputFileName,
String OutputFileName) {
//输入图路径
this.InputDir = InputDir;
//输出图路径
this.OutputDir = OutputDir;
//输入图文件名
this.InputFileName = InputFileName;
//输出图文件名
this.OutputFileName = OutputFileName;
return s_pic();
}
public String s_pic(String InputDir, String OutputDir, String InputFileName,
String OutputFileName, int width, int height,
boolean gp) {
//输入图路径
this.InputDir = InputDir;
//输出图路径
this.OutputDir = OutputDir;
//输入图文件名
this.InputFileName = InputFileName;
//输出图文件名
this.OutputFileName = OutputFileName;
//设置图片长宽
setW_H(width, height);
//是否是等比缩放 标记
this.proportion = gp;
return s_pic();
}
public static void main(String[] a) {
//s_pic(大图片路径,生成小图片路径,大图片文件名,生成小图片文名,生成小图片宽度,生成小图片高度)
Tes mypic = new Tes();
System.out.println(
mypic.s_pic("E://Document//My Pictures//",
"E://Document//My Pictures//",
"topbg-3.gif", "3.gif", 400, 400, true)
);
}
}
3.jsp方式
java.io.*,java.awt.Image,java.awt.image.*,com.sun.image.codec.jpeg.*,
try
{
java.io.File file = new java.io.File("E://Document//My Pictures//3.gif");
String newurl="E://Document//My Pictures//32.gif"; //新的缩略图保存地址
Image src = javax.imageio.ImageIO.read(file); //构造Image对象
float tagsize=200;
int old_w=src.getWidth(null); //得到源图宽
int old_h=src.getHeight(null);
int new_w=0;
int new_h=0; //得到源图长
int tempsize;
float tempdouble;
if(old_w>old_h){
tempdouble=old_w/tagsize;
}else{
tempdouble=old_h/tagsize;
}
new_w=Math.round(old_w/tempdouble);
new_h=Math.round(old_h/tempdouble);//计算新图长宽
BufferedImage tag = new BufferedImage(new_w,new_h,BufferedImage.TYPE_INT_RGB);
tag.getGraphics().drawImage(src,0,0,new_w,new_h,null); //绘制缩小后的图
FileOutputStream newimage=new FileOutputStream(newurl); //输出到文件流
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(newimage);
encoder.encode(tag); //近JPEG编码
newimage.close();
}catch (Exception e){
e.toString();
}
使用JavaSEAPI读取Properties文件的六种方法
1。使用java.util.Properties类的load()方法
示例:InputStreamin=lnewBufferedInputStream(newFileInputStream(name));
Propertiesp=newProperties();
p.load(in);
2。使用java.util.ResourceBundle类的getBundle()方法
示例:ResourceBundlerb=ResourceBundle.getBundle(name,Locale.getDefault());
3。使用java.util.PropertyResourceBundle类的构造函数
示例:InputStreamin=newBufferedInputStream(newFileInputStream(name));
ResourceBundlerb=newPropertyResourceBundle(in);
4。使用class变量的getResourceAsStream()方法
示例:InputStreamin=JProperties.class.getResourceAsStream(name);
Propertiesp=newProperties();
p.load(in);
5。使用class.getClassLoader()所得到的java.lang.ClassLoader的getResourceAsStream()方法
示例:InputStreamin=JProperties.class.getClassLoader().getResourceAsStream(name);
Propertiesp=newProperties();
p.load(in);
6。使用java.lang.ClassLoader类的getSystemResourceAsStream()静态方法
示例:InputStreamin=ClassLoader.getSystemResourceAsStream(name);
Propertiesp=newProperties();
p.load(in);
补充
Servlet中可以使用javax.servlet.ServletContext的getResourceAsStream()方法
示例:InputStreamin=context.getResourceAsStream(path);
Propertiesp=newProperties();
p.load(in);
jdbc继续改进版
/**
* @author sign
* @describe 改进第三版
*
*/
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.LinkedList;
import java.util.Map;
import java.util.TreeMap;
public class JDBCUtil {
Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
String url="jdbc:mysql://localhost:3306/theatermanagement";
String user="root";
String psw="root";
static{
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Connection getConn(){
try {
conn=DriverManager.getConnection(url, user, psw);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
public int update(String sql){
try {
stmt=this.getConn().createStatement();
return stmt.executeUpdate(sql);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return -1;
}finally{
release();
}
}
public LinkedList<Map<String,Object>> query(String sql){
LinkedList<Map<String,Object>> list=new LinkedList<Map<String,Object>>();
try {
stmt=getConn().createStatement();
rs=stmt.executeQuery(sql);
ResultSetMetaData rsmd=rs.getMetaData();
int count=rsmd.getColumnCount();
while(rs.next()){
Map<String,Object> map=new TreeMap<String,Object>();
for (int i = 0; i < count; i++) {
String key=rsmd.getColumnName(i+1);
String keyy="";
if(key.equals("")){// 聚合函数bug
System.out.println("聚合函数bug"+key);
keyy="count";
Object value=rs.getObject(1);
map.put(keyy, value);
}else{
Object value=rs.getObject(key);
map.put(key, value);
}
}
list.add(map);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
release();
}
return list;
}
/**批量更新*/
public void excuteBatch(String[] sqls){
conn=this.getConn();
/**设置提交模式为手动提交*/
try{
conn.setAutoCommit(false);
stmt=conn.createStatement();
for(String sql:sqls){
stmt.addBatch(sql);
}
stmt.executeBatch();
/**手动提交*/
conn.commit();//事务
}catch(SQLException e){
e.printStackTrace();
}finally{
release();
}
}
/**释放资源*/
public void release(){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
枚举类型(enum)在Switch中的使用以及遍历枚举类型(enum)中的内容
public class EnumDemo {
//定义枚举类型
enum Month {
January, February, March, April, May, June, July,August,September,October,November,December
}
public static void main(String[] args) {
Month mon = Month.August;
switch (mon) {
case August:
System.out.println("这是个旅游的季节");
break;
case December:
System.out.println("这是个滑雪的季节");
break;
}
//循环遍历枚举类型Month
for (Month month : Month.values()) {
System.out.println(month + ", 顺序: " + month.ordinal());
}
}
}
有一天,神创造了一头牛。神对牛说:“你要整天在田里替农夫耕田,供应牛奶给人类饮用。你要工作直至日落,而你只能吃草。我给你50年的寿命。”
牛抗议道:“我这么辛苦,还只能吃草,我只要20年寿命,余下的还给你。” 神答应了。
第二天,神创造了猴子。
神跟猴子说:“你要娱乐人类,令他们欢笑,你要表演翻斤斗,而你只能吃香蕉。我给你20年的寿命。”
猴子抗议:“要引人发笑,表演杂技,还要翻斤斗,这么辛苦,我活10年好了。” 神答应了。
第三天,神创造了狗。 神对狗说:“你要站在门口吠,吃主人吃剩的东西。我给你25年的寿命。”
狗抗议道:“整天坐在门口吠,我要15年好了,余下的还给你。” 神答应了。
第四天,神创造了人。 神对人说:“你只需要睡觉、吃东西和玩耍,不用做任何事情,只需要尽情地享受生命,我给你20年的寿命。”
人抗议道:“这么好的生活只有20年,太短!”
神没说话。 人对神说:“这样吧。牛还了30年给你,猴子还了10年,狗也还了10年,这些都给我好了,那我就能活到70岁。”
神答应了。 这就是为什么我们的头20年只需吃饭、睡觉和玩耍;之后的30年,我们像一条牛整天工作养家;接着的10年,我们退休了,不得不像只猴子表演杂耍来娱乐自己的孙儿;最后的10年,整天留在家里,像一条狗坐在门口看门……
Write operations are not allowed in read-only mode 只读模式下(FlushMode.NEVER/MANUAL)写操作不允
org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.
问题:只读模式下(FlushMode.NEVER/MANUAL)写操作不被允许:把你的Session改成FlushMode.COMMIT/AUTO或者清除事务定义中的readOnly标记。
错误原因:
OpenSessionInViewFilter在getSession的时候,会把获取回来的session的flush mode 设为FlushMode.NEVER。然后把该sessionFactory绑定到TransactionSynchronizationManager,使request的整个过程都使用同一个session,在请求过后再接除该sessionFactory的绑定,最后closeSessionIfNecessary根据该session是否已和transaction绑定来决定是否关闭session。在这个过程中,若HibernateTemplate 发现自当前session有不是readOnly的transaction,就会获取到FlushMode.AUTO Session,使方法拥有写权限。也即是,如果有不是readOnly的transaction就可以由Flush.NEVER转为Flush.AUTO,拥有insert,update,delete操作权限,如果没有transaction,并且没有另外人为地设flush model的话,则doFilter的整个过程都是Flush.NEVER。所以受transaction(声明式的事务)保护的方法有写权限,没受保护的则没有。
解决方法:
web.xml配置里添加
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>
</init-param>
<init-param>
<param-name>singleSession</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name> flushMode </param-name>
<param-value>AUTO </param-value>
</init-param>
</filter>
// 。。。。
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
如果在交给spring 管理的情况下,在beans.xml 里的配置
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<aop:config>
<aop:pointcut id="bussinessService"
expression="execution(* com.fan.service.base.*.*(..))" />
<aop:advisor pointcut-ref="bussinessService"
advice-ref="txAdvice" />
</aop:config>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" read-only="false" propagation="NOT_SUPPORTED"/>
<tx:method name="find*" read-only="false" propagation="NOT_SUPPORTED"/>
<tx:method name="save*" propagation="REQUIRED"/> // 如果不把save update delete都配置上,
<tx:method name="update*" propagation="REQUIRED"/> //这些操作会无效
<tx:method name="delete*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hyl.phone" android:versionCode="1" android:versionName="1.0">
<application android:icon="@drawable/maolv" android:label="@string/app_name">
<activity android:name=".phoneActivity" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<!-- 开发的应用适应的版本8代表Android2.2 -->
<uses-sdk android:minSdkVersion="8" />
<!-- 这里指定拨打电话的权限 -->
<uses-permission android:name="android.permission.CALL_PHONE" />
</manifest>
hyl.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="mobellabel">请输入手机号码</string>
<string name="button">拨打此号码</string>
</resources>
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="@string/mobellabel"
android:id="@+id/TextView01"
/>
<EditText android:id="@+id/EditText01"
android:layout_width="fill_parent" android:layout_height="wrap_content" />
<Button android:text="@string/button" android:id="@+id/Button01"
android:layout_width="wrap_content" android:layout_height="wrap_content" />
</LinearLayout>
phoneActivity.java
package com.hyl.phone;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class phoneActivity extends Activity {
/** Called when the activity is first created. */
private Button button;
private EditText editText;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button= (Button)this.findViewById(R.id.Button01);
editText=(EditText) this.findViewById(R.id.EditText01);
button.setOnClickListener(new ButtonListener());
}
private final class ButtonListener implements View.OnClickListener{
public void onClick(View v) {
String phonenum=editText.getText().toString();
//android.intent.action.CALL=Intent.ACTION_CALL
Intent intent=new Intent(Intent.ACTION_CALL,Uri.parse("tel:"+phonenum));
startActivity(intent);
}
}
}
JSP页面<body>
<s:fielderror></s:fielderror>
<s:form action="uploadUploadAction"
enctype="multipart/form-data" theme="simple">
用户名:<s:textfield name="userName" />
<br />
密码: <s:textfield name="userPwd" />
<br />
<input type="file" name="file" />
<br />
<s:submit value="提交"></s:submit>
</s:form>
<br />
下载<a href="DownLoadAction">开始.gif</a>
</body>
UploadAction
package com.hyl.action;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.struts2.ServletActionContext;
import com.hyl.util.DateUtil;
import com.opensymphony.xwork2.ActionSupport;
public class UploadAction extends ActionSupport {
private File file;
private String fileFileName;
private String fileContentType;
private String userName;
private String userPwd;
public String upload() throws IOException {
String path = ServletActionContext.getRequest().getRealPath("/upload");
// System.out.println(path);
InputStream is = new FileInputStream(file);
String date = DateUtil.mailDate(new java.util.Date());
// 截取的文件扩展名
String fileExtenName = fileFileName
.substring(fileFileName.indexOf('.'));
// System.out.println("截取的文件扩展名"+fileName);
File serverFile = new File(path, date + fileExtenName);
OutputStream os = new FileOutputStream(serverFile);
byte[] b = new byte[1024];
int length = 0;
while ((length = is.read(b)) > 0) {
os.write(b);
}
os.close();
is.close();
return SUCCESS;
}
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public String getFileFileName() {
return fileFileName;
}
public void setFileFileName(String fileFileName) {
this.fileFileName = fileFileName;
}
public String getFileContentType() {
return fileContentType;
}
public void setFileContentType(String fileContentType) {
this.fileContentType = fileContentType;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
}
DownLoadAction
package com.hyl.action;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class DownLoadAction extends ActionSupport {
//下面以中文名文件实例
//此处文件名称由用户输入,此处也是动态传参的过程
private String picName = "开始.gif";
public InputStream getDownLoad() throws UnsupportedEncodingException {
//此处做一个中间变量,当重新编码后就无法识别中文名了
String rourseName=picName;
//将源文件的中文名重新编码,目的值让Struts的配置文件中能识别到,呈现给用户看
picName=new String(picName.getBytes(),"iso-8859-1");
System.out.println("/upload/"+rourseName);
return ServletActionContext.getServletContext().getResourceAsStream(
"/upload/"+rourseName);
}
public String execute() throws Exception {
return super.execute();
}
public String getPicName() {
return picName;
}
public void setPicName(String picName) {
this.picName = picName;
}
}
DateUtil
package com.hyl.util;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class DateUtil {
public static String dateTimeChange(Date source) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String changeTime = format.format(source);
return changeTime;
}
public static String shortDate(Date aDate) {
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
return formatter.format(aDate);
}
public static String nowDate() {
String iDate = "";
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String str = formatter.format(new Date());
String[] date = str.split("-");
if (date.length >= 3) {
iDate = date[0] + "/" + date[1] + "/" + date[2] + "";
} else {
iDate = str;
}
return iDate;
}
public static String mailDate(Date aDate) {
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmssSSS");
return formatter.format(aDate);
}
public static String dateParser(Date aDate) {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
return formatter.format(aDate);
}
public static Date parser(String strDate) {
;
strDate = strDate.replace("/", "-");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
return sdf.parse(strDate);
} catch (Exception e) {
return null;
}
}
public static Date parser(String strDate, String formatter) {
SimpleDateFormat sdf = new SimpleDateFormat(formatter);
try {
return sdf.parse(strDate);
} catch (Exception e) {
return null;
}
}
public static String parser(Date date, String formatter) {
SimpleDateFormat sdf = new SimpleDateFormat(formatter);
try {
return sdf.format(date);
} catch (Exception e) {
return null;
}
}
public static Date addMonth(Date myDate, int amount) {
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(myDate);
boolean isEndDayOfMonth_old = cal
.getActualMaximum(GregorianCalendar.DAY_OF_MONTH) == cal
.get(GregorianCalendar.DAY_OF_MONTH);
cal.add(GregorianCalendar.MONTH, amount);
boolean isEndDayOfMonth_new = cal
.getActualMaximum(GregorianCalendar.DAY_OF_MONTH) == cal
.get(GregorianCalendar.DAY_OF_MONTH);
if (isEndDayOfMonth_old && !isEndDayOfMonth_new) {
cal.set(GregorianCalendar.DATE, cal
.getActualMaximum(GregorianCalendar.DAY_OF_MONTH));
}
return cal.getTime();
}
public static Date addDay(Date myDate, int amount) {
Calendar cal = Calendar.getInstance();
cal.setTime(myDate);
cal.add(Calendar.DAY_OF_MONTH, amount);
return cal.getTime();
}
public static Date addMinute(Date myDate, int amount) {
Calendar cal = Calendar.getInstance();
cal.setTime(myDate);
int minute = 0;
amount = -(amount);
if (amount > 60) {
int hour = (int) amount / 60;
if (hour * 60 > amount) {
minute = hour * 60 - amount;
cal.add(Calendar.HOUR_OF_DAY, -hour);
cal.add(Calendar.MINUTE, minute);
} else if (hour * 60 < amount) {
minute = amount - hour * 60;
cal.add(Calendar.HOUR_OF_DAY, -hour);
cal.add(Calendar.MINUTE, -minute);
} else {
cal.add(Calendar.HOUR_OF_DAY, -hour);
}
} else {
cal.add(Calendar.MINUTE, -amount);
}
return cal.getTime();
}
public static Date addYear(Date myDate, int amount) {
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(myDate);
boolean isEndDayOfMonth_old = cal
.getActualMaximum(GregorianCalendar.DAY_OF_MONTH) == cal
.get(GregorianCalendar.DAY_OF_MONTH);
cal.add(GregorianCalendar.YEAR, amount);
boolean isEndDayOfMonth_new = cal
.getActualMaximum(GregorianCalendar.DAY_OF_MONTH) == cal
.get(GregorianCalendar.DAY_OF_MONTH);
if (isEndDayOfMonth_old && !isEndDayOfMonth_new) {
cal.set(GregorianCalendar.DATE, cal
.getActualMaximum(GregorianCalendar.DAY_OF_MONTH));
}
return cal.getTime();
}
public static int getWeekDay(Date myDate) {
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(myDate);
return cal.get(GregorianCalendar.DAY_OF_WEEK);
}
public static int getConvertWeekDay(Date myDate) {
int day = getWeekDay(myDate);
int result = day - 1;
if (result == 0)
result = 7;
return result;
}
public static int getTimeFromDate(Date myDate) {
SimpleDateFormat sdf = new SimpleDateFormat("hhmmss");
int result = Integer.parseInt(sdf.format(myDate));
return result;
}
public static long getDaysBetweenDate(Date startDate, Date endDate) {
Calendar cal = Calendar.getInstance();
cal.setTime(startDate);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
startDate = cal.getTime();
cal.setTime(endDate);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return (cal.getTime().getTime() - startDate.getTime()) / 86400000;
}
public static String strDateTime(String str) {
String idate = "";
if (str != null) {
String[] date = str.split("-");
if (date.length >= 3) {
idate = date[0] + "." + date[1] + "." + date[2];
} else {
idate = str;
}
}
return idate;
}
public static String strDotDateTime(String str) {
String idate = "";
if (str != null) {
String data0 = null;
String[] date = str.split("-");
if (date.length >= 3) {
if (date[0] != null) {
data0 = date[0].substring(2, 4);
}
idate = data0 + "." + date[1] + "." + date[2];
} else {
idate = str;
}
}
return idate;
}
public static String bakDateTime(String str) {
String idate = "";
if (str != null) {
int l1 = str.indexOf(".");
String d1 = str.substring(0, l1);
String s1 = str.substring(l1 + 1);
int l2 = s1.indexOf(".");
String d2 = s1.substring(0, l2);
String d3 = s1.substring(l2 + 1);
idate = d1 + "-" + d2 + "-" + d3;
}
return idate;
}
public static String strShortDateTime(String str) {
String idate = "";
if (str != null) {
String[] date = str.split("-");
if (date.length >= 3) {
idate = date[0] + "." + date[1] + "." + date[2];
} else {
idate = str;
}
if (idate != null && idate.length() > 9) {
idate = idate.substring(0, 10);
}
}
return idate;
}
public static int getBetweenDayNumber(String dateA, String dateB) {
long dayNumber = 0;
long DAY = 24L * 60L * 60L * 1000L;
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
try {
java.util.Date d1 = df.parse(dateA);
java.util.Date d2 = df.parse(dateB);
dayNumber = (d2.getTime() - d1.getTime()) / DAY;
} catch (Exception e) {
e.printStackTrace();
}
return (int) dayNumber;
}
public static void main(String[] args) {
System.out.println(nowDate());
}
}
messageFile.properties
struts.messages.error.file.too.large=\u6587\u4EF6\u8FC7\u5927
struts.messages.error.content.type.not.allowed=\u6587\u4EF6\u7C7B\u578B\u4E0D\u4E00\u81F4
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<!--加载Struts的消息资源文件 value里面指定messageFile.properties的文件名字,不写扩展名字-->
<constant name="struts.custom.i18n.resources" value="messageFile"></constant>
<package name="hyl" extends="struts-default">
<!-- 上传的Action -->
<action name="*UploadAction" class="com.hyl.action.UploadAction"
method="{1}">
<result name="success">/ok.jsp</result>
<result name="input">/index.jsp</result>
<interceptor-ref name="fileUpload">
<param name="allowedTypes">image/jpeg</param>
<param name="maximumSize">102400</param>
</interceptor-ref>
<!-- 这个默认的拦截器必须放在自定义拦截器的下面,否则自定义拦截器不能呗调用 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
<!-- 下载的Action -->
<action name="DownLoadAction" class="com.hyl.action.DownLoadAction">
<result name="success" type="stream">
<!-- 这里显示的指定返回类型,像这种能被浏览器识别的类型会直接显示出来,
如果是其他类型,会以下载形式出现,
如果去掉这个标签,会启用默认的text/plain
-->
<param name="contentType">image/jpeg</param>
<!-- 此处的方法是Action中的getDownLoad方法, -->
<param name="inputName">downLoad</param>
<param name="contentDisposition">filename="${picName}"</param>
<param name="bufferSize">1024</param>
</result>
</action>
</package>
</struts>
UserLoginInterceptor 拦截器类(千万不要写成abstract类,开始我就写成这样了就是加载不上去)
package com.hyl.inter;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import com.hyl.action.UserInfoAction;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class UserLoginInterceptor implements Interceptor {
public void destroy() {
System.out.println("我是登录拦截器销毁");
}
public void init() {
System.out.println("我是登录验证拦截器初始化");
}
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("我正在进行登录拦截功能");
String result = "";
// 判断当前要调用的Action实例(对象) 是否是 登录验证的Action
if (invocation.getAction() instanceof UserInfoAction) {
result = invocation.invoke();
} else {
//当前要调用的不是登录的Action
//从session中取值,判断是否是空(登录)
//登录的Action中将登录用户信息存储到session中,key值是当前的sessionID
HttpServletRequest request = ServletActionContext.getRequest();
Map session = invocation.getInvocationContext().getSession();
if (session.get(request.getSession().getId()) != null) {
result = invocation.invoke();
} else {
//session中如果不存在就跳到登录页面
return "error";
}
}
return result;
}
}
Struts配置文件内容
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<package name="userInfo" namespace="/userInfo" extends="struts-default">
<interceptors>
<interceptor name="userInter" class="com.hyl.inter.UserLoginInterceptor"></interceptor>
<interceptor-stack name="myStack">
<!--加载Struts默认拦截器-->
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="userInter"></interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="myStack"></default-interceptor-ref>
<action name="*userInfoMan" class="com.hyl.action.UserInfoAction" method="{1}">
<result name="success1" type="redirect">/menu.jsp</result>
<result name="error" type="redirect">/user_login.jsp</result>
</action>
</package>
</struts>
以SQLServer为例
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
public class TestCall {
public static void main(String[] args) {
try{
Connection conn=null;
CallableStatement cs=null;
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String url="jdbc:sqlserver://127.0.0.1:1433;databaseName=studentdb";
conn=DriverManager.getConnection(url,"sa","sqlserver");
String sql="{call s_insert(?,?)}";
cs=conn.prepareCall(sql);
cs.setString(1,"张三");
cs.setInt(2, 12);
int num=-1;
num=cs.executeUpdate();
System.out.println("num:"+num);
}catch (Exception e) {
e.printStackTrace();
}
}
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />
<title>Hello, World</title>
<style type="text/css">
html{height:100%}
body{height:100%;margin:0px;padding:0px}
#container{height:70%}
#container{width:50%}
</style>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=1.2"></script>
</head>
<body>
<br><br><br><br><br>
百度地图接口 -- 总结
<br><br>
<div id="container"></div>
<script type="text/javascript">
var map = new BMap.Map("container"); // 创建地图实例
//通过经纬度坐标来初始化地图
var point = new BMap.Point(125.4360909,43.78802888999); // 创建点坐标
map.centerAndZoom(point, 15); // 初始化地图,设置中心点坐标和地图级别
//通过城市名称来初始化地图
//map.centerAndZoom("长春");
var marker = new BMap.Marker(point); // 创建标注
map.addOverlay(marker);
map.enableScrollWheelZoom(); // 开启鼠标滚轮缩放
map.enableKeyboard(); // 开启键盘控制
map.enableContinuousZoom(); // 开启连续缩放效果
map.enableInertialDragging(); // 开启惯性拖拽效果
map.addControl(new BMap.NavigationControl()); //添加标准地图控件(左上角的放大缩小左右拖拽控件)
map.addControl(new BMap.ScaleControl()); //添加比例尺控件(左下角显示的比例尺控件)
map.addControl(new BMap.OverviewMapControl()); // 缩略图控件
map.addControl(new BMap.MapTypeControl()); //// 仅当设置城市信息时,MapTypeControl的切换功能才能可用map.setCurrentCity("北京");
map.setCurrentCity("吉林省");
//添加自定义控件
// 定义一个控件类,即function
function ZoomControl(){
// 设置默认停靠位置和偏移量
this.defaultAnchor = BMAP_ANCHOR_TOP_LEFT;
this.defaultOffset = new BMap.Size(50, 10);
}
// 通过JavaScript的prototype属性继承于BMap.Control
ZoomControl.prototype = new BMap.Control();
// 自定义控件必须实现initialize方法,并且将控件的DOM元素返回
// 在本方法中创建个div元素作为控件的容器,并将其添加到地图容器中
ZoomControl.prototype.initialize = function(map){
// 创建一个DOM元素
var div = document.createElement("div");
// 添加文字说明
div.appendChild(document.createTextNode("长春工业大学人文信息学院"));
// 设置样式
div.style.cursor = "pointer";
div.style.border = "1px solid gray";
div.style.backgroundColor = "white";
// 绑定事件,点击一次放大两级
div.onclick = function(e){
alert("长春工业大学人文信息学院");
}
// 添加DOM元素到地图中
map.getContainer().appendChild(div);
// 将DOM元素返回
return div;
}
// 创建控件实例
var myZoomCtrl = new ZoomControl();
// 添加到地图当中
map.addControl(myZoomCtrl);
//添加信息窗口
var opts = {
width : 200, // 信息窗口宽度
height: 70, // 信息窗口高度
title : "长春工业大学人文信息学院" // 信息窗口标题
}
var infoWindow = new BMap.InfoWindow("您好,欢迎来到长春工业大学人文信息学院", opts); // 创建信息窗口对象
map.openInfoWindow(infoWindow, map.getCenter()); // 打开信息窗口
</script>
</body>
</html>
运行效果图
一、AddUAction
package com;
import java.util.Date;
public class AddUAction {
private Date birdate;
public Date getBirdate() {
return birdate;
}
public void setBirdate(Date birdate) {
this.birdate = birdate;
}
public String addU(){
System.out.println(birdate);
return "ok";
}
}
二、struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "
http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<package name="te" namespace="/te" extends="struts-default">
<action name="teMan" class="com.AddUAction" method="addU">
<result name="ok">/index.jsp</result>
</action>
</package>
</struts>
三、DateConverter
package com;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Map;
import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter;
public class DateConverter extends DefaultTypeConverter {
@Override
public Object convertValue(Map<String, Object> context, Object value,
Class toType) {
SimpleDateFormat dateFormat=new SimpleDateFormat("yyyyMMdd");
try{
if(toType==Date.class){
String[] params=(String[]) value;
return dateFormat.parse(params[0]);
}else{
Date date=(Date) value;
return dateFormat.format(date);
}
}catch (Exception e) {
return null;
}
}
}
四、AddUAction-conversion.properties
birdate=com.DateConverter
五、包结构
六、在地址栏输入
http://localhost:8080/test/te/teMan!addU?birdate=20010205七、结果会在jsp页面显示出来
This is my JSP page.
Mon Feb 05 00:00:00 CST 2001
对数数组中的内容强排序
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class TestComparator {
public static void main(String[] args){
ArrayList list = new ArrayList();
list.add(new Persion("lcl",28));
list.add(new Persion("fx",23));
list.add(new Persion("wqx",29));
Comparator comp = new Comparator(){
public int compare(Object o1,Object o2) {
Persion p1=(Persion)o1;
Persion p2=(Persion)o2;
if(p1.age<p2.age)
return 1;
else
return 0;
}
};
Collections.sort(list,comp);
for(int i=0;i<list.size();i++){
Persion p=(Persion) list.get(i);
System.out.println(p.age+"+"+p.name);
}
}
}
如果在Unity3D中或者Flex中访问tomcat会出现访问协议异常 做下面的配置即可解决
crossdomain.xml 位置 将这两个文件放在tomcat主目录下即 %TOMCAT_HOME%\webapps\ROOT 下可以避免不同项目相互访问资源导致的权限问题。
web访问位置http://your_host:port/crossdomain.xml,成功访问该文件即可。
1.crossdomain.xml
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "./cross-domain-policy.dtd">
<cross-domain-policy> <site-control permitted-cross-domain-policies="all" />
<allow-access-from domain="*" />
<allow-http-request-headers-from domain="*" headers="*"/>
</cross-domain-policy>
2.cross-domain-policy.dtd
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Adobe DTD for cross-domain policy files -->
<!-- Copyright (c) 2008-2009, Adobe Systems Inc. -->
<!ELEMENT cross-domain-policy (site-control?,allow-access-from*,allow-http-request-headers-from*,allow-access-from-identity*)>
<!ELEMENT site-control EMPTY>
<!ATTLIST site-control permitted-cross-domain-policies (all|by-content-type|by-ftp-filename|master-only|none) #REQUIRED>
<!ELEMENT allow-access-from EMPTY>
<!ATTLIST allow-access-from domain CDATA #REQUIRED>
<!ATTLIST allow-access-from to-ports CDATA #IMPLIED>
<!ATTLIST allow-access-from secure (true|false) "true">
<!ELEMENT allow-http-request-headers-from EMPTY>
<!ATTLIST allow-http-request-headers-from domain CDATA #REQUIRED>
<!ATTLIST allow-http-request-headers-from headers CDATA #REQUIRED>
<!ATTLIST allow-http-request-headers-from secure (true|false) "true">
<!ELEMENT allow-access-from-identity (signatory)>
<!ELEMENT signatory (certificate)>
<!ELEMENT certificate EMPTY>
<!ATTLIST certificate fingerprint CDATA #REQUIRED>
<!ATTLIST certificate fingerprint-algorithm CDATA #REQUIRED>
<!-- End of file. -->
本文讲述Hibernate的generator属性的意义。Generator属性有7种class,本文简略描述了这7种class的意义和用法。
- <class name="onlyfun.caterpillar.User"
- table="USER">
- <id name="id" type="string" unsaved-value="null">
- <column name="USER_ID"/>
- <generator class="uuid.hex"/>
- </id>
- </class>
Hibernate的Generator属性有7种class,本文简略描述了这7种class的意义和用法。
1、identity:用于MySql数据库。特点:递增
- <id name="id" column="id">
- < generator class="identity"/>
- </id>
注:对于MySql数据库使用递增序列时需要在建表时对主键指定为auto_increment属性。
2、sequence:用于Oracle数据库
- <id name="id" column="id">
- <generator class="sequence">
- <param name="sequence">序列名</param>
- </generator>
- </id>
3、native:跨数据库时使用,由底层方言产生。
Default.sequence为hibernate_sequence
- <id name="id" column="id">
- <generator class="native"/>
- </id>
注:使用native时Hibernate默认会去查找Oracle中的hibernate_sequence序列。
如果Oracle中没有该序列,连Oracle数据库时会报错。
4、hilo:通过高低位合成id,先建表hi_value,再建列next_value。必须要有初始值。
- <id name="id" column="id">
- <generator class="hilo">
- <param name="table">high_val</param>
- <param name="column">nextval</param>
- <param name="max_lo">5</param>
- </generator>
- </id>
5、sequencehilo:同过高低位合成id,建一个sequence序列,不用建表。
- <id name="id" column="id">
- <generator class="hilo">
- <param name="sequence">high_val_seq</param>
- <param name="max_lo">5</param>
- </generator>
- </id>
6、assigned:用户自定义id;
- <id name="id" column="id">
- <generator class="assigned"/>
- </id>
7、foreign:用于一对一关系共享主健时,两id值一样。
本文讲解Hibernate中hbm的generator子元素的一些内置生成器的快捷名字。Generator子元素是一个非常简单的接口;某些应用程序可以选择提供他们自己特定的实现。
在*.hbm.xml必须声明的< generator>子元素是一个Java类的名字,用来为该持久化类的实例生成唯一的标识。
- <generator class="sequence"/>
这是一个非常简单的接口;某些应用程序可以选择提供他们自己特定的实现。当然,Hibernate提供了很多内置的实现。下面是Generator子元素的一些内置生成器的快捷名字:
increment(递增)
用于为long, short或者int类型生成唯一标识。只有在没有其他进程往同一张表中插入数据时才能使用。 在集群下不要使用。
identity
对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持。返回的标识符是long, short 或者int类型的。
sequence (序列)
在DB2,PostgreSQL, Oracle, SAP DB, McKoi中使用序列(sequence),而在Interbase中使用生成器(generator)。返回的标识符是long, short或者 int类型的。
hilo (高低位)
使用一个高/低位算法来高效的生成long, short或者 int类型的标识符。给定一个表和字段(默认分别是是hibernate_unique_key 和next_hi)作为高位值得来源。高/低位算法生成的标识符只在一个特定的数据库中是唯一的。在使用JTA获得的连接或者用户自行提供的连接中,不要使用这种生成器。
seqhilo(使用序列的高低位)
使用一个高/低位算法来高效的生成long, short或者 int类型的标识符,给定一个数据库序列(sequence)的名字。
uuid.hex
用一个128-bit的UUID算法生成字符串类型的标识符。在一个网络中唯一(使用了IP地址)。UUID被编码为一个32位16进制数字的字符串。
uuid.string
使用同样的UUID算法。UUID被编码为一个16个字符长的任意ASCII字符组成的字符串。不能使用在PostgreSQL数据库中
native(本地)
根据底层数据库的能力选择identity, sequence 或者hilo中的一个。
assigned(程序设置)
让应用程序在save()之前为对象分配一个标示符。
foreign(外部引用)
使用另外一个相关联的对象的标识符。和< one-to-one>联合一起使用。
Generator子元素的用法:
- <class name="onlyfun.caterpillar.User" table="USER">
- <id name="id" type="string" unsaved-value="null">
- <column name="USER_ID"/>
- <generator class="uuid.hex"/>
- </id>
- </class>
index当前这次迭代从 0 开始的迭代索引
count当前这次迭代从 1 开始的迭代计数
first用来表明当前这轮迭代是否为第一次迭代的标志
last用来表明当前这轮迭代是否为最后一次迭代的标志
begin属性值
end属性值
step属性值
例:
表格偶数行与奇数行颜色交替效果
引标签库
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<c:forEach items="${queryPromotionList}" var="vPromotion" varStatus="vstatus">
<c:choose>
<c:when test="${vstatus.index%2==0}">
<tr bgcolor="#FFFFFF" height="40">
</c:when>
<c:otherwise>
<tr bgcolor="#F3F3F5" height="40">
</c:otherwise>
</c:choose>
<table class=table_body_bg cellspacing=1 cellpadding=1
width="100%" align=center border=0>
<c:forEach items="${list}" var="a" varStatus="vs">
<c:if test="${vs.count%5==1}">
<tr align="left" height="20">
</c:if>
<td class=table_body_td width="20%"><a href="/aam/degree/advisorAnswer.do?sfid=${a.sfid }">${a.xm }(${a.sfid })</a></td>
<c:set var="count" value="${vs.count}"/> //${vs.count}只在<c:forEach></c:forEach>的范围内有值 外部引用需要把值传出去
</c:forEach>
<c:if test="${count%5==1}">
<td class="table_body_td" width="20%"></td>
<td class="table_body_td" width="20%"></td>
<td class="table_body_td" width="20%"></td>
<td class="table_body_td" width="20%"></td>
</tr>
</c:if>
<c:if test="${count%5==2}">
<td class="table_body_td" width="20%"></td>
<td class="table_body_td" width="20%"></td>
<td class="table_body_td" width="20%"></td>
</tr>
</c:if>
<c:if test="${count%5==3}">
<td class="table_body_td" width="20%"></td>
<td class="table_body_td" width="20%"></td>
</tr>
</c:if>
<c:if test="${count%5==4}">
<td class="table_body_td" width="20%"></td>
</tr>
</c:if>
<c:if test="${count%5==0}">
</tr>
</c:if>
</table>
不论是对整数还是对集合进行迭代, <c:forEach>
剩余的属性 varStatus
所起的作用相同。和 var
属性一样, varStatus
用于创建限定了作用域的变量。不过,由 varStatus
属性命名的变量并不存储当前索引值或当前元素,而是赋予 javax.servlet.jsp.jstl.core.LoopTagStatus
类的实例。该类定义了一组特性,它们描述了迭代的当前状态,下面列出了这些特性:
特性 |
Getter |
描述 |
current |
getCurrent() |
当前这次迭代的(集合中的)项 |
index |
getIndex() |
当前这次迭代从 0 开始的迭代索引 |
count |
getCount() |
当前这次迭代从 1 开始的迭代计数 |
first |
isFirst() |
用来表明当前这轮迭代是否为第一次迭代的标志 |
last |
isLast() |
用来表明当前这轮迭代是否为最后一次迭代的标志 |
begin |
getBegin() |
begin 属性值 |
end |
getEnd() |
end 属性值 |
step |
getStep() |
step 属性值 |
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* 用户数据库访问的类
*@作者Administrator
*@createTime 2011-12-5 上午11:55:18
*@version 1.0
*/
public class DButil1 {
private Connection conn;
private Statement st;
private PreparedStatement pps;
private ResultSet rs;
public String url="jdbc:oracle:thin:@localhost:1521:orcl";
private String user="hyl";
private String password="hyl";
//加载驱动、放在静态代码块中,保证驱动在整个项目中只加载一次,提高效率
static{
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取连接的方法
* @return Connection 一个有效的数据库连接
*/
public Connection getConnection()
{
try {
//注意链接时,要换成自己的数据库名,数据库用户名及密码
Connection con=DriverManager.getConnection(url,user,password);
return con;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/**
* 用于执行更新的方法,包括(insert delete update)操作
* @param sql String 类型的SQL语句
* @return Integer 表示受影响的行数
*/
public int update(String sql)
{
//定义变量用来判断更新操作是否成功,如果返回-1说明没有影响到更新操作的数据库记录条数,即更新操作失败
int row=-1;
try {
//如果数据库链接被关闭了,就要既得一个新的链接
if(conn==null||conn.isClosed()){
conn=getConnection();
}
//使用Connection对象conn的createStatement()创建Statement(数据库语句对象)st
st=conn.createStatement();
//执行更新操作,返回影响的记录条数row
row=st.executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
}
finally{
close();
}
return row;
}
/**
* 基于PreparedStatement的修改方法 PreparedStatement:表示预编译的 SQL 语句的对象
* @param sql String 类型的SQL语句(insert delete update)
* @param obj 存放动态参数的数组
* @return Integer 表示受影响的行数
*/
public int update(String sql,Object ...obj)
{
try {
//获取链接
if(conn==null||conn.isClosed()){
conn=getConnection();
}
//创建预编译的 SQL 语句对象
pps=conn.prepareStatement(sql);
//定义变量length代表数组长度,也就是预处理的sql语句中的参数个数
int length=0;
//ParameterMetaData:用于获取关于 PreparedStatement 对象中每个参数的类型和属性信息的对象
ParameterMetaData pmd=pps.getParameterMetaData();
length=pmd.getParameterCount();
//循环将sql语句中的?设置为obj数组中对应的值,注意从1开始,所以i要加1
for(int i=0;i<length;i++)
{
pps.setObject(i+1, obj[i]);
}
//执行更新操作
return pps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally{
close();
}
return -1;
}
/**
* 获取一条记录的方法,要依赖于下面的queryToList方法,注意泛型的使用
* @param sql
* @return Map<String,Object>
*/
public Map<String,Object> getOneRow(String sql)
{
//执行下面的queryToList方法
List<Map<String,Object>> list=queryToList(sql);
//三目运算,查询结果list不为空返回list中第一个对象,否则返回null
return list.size()>0?list.get(0):null;
}
/**
* 返回查询结果列表,形如:[{TEST_NAME=aaa, TEST_NO=2, TEST_PWD=aaa}, {TEST_NAME=bbb, TEST_NO=3, TEST_PWD=bbb}...]
* @param sql
* @return List<Map<String,Object>>
*/
public List<Map<String,Object>> queryToList(String sql)
{
//创建集合列表用以保存所有查询到的记录
List<Map<String, Object>> list=new LinkedList<Map<String, Object>>();
try {
if(conn==null||conn.isClosed()){
conn=getConnection();
}
st=conn.createStatement();
rs=st.executeQuery(sql);
//ResultSetMetaData 是结果集元数据,可获取关于 ResultSet 对象中列的类型和属性信息的对象 例如:结果集中共包括多少列,每列的名称和类型等信息
ResultSetMetaData rsmd=rs.getMetaData();
//获取结果集中的列数
int columncount=rsmd.getColumnCount();
//while条件成立表明结果集中存在数据
while(rs.next())
{
//创建一个HashMap用于存储一条数据
HashMap<String, Object> onerow=new HashMap<String, Object>();
//循环获取结果集中的列名及列名所对应的值,每次循环都得到一个对象,形如:{TEST_NAME=aaa, TEST_NO=2, TEST_PWD=aaa}
for(int i=0;i<columncount;i++)
{
//获取指定列的名称,注意orcle中列名的大小写
String columnName=rsmd.getColumnName(i+1);
onerow.put(columnName, rs.getObject(i+1));
}
//将获取到的对象onewrow={TEST_NAME=aaa, TEST_NO=2, TEST_PWD=aaa}放到集合列表中
list.add(onerow);
}
}catch (SQLException e) {
e.printStackTrace();
}
finally{
close();
}
return list;
}
/**
* 返回查询结果列表,使用的是预编绎SQL 语句对象PreparedStatement
* 形如:[{TEST_NAME=aaa, TEST_NO=2, TEST_PWD=aaa}, {TEST_NAME=bbb, TEST_NO=3, TEST_PWD=bbb}]
* @param sql
* @param paramValues
* @return List<Map<String,Object>>
*/
public List<Map<String,Object>> queryWithParam(String sql,Object ...paramValues){
//创建集合列表用以保存所有查询到的记录
List<Map<String, Object>> list=new LinkedList<Map<String, Object>>();
try {
if(conn==null||conn.isClosed()){
conn=getConnection();
}
pps = conn.prepareStatement(sql);
for (int i = 0; i < paramValues.length; i++) {
pps.setObject(i + 1, paramValues[i]);
}
rs = pps.executeQuery();
//ResultSetMetaData 是结果集元数据,可获取关于 ResultSet 对象中列的类型和属性信息的对象 例如:结果集中共包括多少列,每列的名称和类型等信息
ResultSetMetaData rsmd=rs.getMetaData();
//获取结果集中的列数
int columncount=rsmd.getColumnCount();
//while条件成立表明结果集中存在数据
while (rs.next()) {
//创建一个HashMap用于存储一条数据
HashMap<String, Object> onerow=new HashMap<String, Object>();
//循环获取结果集中的列名及列名所对应的值,每次循环都得到一个对象,形如:{TEST_NAME=aaa, TEST_NO=2, TEST_PWD=aaa}
for(int i=0;i<columncount;i++)
{
//获取指定列的名称,注意orcle中列名的大小写
String columnName=rsmd.getColumnName(i+1);
onerow.put(columnName, rs.getObject(i+1));
}
//将获取到的对象onewrow={TEST_NAME=aaa, TEST_NO=2, TEST_PWD=aaa}放到集合列表中
list.add(onerow);
}
}catch (SQLException e) {
e.printStackTrace();
}
finally{
close();
}
return list;
}
/**
* 实现oracle分页功能
* @param sql
* @param pagesize
* @param pagenow
* @return PageBean
*/
public PageBean getPage(String sql,int pagesize,int pagenow)
{
PageBean pb=new PageBean();
int end=pagenow*pagesize;
int start=end-pagesize+1;
String exesql="select a.* from (select t.*,rownum as rowindex from ("+sql+") t where rownum<="+end+" ) a where a.rowindex>="+start;
String countsql="select count(*) as rowcount from ("+sql+")";
pb.setResult(queryToList(exesql));
pb.setPagenow(pagenow);
pb.setPagesize(pagesize);
Map<String,Object> map=this.getOneRow(countsql);
int rows=Integer.parseInt(map.get("ROWCOUNT").toString());
pb.setRows(rows);
int pages=rows%pagesize==0?rows/pagesize:rows/pagesize+1;
pb.setPages(pages);
pb.setSql(sql);
return pb;
}
/**
* 关闭数据库各种资源Connection Statement PreparedStatement ResultSet的方法
*/
private void close()
{
if(rs!=null)
{
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(st!=null)
{
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(pps!=null){
try {
pps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
try {
if(conn!=null&&!conn.isClosed())
{
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
首先写一个计数的类OnlineCounter
package accp.onlinecounter;
public class OnlineCounter {
private static long online = 0;
public static long getOnline() {
return online;
}
public static void raise() {
online++;
}
public static void reduce() {
online--;
}
}
之后写一个实现HttpSessionEvent的类OnlineCounterListener
package accp.onlinecounter;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class OnlineCounterListener implements HttpSessionListener {
public void sessionCreated(HttpSessionEvent hse) {
OnlineCounter.raise();
}
public void sessionDestroyed(HttpSessionEvent hse) {
OnlineCounter.reduce();
}
}
在web.xml中写listener的注册信息
<listener>
<listener-class>
accp.onlinecounter.OnlineCounterListener
</listener-class>
</listener>
前台界面写上
<body>
在线人数: <%=OnlineCounter.getOnline() %><br/>
<a href="adcourse.jsp">添加课程add course</a><br/>
<a href="adds.jsp">添加学生add stu</a><br/>
<a href="findallcourse.jsp">查询课程信息 select course</a><br/>
<a href="findallstudent.jsp">查询学生信息 select student</a><br/>
<a href="addstudentcourse.jsp">添加选课信息add student course</a><br/>
<a href="querystucourse.jsp">查询选课信息query student course</a><br/>
</body>
注意引入包即可
方法一、 解决的办法自然是用相对路径代替绝对路径,其实log4j的FileAppender本身就有这样的机制,如:log4j.appender.logfile.File=${WORKDIR}/logs/app.log
其中“${WORKDIR}/”是个变量,会被System Property中的“WORKDIR”的值代替。这样,我们就可以在log4j加载配置文件之前,先用System.setProperty ("WORKDIR", WORKDIR);设置好根路径,此操作可通过一初始的servlet进行。
方法二、可以使用服务器环境变量
log4j的配置文件支持服务器的vm的环境变量,格式类似${catalina.home}
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=${catalina.home}/logs/logs_tomcat.log
log4j.appender.R.MaxFileSize=10KB
其中的${catalina.home}并非windows系统的环境变量,这个环境变量就不需要在Windows系统的环境变量中设置。之所以这样,你可以看看tomcat\bin\catalina.bat(startup,shutdown都是调用这个)里面自带有-Dcatalina.home= "%CATALINA_HOME%" 。继承这个思想,所以你也可以自己设定一个参数-Dmylog.home="D:/abc/log"到对应的服务器java启动的vm参数中
方法三、通过servlet初始化init()方法中加载file属性实现相对路径
具体实现:做一个servlet,在系统加载的时候,就把properties的文件读到一个properties文件中.那个file的属性值(我使用的是相对目录)改掉(前面加上系统的根目录),让后把这个properties对象设置到propertyConfig中去,这样就初始化了log的设置.在后面的使用中就用不着再配置了
一般在我们开发项目过程中,log4j日志输出路径固定到某个文件夹,这样如果我换一个环境,日志路径又需要重新修改,比较不方便,目前我采用了动态改变日志路径方法来实现相对路径保存日志文件
(1).在项目启动时,装入初始化类:
public class Log4jInit extends HttpServlet {
static Logger logger = Logger.getLogger(Log4jInit.class);
public Log4jInit() {
}
public void init(ServletConfig config) throws ServletException {
String prefix = config.getServletContext().getRealPath("/");
String file = config.getInitParameter("log4j");
String filePath = prefix + file;
Properties props = new Properties();
try {
FileInputStream istream = new FileInputStream(filePath);
props.load(istream);
istream.close();
//toPrint(props.getProperty("log4j.appender.file.File"));
String logFile = prefix + props.getProperty("log4j.appender.file.File");//设置路径
props.setProperty("log4j.appender.file.File",logFile);
PropertyConfigurator.configure(props);//装入log4j配置信息
} catch (IOException e) {
toPrint("Could not read configuration file [" + filePath + "].");
toPrint("Ignoring configuration file [" + filePath + "].");
return;
}
}
public static void toPrint(String content) {
System.out.println(content);
}
}
实际上log4j的配置文件log4j.properties如为默认名,可放置在JVM能读到的classpath里的任意地方,一般是放在WEB- INF/classes目录下。当log4j的配置文件不再是默认名,则需要另外加载并给出参数,如上 “ropertyConfigurator.configure(props);//装入log4j配置信息”
(2).Web.xml中的配置
<servlet>
<servlet-name>log4j-init</servlet-name>
<servlet-class>Log4jInit</servlet-class>
<init-param>
<param-name>log4j</param-name>
<param-value>WEB-INF/classes/log4j.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
注意:上面的load-on-startup设为0,以便在Web容器启动时即装入该Servlet。log4j.properties文件放在根的properties子目录中,也可以把它放在其它目录中。应该把.properties文件集中存放,这样方便管理。
(3).log4j.properties中即可配置log4j.appender.file.File为当前应用的相对路径.
以上是网上log4j日志文件的相对路径配置的三种方法(我能找到的就三种),分析:
方法一主要是扩展了log4j的RollingFileAppender类,其他的FileAppender同样道理。扩展的方法,就是用一个子类去覆盖setFile方法,这个方法在log4j读取配置文件生成appender的时候调用,传入的就是配
置文件中的路径,这样我就可以按照自己的想法在路径前面加上根路径了。这种方法可以在log4j.properties中用相对路径自由配置log4j.appender.A1.File属性来决定生成的日志相对web应用根
目录的位置。
方法二是利用服务器vm中已经存在的环境变量如${catalina.home}来设置相对于${catalina.home}的日志路径,日志只能放到服务器子目录里,而且如果是用的其它服务器,则要改对应的环境变量。此方法平台移植不方便。
方法三是扩展ActionServlet类,覆盖其init()方法,新方法中载入log4j.properties位置的参数,可以自由配置log4j的配置文件的名字和存放位置。也可自由配置log4j日志文件的相对于当前应用的路径。详
细代码如下:
程序代码
package wbb.bysxxglxt.util;
import org.apache.struts.action.*;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;
import javax.servlet.ServletException;
import java.util.Properties;
import java.io.InputStream;
import org.apache.log4j.PropertyConfigurator;
import java.io.FileInputStream;
import java.io.IOException;
public class ExtendedActionServlet extends ActionServlet {
private Log log = LogFactory.getLog(this.getClass().getName());
public ExtendedActionServlet() {}
public void init() throws ServletException {
log.info(
"Initializing, My MyActionServlet init this System's Const Variable");
String prefix = this.getServletConfig().getServletContext().getRealPath(
"/");
String file = this.getServletConfig().getInitParameter("log4j");
String filePath = prefix + file;
Properties props = new Properties();
System.out.println(prefix);
System.out.println(file);
System.out.println(filePath);
try {
FileInputStream log4jStream = new FileInputStream(filePath);
props.load(log4jStream);
log4jStream.close();
String logFile = prefix +
props.getProperty("log4j.appender.A1.File"); //设置路径
System.out.println(logFile);
props.setProperty("log4j.appender.A1.File", logFile);
PropertyConfigurator.configure(props); //装入log4j配置信息
} catch (IOException e) {
e.printStackTrace();
}
log.info("Initializing, end My Init");
super.init();//应用了struts,此方法不能省,ActionServlet覆盖了的此方法中有很多重要操作
}
}
**********************应用web.xml 关键部分***************************
程序代码
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>wbb.bysxxglxt.util.ExtendedActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>log4j</param-name>
<param-value>properties\log4j.properties</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>application</param-name>
<param-value>ApplicationResources</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
注意log4j参数中相对路径的斜杠线的写法,而且log4j属性文件如放置在web-inf/classes目录或web-inf等目录中最好改名,因为在加载此Servlet之前,服务器如tomcat启动时会自动搜索web-inf目录和web-inf/classes目录中log4j.properties文件,如有则自动加载。log4j属性文件加载后,由于该属性文件中log4j.appender.A1.File的值用的是相对路径,自动加载配置便会出错:
log4j:ERROR setFile(null,true) call failed.
java.io.FileNotFoundException: WEB-INF\logs\bysxxglxt.log (系统找不到指定的路径。)
不知道log4j为什么会这么早自动启动。尽管后面加载扩展的ActionServlet中正确设置了log4j属性文件并正常加载了,但报的这个错还是怪不爽的,于是只有更改log4j属性文件名字或者更改其存放位置,让其不能自动加载了,不过还是有两个警告:
log4j:WARN No appenders could be found for logger (org.apache.commons.digester.Digester.sax).
log4j:WARN Please initialize the log4j system properly.
这样做就算是掩耳盗铃了,如果你有更好的解决办法,希望能在此贴出来,大家一起研究。
********************log4j.properties*****************************
### 设置logger级别 ###
程序代码
log4j.rootLogger=DEBUG,stdout,A1
### appender.stdout输出到控制台 ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern= [%5p] [BYSXXGLXT] %d{yyyy-MM-dd HH:mm:ss}: %-4r [%-5p] [%t] ( %F,%L ) - %m%n
### appender.A1输出到日志文件 ###
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=WEB-INF\\logs\\bysxxglxt.log
##注意上面日志文件相对应用根目录路径的写法
log4j.appender.A1.DatePattern='.'yyyy-MM-dd'.log'
log4j.appender.A1.Append=true
## 输出DEBUG级别以上的日志
log4j.appender.A1.Threshold=DEBUG
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern= [%5p] [BYSXXGLXT] %d{yyyy-MM-dd HH:mm:ss}: %-4r [%t] ( %F,%L ) - %m%n
首先导入两个包: commons-logging.jar log4j-1.2.12.jar
在src下编写3个 properties文件
1.log4j.properties 下面是内容
##LOGGERS
#define a logger
log4j.rootLogger=INFO,console,file
##APPENDERS
#define an appender named console
log4j.appender.console=org.apache.log4j.ConsoleAppender
#define an appender named file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=d:/demo_log.txt
#set the log's size
log4j.appender.file.MaxFileSize=1000KB
log4j.appender.file.MaxBackupIndex=20
##LAYOUTS
#assign a SimpleLayout to console appender
log4j.appender.console.layout=org.apache.log4j.SimpleLayout
#assign a PatternLayout to file appender
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%-5p][%d{yyyy-MM-dd HH:mm:ss}]%m%n
2.
simplelog.properties下面是内容
log.apache.commons.logging.simplelog.defaultlog=info
3.
commons-logging.properties下面是内容
##set Log as Log4J
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
一、什么是log4j
Log4j 是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
二、日志简介
日志指在程序中插入语句以提供调试信息。使用日志能够监视程序的执行。例如,用户利用日志可以获得关于应用程序故障的完整信息。用户可以将调试语句(如 System.out.println)插入到程序中以获得详细的调试信息。
三、项目中为什么要用log4j
大家在编程时经常不可避免地要使用到一些日志操作,比如开发阶段的调试信息、运行时的日志记录及审计。调查显示,日志代码占代码总量的4%。通常大家可以简单地使用System.out.println()语句输出日志信息,但是往往会有一些判断,比如:
if (someCondition)
{
System.out.println("some information.");
}
这些判断造成正常的程序逻辑中混杂了大量的输出语句。而在开发阶段写下的这些判断仅为了调试的语句,在开发完成时需要查找并移除。部署运行后,尤其是在一些企业应用系统中,还经常需要进一步调试,这时就遇到了更大的麻烦。所以,我们需要一套完备的、灵活的、可配置的日志工具log4J就是优秀的选择。
四、log4j组件
Log4j 由 logger、appender 和 layout 三个组件组成。可以通过同名的 Java 类访问 Log4j 的这三个组件。
Logger - 在执行应用程序时,接收日志语句生成的日志请求。它是一种重要的日志处理组件, 可以通过 log4j API 的 logger 类对其进行访问。它的方法有:debug、info、warn、error、fatal 和 log。这些方法用于记录消息。
Appender - 管理日志语句的输出结果。执行日志语句时,Logger 对象将接收来自日志语句的记录请求。此请求是通过 logger 发送至 appender 的。然后,Appender 将输出结果写入到用户选择的目的地。对于不同的日志目的地,提供不同的 appender 类型。这些 appender 包括:用于文件的 file appender、用于数据库的 JDBC appender 和用于 SMTP 服务器的 SMTP appender。
Layout - 用于指定 appender 将日志语句写入日志目的地所采用的格式。appender 可以用来格式化输出结果的各种布局包括:简单布局、模式布局和 HTML 布局。
触发器
是一种特殊的存储过程﹐它不能被显式地调用﹐而是在往表中插入记录﹑更新记录或者删除记录时被自动地激活。所以触发器可以用来实现对表实施复杂的完整性约束。
二: SQL Server为每个触发器都创建了两个专用表:Inserted表和Deleted表。这两个表。 一: 触发器是一种特殊的存储过程﹐它不能被显式地调用﹐而是在往表中插入记录﹑更新记录或者删除记录时被自动地激活。所以触发器可以用来实现对表实施复杂的完整性约`束。
二: SQL Server为每个触发器都创建了两个专用表:Inserted表和Deleted表。这两个表由系统来维护﹐它们存在于内存中而不是在数据库中。这两个表的结构总是与被该触发器作用的表的结构相同。触发器执行 完成后﹐与该触发器相关的这两个表也被删除。
Deleted表存放由于执行Delete或Update语句而要从表中删除的所有行。
Inserted表存放由于执行Insert或Update语句而要向表中插入的所有行。
三:Instead of 和 After触发器
SQL Server2000提供了两种触发器:Instead of 和After 触发器。这两种触发器的差别在于他们被激活的同:
Instead of触发器用于替代引起触发器执行的T-SQL语句。除表之外﹐Instead of 触发器也可以用于视图﹐用来扩展视图可以支持的更新操作。
After触发器在一个Insert,Update或Deleted语句之后执行﹐进行约束检查等动作都在After触发器被激活之前发生。After触发器只能用于表。
一个表或视图的每一个修改动作(insert,update和delete)都可以有一个instead of 触发器﹐一个表的每个修改动作都可以有多个After触发器。
四:触发器的执行过程
如果一个Insert﹑update或者delete语句违反了约束﹐那幺After触发器不会执行﹐因为对约束的检查是在After触发器被激动之前发生的。所以After触发器不能超越约束。
Instead of 触发器可以取代激发它的操作来执行。它在Inserted表和Deleted表刚刚建立﹐其它任何操作还没有发生时被执行。因为Instead of 触发器在约束之前执行﹐所以它可以对约束进行一些预处理。
五:使用T-SQL语句来创建触发器 基本语句如下:
create trigger trigger_name
on {table_name view_name}
{for After Instead of }
[ insert, update,delete ]
as
sql_statement
六:删除触发器:
基本语句如下:
drop trigger trigger_name
七:查看数据库中已有触发器:
-- 查看数据库已有触发器
use jxcSoftware
go
select * from sysobjects where xtype='TR'
-- 查看单个触发器
exec sp_helptext '触发器名'
八:修改触发器: 基本语句如下:
alter trigger trigger_name
on {table_name view_name}
{for After Instead of }
[ insert, update,delete ]
as
sql_statement
九:相关示例: 1:在Orders表中建立触发器﹐当向Orders表中插入一条订单记录时﹐检查goods表的货品状态status是否为1(正在整理)﹐是﹐则不能往Orders表加入该订单。
create trigger orderinsert
on orders
after insert
as
if (select status from goods,inserted
where goods.name=inserted.goodsname)=1
begin
print 'the goods is being processed'
print 'the order cannot be committed'
rollback transaction --回滚﹐避免加入
end
2:在Orders表建立一个插入触发器﹐在添加一条订单时﹐减少Goods表相应的货品记录中的库存。
create trigger orderinsert1
on orders
after insert
as
update goods set storage=storage-inserted.quantity
from goods,inserted
where
goods.name=inserted.goodsname
3:在Goods表建立删除触发器﹐实现Goods表和Orders表的级联删除。
create trigger goodsdelete
on goods
after delete
as
delete from orders
where goodsname in
(select name from deleted)
4:在Orders表建立一个更新触发器﹐监视Orders表的订单日期(OrderDate)列﹐使其不能手工修改.
create trigger orderdateupdate
on orders
after update
as
if update(orderdate)
begin
raiserror(' orderdate cannot be modified',10,1)
rollback transaction
end
5:在Orders表建立一个插入触发器﹐保证向Orders表插入的货品名必须要在Goods表中一定存在。
create trigger orderinsert3
on orders
after insert
as
if (select count(*) from goods,inserted where goods.name=inserted.goodsname)=0
begin
print ' no entry in goods for this order'
rollback transaction
end
6:Orders表建立一个插入触发器,保证向Orders表插入的货品信息要在Order表中添加
alter trigger addOrder
on Orders
for insert
as
insert into Order
select inserted.Id, inserted.goodName,inserted.Number from inserted