風(fēng)人園

          弱水三千,只取一瓢,便能解渴;佛法無邊,奉行一法,便能得益。
          隨筆 - 99, 文章 - 181, 評論 - 56, 引用 - 0
          數(shù)據(jù)加載中……

          2009年8月21日

          Spring boot+Spring Security 4配置整合實(shí)例

          http://blog.csdn.net/code__code/article/details/53885510

          1. 使用Spring Security管理用戶身份認(rèn)證、登錄退出

          2. 用戶密碼加密及驗(yàn)證

          3. 采用數(shù)據(jù)庫的方式實(shí)現(xiàn)Spring Securityremember-me功能

          4. 獲取登錄用戶信息。

          5.使用Spring Security管理url和權(quán)限

          posted @ 2018-03-19 21:02 風(fēng)人園 閱讀(318) | 評論 (0)編輯 收藏

          spring security 參數(shù)配置

               摘要:         // 自定義登錄頁面          http.csrf().disable().formLogin().loginPage("/login")  //指定登錄頁的路徑&n...  閱讀全文

          posted @ 2018-03-19 20:33 風(fēng)人園 閱讀(434) | 評論 (0)編輯 收藏

          spring quartz 串行配置

          <bean id="jobDetail7"class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">

                             <propertyname="targetObject" ref="billingBillTask"></property>

                             <propertyname="targetMethod" value="executeInternal" />

                             <propertyname="concurrent" value="false" />

                   </bean>

                   <beanid="billingBillTask"class="com.dangdang.tms.job.schedule.bms.BillingBillTask"/>

                   <beanid="cronTriggerBean7" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">

                             <propertyname="jobDetail" ref="jobDetail7"></property>

                             <propertyname="cronExpression" value="0/5 * * * * ?"></property>

                   </bean>

          參考 http://blog.csdn.net/lkforce/article/details/51841890

          posted @ 2018-03-12 19:58 風(fēng)人園 閱讀(388) | 評論 (0)編輯 收藏

          spring 3.0 async 異步方法 設(shè)置

          為了解決一些比較費(fèi)時且不是很緊要的任務(wù),將此任務(wù)轉(zhuǎn)為異步任務(wù)處理,提高前端操作體驗(yàn)。 spring 中 自帶注解 @Async. 配置如下 applicationContext.xml 中 增加 task的引用 如上配置之后,只需要在 需要進(jìn)行異步調(diào)用的方法前面增加 注解就可以了。 @Async public void updateOrderBillItemPQty(String deptId, String orderNo, Integer orderItemSid, Double pQty) { 注:需要注意,同一個對象里面方法調(diào)用,不會作為異步方法執(zhí)行。

          posted @ 2017-05-24 14:27 風(fēng)人園 閱讀(263) | 評論 (0)編輯 收藏

          android ResourceNotFoundException


          在對 TextView 或者 EditText 進(jìn)行賦值時,調(diào)用setText()方法,一定要注意,使用String類型,不要使用int 或者long,否則 會出現(xiàn)找不到資源的異常。系統(tǒng)自動會將int作為一個資源ID,然后去R 里面找,結(jié)果找不到。

          posted @ 2016-12-21 20:48 風(fēng)人園 閱讀(136) | 評論 (0)編輯 收藏

          android 系統(tǒng)提示對話框(AlertDialog)的使用(zt)

               摘要: http://blog.csdn.net/meng425841867/article/details/8523730 在按鍵單擊事件中添加創(chuàng)建對話框并設(shè)置相關(guān)屬性。        [java] view plain copy dialogButton=(Button)findViewBy...  閱讀全文

          posted @ 2016-12-02 12:54 風(fēng)人園 閱讀(476) | 評論 (0)編輯 收藏

          Android 自定義ListView adapter(zt)

               摘要: http://daoshud1.iteye.com/blog/1874241 本文講實(shí)現(xiàn)一個自定義列表的Android程序,程序?qū)?shí)現(xiàn)一個使用自定義的適配器(Adapter)綁定 數(shù)據(jù),通過contextView.setTag綁定數(shù)據(jù)有按鈕的ListView。 系統(tǒng)顯示列表(ListView)時,首先會實(shí)例化一個適配器,本文將實(shí)例化一個自定義的適配器。實(shí)現(xiàn) 自定義適...  閱讀全文

          posted @ 2016-12-01 13:13 風(fēng)人園 閱讀(168) | 評論 (0)編輯 收藏

          Android之SimpleAdapter簡單實(shí)例和SimpleAdapter參數(shù)說明(zt)

               摘要: http://blog.csdn.net/x605940745/article/details/11981049 SimpleAdapter的參數(shù)說明 第一個參數(shù) 表示訪問整個android應(yīng)用程序接口,基本上所有的組件都需要 第二個參數(shù)表示生成一個Map(String ,Object)列表選項(xiàng) 第三個參數(shù)表示界面布局的id  表示該文件作為列表項(xiàng)的組件&...  閱讀全文

          posted @ 2016-12-01 13:12 風(fēng)人園 閱讀(184) | 評論 (0)編輯 收藏

          android開發(fā)教程之listview使用方法

          首先是布局文件,這里需要兩個布局文件,一個是放置列表控件的Activity對應(yīng)的布局文件 main.xml,另一個是ListView中每一行信息顯示所對應(yīng)的布局 list_item.xml 這一步需要注意的問題是ListView 控件的id要使用Android系統(tǒng)內(nèi)置的 android:id="@android:id/list"

          main.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" >
                  
          <ListView 
                  
          android:id="@android:id/list"
                  android:layout_width
          ="match_parent"
                  android:layout_height
          ="match_parent"
                  android:padding
          ="20dip"/>
          </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" >

          <TextView
          android:id="@+id/user_name"
          android:layout_width
          ="match_parent"
          android:layout_height
          ="match_parent"
          android:layout_weight
          ="1"/>
          <TextView
          android:id="@+id/user_id"
          android:layout_width
          ="match_parent"
          android:layout_height
          ="match_parent"
          android:layout_weight
          ="1"/>
          </LinearLayout>


          然后就設(shè)置MainActivity中的代碼了:基本思想就是先將數(shù)據(jù)添加到ArrayList中,然后在設(shè)置SimpleAdapter適配器完成設(shè)置,入下:

          package com.example.android_newlistview;

          import java.util.ArrayList;
          import java.util.HashMap;
          import java.util.Map;

          import android.os.Bundle;
          import android.app.Activity;
          import android.app.ListActivity;
          import android.view.Menu;
          import android.widget.SimpleAdapter;

          public class MainActivity extends ListActivity {


          String[] from
          ={"name","id"}; //這里是ListView顯示內(nèi)容每一列的列名
          int[] to={R.id.user_name,R.id.user_id}; //這里是ListView顯示每一列對應(yīng)的list_item中控件的id

          String[] userName
          ={"zhangsan","lisi","wangwu","zhaoliu"}; //這里第一列所要顯示的人名
          String[] userId={"1001","1002","1003","1004"}; //這里是人名對應(yīng)的ID

          ArrayList
          <HashMap<String,String>> list=null;
          HashMap
          <String,String> map=null;
          @Override
          protected void onCreate(Bundle savedInstanceState) {
          // TODO Auto-generated method stub
          super.onCreate(savedInstanceState);
          setContentView(R.layout.main);
          //為MainActivity設(shè)置主布局
          //創(chuàng)建ArrayList對象;
          list=new ArrayList<HashMap<String,String>>();
          //將數(shù)據(jù)存放進(jìn)ArrayList對象中,數(shù)據(jù)安排的結(jié)構(gòu)是,ListView的一行數(shù)據(jù)對應(yīng)一個HashMap對象,
          //HashMap對象,以列名作為鍵,以該列的值作為Value,將各列信息添加進(jìn)map中,然后再把每一列對應(yīng)
          //的map對象添加到ArrayList中

          for(int i=0; i<4; i++){
          map
          =new HashMap<String,String>(); //為避免產(chǎn)生空指針異常,有幾列就創(chuàng)建幾個map對象
          map.put("id", userId[i]);
          map.put(
          "name", userName[i]);
          list.add(map);
          }


          //創(chuàng)建一個SimpleAdapter對象
          SimpleAdapter adapter=new SimpleAdapter(this,list,R.layout.list_item,from,to);
          //調(diào)用ListActivity的setListAdapter方法,為ListView設(shè)置適配器
          setListAdapter(adapter);
          }

          }


          另外對點(diǎn)擊某一行作出響應(yīng)的方法是覆寫onListItemClick方法,根據(jù)返回的position(從0開始):
          @Override
          protected void onListItemClick(ListView l, View v, int position, long id) {
          // TODO Auto-generated method stub
          super.onListItemClick(l, v, position, id);
          }


          posted @ 2016-12-01 13:08 風(fēng)人園 閱讀(157) | 評論 (0)編輯 收藏

          android json 數(shù)據(jù)解析



          單數(shù)據(jù){'singer':{'id':01,'name':'tom','gender':'男'}} 
          多個數(shù)據(jù){"singers":[ 
                  {'id':02,'name':'tom','gender':'男'}, 
                   {'id':03,'name':'jerry,'gender':'男'}, 
          {'id':04,'name':'jim,'gender':'男'}, 
          {'id':05,'name':'lily,'gender':'女'}]}          
          // 普通Json數(shù)據(jù)解析 
              private void parseJson(String strResult) 
                  
          try 
                      JSONObject jsonObj 
          = new JSONObject(strResult).getJSONObject("singer"); 
                      
          int id = jsonObj.getInt("id"); 
                      String name 
          = jsonObj.getString("name"); 
                      String gender 
          = jsonObj.getString("gender"); 
                      tvJson.setText(
          "ID號"+id + ", 姓名:" + name + ",性別:" + gender); 
                  }
           catch (JSONException e) 
                      System.out.println(
          "Json parse error"); 
                      e.printStackTrace(); 
                  }
           
              }
           
              
          //解析多個數(shù)據(jù)的Json
             private void parseJsonMulti(String strResult) 
                 
          try 
                      JSONArray jsonObjs 
          = new JSONObject(strResult).getJSONArray("singers"); 
                      String s 
          = ""
                      
          for(int i = 0; i < jsonObjs.length() ; i++)
                          JSONObject jsonObj 
          = ((JSONObject)jsonObjs.opt(i)).getJSONObject("singer"); 
                          
          int id = jsonObj.getInt("id"); 
                          String name 
          = jsonObj.getString("name"); 
                          String gender 
          = jsonObj.getString("gender"); 
                          s 
          +=  "ID號"+id + ", 姓名:" + name + ",性別:" + gender+ "\n" ; 
                      }
           
                      tvJson.setText(s); 
                  }
           catch (JSONException e) 
                      System.out.println(
          "Jsons parse error !"); 
                      e.printStackTrace(); 
                  }
           
              }
           

          posted @ 2016-11-29 15:09 風(fēng)人園 閱讀(163) | 評論 (0)編輯 收藏

          button onClick 事件的幾種調(diào)用方式



          1. //第一種方式    
          2.         Button Btn1 = (Button)findViewById(R.id.button1);//獲取按鈕資源    
          3.         Btn1.setOnClickListener(new Button.OnClickListener(){//創(chuàng)建監(jiān)聽    
          4.             public void onClick(View v) {    
          5.                 String strTmp = "點(diǎn)擊Button01";    
          6.                 Ev1.setText(strTmp);    
          7.             }    
          8.   
          9.         });   

          1.     //第二種方式(Android1.6版本及以后的版本中提供了,直接在layout中設(shè)置)    
          2.     public void Btn3OnClick(View view){    
          3.         String strTmp="點(diǎn)擊Button03";  
          4.         Ev1.setText(strTmp);  
          5.   
          6.     }  

          1.  <Button  
          2.         android:id="@+id/button3"  
          3.         android:layout_width="wrap_content"  
          4.         android:layout_height="wrap_content"  
          5.         android:text="Button3"   
          6.         android:onClick="Btn3OnClick"/>  


          第三種方式 activity 實(shí)現(xiàn) 單擊監(jiān)聽接口

          public class TestButtonActivity extends Activity implements OnClickListener {
          Button btn1, btn2;
          Toast tst;
          @Override
          protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_test_button);
          btn1 = (Button) findViewById(R.id.button1);
          btn2 = (Button) findViewById(R.id.button2);
          btn1.setOnClickListener(this);
          btn2.setOnClickListener(this);
          }
          @Override
          public void onClick(View v) {
          // TODO Auto-generated method stub
          switch (v.getId()) {
          case R.id.button1:
          tst = Toast.makeText(this, "111111111", Toast.LENGTH_SHORT);
          tst.show();
          break;
          case R.id.button2:
          tst = Toast.makeText(this, "222222222", Toast.LENGTH_SHORT);
          tst.show();
          break;
          default:
          break;
          }
          }
          }




           

          posted @ 2016-11-29 13:31 風(fēng)人園 閱讀(906) | 評論 (0)編輯 收藏

          打開activity的幾種方式


          一、直接打開,不傳遞參數(shù)
          Intent intent = new Intent(this, Activity.class);
          startActivity(intent);


          二、傳遞參數(shù)
          public void OpenNew(View v) {
              
          //新建一個顯式意圖,第一個參數(shù)為當(dāng)前Activity類對象,第二個參數(shù)為你要打開的Activity類
              Intent intent =new Intent(MainActivity.this,MainActivity2.class);
              
              
          //用Bundle攜帶數(shù)據(jù)
              Bundle bundle=new Bundle();
              
          //傳遞name參數(shù)為tinyphp
              bundle.putString("name""tinyphp");
              intent.putExtras(bundle);
              
              startActivity(intent);       
           //1.要關(guān)閉的頁面  
              protected void onCreate(Bundle savedInstanceState) {  
                  
          super.onCreate(savedInstanceState);  
                  setContentView(R.layout.otheractivity);  
                  Intent intent 
          = this.getIntent();  
                  intent.putExtra(
          "tel"12345);  
                  
          //設(shè)置requestCode和帶有數(shù)據(jù)的intent對象  
                  OtherActivity.this.setResult(3, intent);  
                  
          //馬上關(guān)閉Activity  
                  this.finish();  
              }
            
                
              
          //2.上面的頁面關(guān)閉時,此頁面進(jìn)行數(shù)據(jù)的接收  
              class ButtonListener implements android.view.View.OnClickListener{  
                  @Override  
                  
          public void onClick(View arg0) {  
                      Intent intent 
          = new Intent();  
                      intent.setClass(MainActivity.
          this, OtherActivity.class);  
                      
          //與普通的start方法不同,需要設(shè)置requestCode  
                      startActivityForResult(intent, 1);  
                  }
            
              }
            
                
              
          //如果要進(jìn)行此操作,需要在數(shù)據(jù)接收頁面中復(fù)寫activity的onActivityResul()方法  
              @Override  
              
          protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
                  
          super.onActivityResult(requestCode, resultCode, data);  
                  
          int tel = 0;  
                  
          //根據(jù)返回碼resultCode來判斷下一步進(jìn)行的業(yè)務(wù)代碼  
                  if(resultCode==3){  
                      tel 
          = data.getIntExtra("tel"0);  
                  }
            
                  Log.i(TAG, 
          "tel--------->"+String.valueOf(tel));  
              }
            
           
              }



          三、回傳參數(shù)


          posted @ 2016-11-29 13:24 風(fēng)人園 閱讀(444) | 評論 (0)編輯 收藏

          spring mvc @ExceptionHandler 異常處理

          spring mvc 統(tǒng)一的異常處理,有兩種方式。
          一、exceptionResolver
          二、ExceptionHandler

          兩者不能同時配置。如果配置了第一種,則第二種無效。就因?yàn)檫@個原因,找了一天的問題。

          ExceptionHandler 通過注解的方式,進(jìn)行配置,只需要在某個controller 中設(shè)置了這個注解,則這個controller中的所有異常都會通過這個方法進(jìn)行處理。

          比如rest controller,增加一個
              @ExceptionHandler
              
          public String exp(HttpServletRequest request, Exception ex) {  
                  
                  Map map 
          = new HashMap();
                  
                  logger.error(
          "error," + UUID.randomUUID().toString(), ex);
                  request.setAttribute(
          "ex", ex);  
                  
                  String msg 
          = ex.getMessage();
                  
                  map.put(
          "success""0"); 
                  map.put(
          "msg", msg);
                  
                  String rtnjson 
          = JSONUtil.objectToJson(map);
                  
                  request.setAttribute(
          "json", rtnjson);
                  
                  
          return "json";
              }
           

          這樣,這個controler中的異常,都會由這個異常處理方法,進(jìn)行統(tǒng)一處理,生成異常json。避免在各個方法中通過try catch 的方法,進(jìn)行異常處理。

          posted @ 2016-11-08 08:32 風(fēng)人園 閱讀(394) | 評論 (0)編輯 收藏

          有關(guān)使用 ActionBarSherlock 自定義樣式的問題

          1、不同android 版本,需要設(shè)置不同的 sytle 文件。
              默認(rèn) 通常我們會設(shè)置values下面的style 文件
              但是如果是4.0以上,則還需要設(shè)置values-v14下面的style文件。
              
          否則不能生效

          posted @ 2014-03-30 09:00 風(fēng)人園 閱讀(469) | 評論 (0)編輯 收藏

          解決IIS 啟動響應(yīng)超時 或者 World Wide Web Publishing服務(wù)無法啟動提示:錯誤127 找不到指定程序/路徑

          找了很多方案,都說是那個KB939373 這個補(bǔ)丁搞的,但是在添加刪除里就是找不到這個東東,重裝也沒有用,后來找到了這篇文章
          http://www.cnblogs.com/skylaugh/archive/2011/07/21/2112860.html

          根據(jù)這篇文章,我把 infocomm.dll 給替換一下,然后就好了,簡直就是坑爹啊。

          這里講講需要注意的事項(xiàng)。
          1、替換的文件通過iis安裝文件生成,請看參考文章
          2、文件直接黏貼覆蓋,不要使用參考里面bat處理。
          3、然后啟動這個服務(wù),啟動iis,搞定

          posted @ 2013-06-18 15:49 風(fēng)人園 閱讀(231) | 評論 (0)編輯 收藏

          解決Tomcat Error listenerStart 問題

          昨天部署web應(yīng)用到Tomcat之后,無法成功啟動,并且控制臺沒有詳細(xì)的錯誤信息,
          頂多就兩行提示信息,例如:
          嚴(yán)重: Error listenerStart
          嚴(yán)重: Context [/] startup failed due to previous errors

          或者

          嚴(yán)重: Error filterStart
          org.apache.catalina.core.StandardContext start
          嚴(yán)重: Context startup failed due to previous errors

          查找logs目錄下的信息,除了這兩句話,也沒別的輔助內(nèi)容.
          給查錯帶來了困難,在這種情況下,是因?yàn)門omcat自身的默認(rèn)日志沒有將一些錯誤信息輸出到控制臺或文件,
          這個時候則需要配置Tomcat自身的log,啟用詳細(xì)的調(diào)試日志.

          3.log4j配置文件:
          log4j.properties
          配置內(nèi)容為:

          log4j.rootLogger=ERROR,R

          log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
          log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
          log4j.appender.CONSOLE.layout.ConversionPattern=[%p]%t-%c-%m%n

          log4j.appender.R=org.apache.log4j.RollingFileAppender
          log4j.appender.R.File=${catalina.home}/logs/tomcat.log
          log4j.appender.R.MaxFileSize=10MB
          log4j.appender.R.MaxBackupIndex=10
          log4j.appender.R.layout=org.apache.log4j.PatternLayout
          log4j.appender.R.layout.ConversionPattern=[%p]%t-%c-%m%n

          log4j.logger.org.apache.catalina=INFO,R,CONSOLE

          #日志級別不能太低,如果配置為debug的話,輸出的日志信息太多,導(dǎo)致tomcat啟動非常的慢.

          4.Tomcat 6.0所需的juli替換文件:
          http://www.apache.org/dist/--escaped_anchor:079305423cce36d6691457475e081123--/tomcat-6/v6.0.18/bin/extras/tomcat-juli-adapters.jar
          http://www.apache.org/dist/--escaped_anchor:079305423cce36d6691457475e081123--/tomcat-6/v6.0.18/bin/extras/tomcat-juli.jar
          以上兩個鏈接基本沒用,大家可以搜索一下,csdn上面有人提供jar包下載,這里附件也不能加,沒有辦法。

          在Tomcat6.0中,

          將tomcat-juli-adapters.jar,log4j-1.2.15.jar,log4j.properties復(fù)制到D:\Java\ApacheTomcat6.0.14\lib下面.

          將tomcat-juli.jar復(fù)制到D:\Java\apache-tomcat-6.0.14\bin\下面.

          然后啟動tomcat,就可以在D:\Java\apache-tomcat-6.0.14\logs下看到tomcat.log了.

          在這個時候,再通過日志文件來分析,則會發(fā)現(xiàn)出現(xiàn)這種錯誤的情況可能有:
          (以下是我遇到的出錯情況,大多是些低級錯誤)
          1.webapps要用到的classe文件根本沒有復(fù)制到WEB-INF/classes目錄下面
          (java.lang.NoClassDefFoundError,而這個信息可能默認(rèn)沒輸出到控制臺,尤其是用了spring的,昨天就是這個粗心的低級錯誤)
          2.要用到lib文件沒有復(fù)制完,缺少lib
          3.lib下的同一個庫的jar文件存在多個不同版本,引起版本沖突.
          4.lib下的jar與tomcat版本不相對應(yīng)(我遇到的問題是web應(yīng)用在Tomcat5.5上運(yùn)行正常,換到Tomcat6.0上就出錯,
          例如一個用了struts的webapp在Tomcat 6上報下面的錯誤
          “Parse Fatal Error at line 17 column 6: The processing instruction
          target matching “[xX][mM][lL]” is not allowed” )

          愿意看英文的可以參考官方網(wǎng)站說明:
          http://tomcat.apache.org/tomcat-6.0-doc/logging.html


          標(biāo)記一下:) 

          posted @ 2012-04-20 15:39 風(fēng)人園 閱讀(2879) | 評論 (0)編輯 收藏

          javax.servlet 和 javax.servlet.jsp導(dǎo)致系統(tǒng)錯誤的問題

          提示無法載入 c.tld等信息

          只要刪除 WEB-INF/lib 下的上述兩個文件即可

          因?yàn)榇宋募c tomcat中的文件版本沖突

          posted @ 2012-04-20 14:16 風(fēng)人園 閱讀(243) | 評論 (0)編輯 收藏

          [轉(zhuǎn)]淺談Hibernate的flush機(jī)制

          淺談Hibernate的flush機(jī)制

          隨著Hibernate在Java開發(fā)中的廣泛應(yīng)用,我們在使用Hibernate進(jìn)行對象持久化操作中也遇到了各種各樣的問題。這些問題往往都是我們對Hibernate缺乏了解所致,這里我講個我從前遇到的問題及一些想法,希望能給大家一點(diǎn)借鑒。

                這是在一次事務(wù)提交時遇到的異常。
                an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
          net.sf.hibernate.AssertionFailure: possible nonthreadsafe access to session
          注:非possible non-threadsafe access to the session (那是另外的錯誤,類似但不一樣)
                這個異常應(yīng)該很多的朋友都遇到過,原因可能各不相同。但所有的異常都應(yīng)該是在flush或者事務(wù)提交的過程中發(fā)生的。這一般由我們在事務(wù)開始至事務(wù)提交的 過程中進(jìn)行了不正確的操作導(dǎo)致,也會在多線程同時操作一個Session時發(fā)生,這里我們僅僅討論單線程的情況,多線程除了線程同步外基本與此相同。
                至于具體是什么樣的錯誤操作那?我給大家看一個例子(假設(shè)Hibernate配置正確,為保持代碼簡潔,不引入包及處理任何異常)
          SessionFactory sf = new Configuration().configure().buildSessionFactory() ;
          Session s = sf.openSession();
          Cat cat = new Cat();
          Transaction tran = s.beginTransaction(); (1)
          s.save(cat); (2)(此處同樣可以為update delete)
          s.evict(cat); (3)
          tran.commit(); (4)
          s.close();(5)
                這就是引起此異常的典型錯誤。我當(dāng)時就遇到了這個異常,檢查代碼時根本沒感覺到這段代碼出了問題,想當(dāng)然的認(rèn)為在Session上開始一個事務(wù),通過 Session將對象存入數(shù)據(jù)庫,再將這個對象從Session上拆離,提交事務(wù),這是一個很正常的流程。如果這里正常的話,那問題一定在別處。
                  問題恰恰就在這里,我的想法也許沒有錯,但是一個錯誤的論據(jù)所引出的觀點(diǎn)永遠(yuǎn)都不可能是正確的。因?yàn)槲乙恢币詾橹苯釉趯?shù)據(jù)庫進(jìn)行操作,忘記了在我與數(shù)據(jù) 庫之間隔了一個Hibernate,Hibernate在為我們提供持久化服務(wù)的同時,也改變了我們對數(shù)據(jù)庫的操作方式,這種方式與我們直接的數(shù)據(jù)庫操作 有著很多的不同,正因?yàn)槲覀儗@種方式?jīng)]有一個大致的了解造成了我們的應(yīng)用并未得到預(yù)先設(shè)想的結(jié)果。
          那Hibernate的持久化機(jī)制到底有什么不同那?簡單的說,Hibernate在數(shù)據(jù)庫層之上實(shí)現(xiàn)了一個緩存區(qū),當(dāng)應(yīng)用save或者update一個 對象時,Hibernate并未將這個對象實(shí)際的寫入數(shù)據(jù)庫中,而僅僅是在緩存中根據(jù)應(yīng)用的行為做了登記,在真正需要將緩存中的數(shù)據(jù)flush入數(shù)據(jù)庫時 才執(zhí)行先前登記的所有行為。
          在實(shí)際執(zhí)行的過程中,每個Session是通過幾個映射和集合來維護(hù)所有與該Session建立了關(guān)聯(lián)的對象以及應(yīng)用對這些對象所進(jìn)行的操作的,與我們這 次討論有關(guān)的有entityEntries(與Session相關(guān)聯(lián)的對象的映射)、insertions(所有的插入操作集合)、 deletions(刪除操作集合)、updates(更新操作集合)。下面我就開始解釋在最開始的例子中,Hibernate到底是怎樣運(yùn)作的。
          (1)生成一個事務(wù)的對象,并標(biāo)記當(dāng)前的Session處于事務(wù)狀態(tài)(注:此時并未啟動數(shù)據(jù)庫級事務(wù))。
          (2)應(yīng)用使用s.save保存cat對象,這個時候Session將cat這個對象放入entityEntries,用來標(biāo)記cat已經(jīng)和當(dāng)前的會話建 立了關(guān)聯(lián),由于應(yīng)用對cat做了保存的操作,Session還要在insertions中登記應(yīng)用的這個插入行為(行為包括:對象引用、對象id、 Session、持久化處理類)。
          (3)s.evict(cat)將cat對象從s會話中拆離,這時s會從entityEntries中將cat這個對象移出。
          (4)事務(wù)提交,需要將所有緩存flush入數(shù)據(jù)庫,Session啟動一個事務(wù),并按照insert,update,……,delete的順序提交所有 之前登記的操作(注意:所有insert執(zhí)行完畢后才會執(zhí)行update,這里的特殊處理也可能會將你的程序搞得一團(tuán)糟,如需要控制操作的執(zhí)行順序,要善 于使用flush),現(xiàn)在cat不在entityEntries中,但在執(zhí)行insert的行為時只需要訪問insertions就足夠了,所以此時不會 有任何的異常。異常出現(xiàn)在插入后通知Session該對象已經(jīng)插入完畢這個步驟上,這個步驟中需要將entityEntries中cat的 existsInDatabase標(biāo)志置為true,由于cat并不存在于entityEntries中,此時Hibernate就認(rèn)為 insertions和entityEntries可能因?yàn)榫€程安全的問題產(chǎn)生了不同步(也不知道Hibernate的開發(fā)者是否考慮到例子中的處理方 式,如果沒有的話,這也許算是一個bug吧),于是一個net.sf.hibernate.AssertionFailure就被拋出,程序終止。

          我想現(xiàn)在大家應(yīng)該明白例子中的程序到底哪里有問題了吧,我們的錯誤的認(rèn)為s.save會立即的執(zhí)行,而將cat對象過早的與Session拆離,造成了 Session的insertions和entityEntries中內(nèi)容的不同步。所以我們在做此類操作時一定要清楚Hibernate什么時候會將數(shù) 據(jù)flush入數(shù)據(jù)庫,在未flush之前不要將已進(jìn)行操作的對象從Session上拆離。

          對于這個錯誤的解決方法是,我們可以在(2)和(3)之間插入一個s.flush()強(qiáng)制Session將緩存中的數(shù)據(jù)flush入數(shù)據(jù)庫(此時 Hibernate會提前啟動事務(wù),將(2)中的save登記的insert語句登記在數(shù)據(jù)庫事務(wù)中,并將所有操作集合清空),這樣在(4)事務(wù)提交時 insertions集合就已經(jīng)是空的了,即使我們拆離了cat也不會有任何的異常了。
          前面簡單的介紹了一下Hibernate的flush機(jī)制和對我們程序可能帶來的影響以及相應(yīng)的解決方法,Hibernate的緩存機(jī)制還會在其他的方面給我們的程序帶來一些意想不到的影響。看下面的例子:
          (name為cat表的主鍵)
          Cat cat = new Cat();
          cat.setName(“tom”);
          s.save(cat);
          cat.setName(“mary”);
          s.update(cat);(6)
          Cat littleCat = new Cat();
          littleCat.setName(“tom”);
          s.save(littleCat);
          s.flush();
          這個例子看起來有什么問題?估計不了解Hibernate緩存機(jī)制的人多半會說沒有問題,但它也一樣不能按照我們的思路正常運(yùn)行,在flush過程中會產(chǎn) 生主鍵沖突,可能你想問:“在save(littleCat)之前不是已經(jīng)更改cat.name并已經(jīng)更新了么?為什么還會發(fā)生主鍵沖突那?”這里的原因 就是我在解釋第一個例子時所提到的緩存flush順序的問題,Hibernate按照insert,update,……,delete的順序提交所有登記 的操作,所以你的s.update(cat)雖然在程序中出現(xiàn)在s.save(littleCat)之前,但是在flush的過程中,所有的save都將 在update之前執(zhí)行,這就造成了主鍵沖突的發(fā)生。
          這個例子中的更改方法一樣是在(6)之后加入s.flush()強(qiáng)制Session在保存littleCat之前更新cat的name。這樣在第二次 flush時就只會執(zhí)行s.save(littleCat)這次登記的動作,這樣就不會出現(xiàn)主鍵沖突的狀況。再看一個例子(很奇怪的例子,但是能夠說明問 題)
          Cat cat = new Cat();
          cat.setName(“tom”);
          s.save(cat); (7)
          s.delete(cat);(8)
          cat.id=null;(9)
          s.save(cat);(10)
          s.flush();
          這個例子在運(yùn)行時會產(chǎn)生異常net.sf.hibernate.HibernateException: identifier of an instance of Cat altered from 8b818e920a86f038010a86f03a9d0001 to null這里例子也是有關(guān)于緩存的問題,但是原因稍有不同:(7)和(2)的處理相同。(8)Session會在deletions中登記這個刪除動作,同時更新entityEntries中該對象的登記狀態(tài)為DELETED。(9)Cat類的標(biāo)識符字段為id,將其置為null便于重新分配id并保存進(jìn)數(shù)據(jù)庫。
          (10)此時Session會首先在entityEntries查找cat對象是否曾經(jīng)與Session做過關(guān)聯(lián),因?yàn)閏at只改變了屬性值,引用并未改 變,所以會取得狀態(tài)為DELETED的那個登記對象。由于第二次保存的對象已經(jīng)在當(dāng)前Session中刪除,save會強(qiáng)制Session將緩存 flush才會繼續(xù),flush的過程中首先要執(zhí)行最開始的save動作,在這個save中檢查了cat這個對象的id是否與原來執(zhí)行動作時的id相同。 不幸的是,此時cat的id被賦為null,異常被拋出,程序終止(此處要注意,我們在以后的開發(fā)過程盡量不要在flush之前改變已經(jīng)進(jìn)行了操作的對象 的id)。
          這個例子中的錯誤也是由于緩存的延時更新造成的(當(dāng)然,與不正規(guī)的使用Hibernate也有關(guān)系),處理方法有兩種:
          1、在(8)之后flush,這樣就可以保證(10)處save將cat作為一個全新的對象進(jìn)行保存。
          2、刪除(9),這樣第二次save所引起的強(qiáng)制flush可以正常的執(zhí)行,在數(shù)據(jù)庫中插入cat對象后將其刪除,然后繼續(xù)第二次save重新插入cat對象,此時cat的id仍與從前一致。
          這兩種方法可以根據(jù)不同的需要來使用,呵呵,總覺得好像是很不正規(guī)的方式來解決問題,但是問題本身也不夠正規(guī),只希望能夠在應(yīng)用開發(fā)中給大家一些幫助,不對的地方也希望各位給與指正。
            總的來說,由于Hibernate的flush處理機(jī)制,我們在一些復(fù)雜的對象更新和保存的過程中就要考慮數(shù)據(jù)庫操作順序的改變以及延時flush是 否對程序的結(jié)果有影響。如果確實(shí)存在著影響,那就可以在需要保持這種操作順序的位置加入flush強(qiáng)制Hibernate將緩存中記錄的操作flush入 數(shù)據(jù)庫,這樣看起來也許不太美觀,但很有效。

          轉(zhuǎn)
          http://hi.baidu.com/lkdlhw_2000/blog/item/a35b9cca82945342f31fe769.html

          posted @ 2012-02-22 13:11 風(fēng)人園| 編輯 收藏

          ActiveMq 的安裝及整合spring 使用


          1、下載 安裝
          在windows xp 上,直接解壓就可以使用
          在2003 上,還需要配置一下,缺一個文件,否則無法啟動

          2、mq 配置
          默認(rèn)使用 文件持久化的方式,無需進(jìn)行配置,只需要通過代碼,標(biāo)記消息為持久化即可

          //設(shè)置 消息為 ‘持久化’ 消息,隊列服務(wù)器重啟后,會重新載入
          message.setJMSDeliveryMode(DeliveryMode.PERSISTENT);
          message.setString("context", context);

          2、整合spring
          mq的spring 配置文件, 此處三個bean
           mq 服務(wù)器配置,sender ,監(jiān)聽器
          完成系統(tǒng)的消息發(fā)送和接收

          <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
                  
          <property name="brokerURL" value="tcp://10.10.1.31:61616" />
              
          </bean>
              
              
          <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
                  
          <property name="connectionFactory" ref="connectionFactory" />
              
          </bean>
               
              
          <!--  ============================  消息發(fā)送 ============================== -->
              
              
          <!-- ecp.sd.log -->
              
          <bean id="logDestination" class="org.apache.activemq.command.ActiveMQQueue">
                  
          <constructor-arg value="km.wlog"/>
              
          </bean>
              
              
          <bean id="logMessageSender" class="com.chint.mq.sender.LogMessageSender">
                  
          <property name="destination" ref="logDestination" />
                  
          <property name="jmsTemplate" ref="jmsTemplate" />
              
          </bean>
              
              
          <!--=============================  隊列監(jiān)聽器  ==========================  -->
              
              
          <!-- 日志 隊列監(jiān)聽器 
              
          <bean id="logContextListener" class="com.chint.mq.listener.LogContextListener">
              
          </bean>
              
              
          <bean class="org.springframework.jms.listener.SimpleMessageListenerContainer">
                  
          <property name="connectionFactory" ref="connectionFactory"/>
                  
          <property name="destinationName" value="km.wlog"/>
                  
          <property name="messageListener" ref="logContextListener"/>
              
          </bean>
              
          -->

          消息發(fā)送者
          @Service
          public class LogMessageSender extends BaseMessageSender{
              
              
          public void sendMessage(final String context) {
                  jmsTemplate.send(destination, 
          new MessageCreator(){

                      @Override
                      
          public Message createMessage(Session session) throws JMSException {
                          MapMessage message 
          = session.createMapMessage();
                          
                          
          //設(shè)置 消息為 ‘持久化’ 消息,隊列服務(wù)器重啟后,會重新載入
                          message.setJMSDeliveryMode(DeliveryMode.PERSISTENT);
                          message.setString(
          "context", context);
                          
                          logger.info(
          "KM INFO [LogMessageSender] send message context ({})", context);
                          
                          
          return message;
                      }

                      
                  }
          );
              }


          }

          消息接受者
          /**
           * 
          @author wxf
           *
           
          */

          public class LogContextListener extends BaseContextListener implements MessageListener{

              @Autowired
              
          private WorkLogManager workLogManager;
              
              @Override
              
          public void onMessage(Message arg) {
                  
          if(arg instanceof MapMessage) {
                      MapMessage message 
          = (MapMessage)arg;
                      
                      
          try {
                          String context 
          = message.getString("context");
                          logger.info(
          "KM INFO [LogContextListener] get message context ({})", context);   
                      }
           catch (JMSException e) {
                          
          throw JmsUtils.convertJmsAccessException(e);
                      }

                  }
           else {
                      System.out.println(arg.toString());
                  }

              }


          }


          以上就完成了 MQ的使用,比較簡單。

          通過spring使用mq從代碼來講還是很簡單的,但是mq的性能可能需要額外的調(diào)整一下才能達(dá)到最佳的狀態(tài),特別是大數(shù)量的情況下。

          僅作記錄

          posted @ 2011-11-09 09:25 風(fēng)人園 閱讀(633) | 評論 (0)編輯 收藏

          同一臺電腦登陸多個賬號的問題

          這個問題一直比較奇怪,今天搜了一下,原來是瀏覽器的問題,這讓我想起來了網(wǎng)頁版的網(wǎng)游,不能多登的問題。原來session是相同的。

          打開的是兩個瀏覽器還是兩個頁簽,
          比如 IE7這種支持多頁簽的,也就是在一個瀏覽器里面同時打開多個頁簽的這種,是共用一個Session的,
          但是比如IE6這種一次只能打開一個瀏覽器的,就沒有問題,

          因?yàn)榇蜷_的是多個瀏覽器我說了,這個和瀏覽器相關(guān),每當(dāng)你打開一個瀏覽器,這個瀏覽器就會有專門的session.


          也算是解決了一個問題吧:)

          這里標(biāo)記一下

          posted @ 2011-09-09 16:43 風(fēng)人園 閱讀(411) | 評論 (0)編輯 收藏

          遍歷所有數(shù)據(jù)文件的大小

           

          1、新建一個臨時數(shù)據(jù)庫,用于存放查詢結(jié)果
          CREATE TABLE DatabaseFileLog
          (
           date DATETIME,
           dbname VARCHAR(20),
           FILENAME VARCHAR(100),
           fileSIZE FLOAT
           
          )


          2、通過游標(biāo)遍歷所有數(shù)據(jù)庫
          declare @dbName varchar(50)
          declare @command varchar(1024)
          declare dbName_cursor CURSOR FOR
              select [name]
              from master.dbo.sysdatabases
              where [name] not in ('master','tempdb','msdb','model')
          open dbName_cursor
          FETCH NEXT FROM dbName_cursor INTO @dbName
          WHILE @@FETCH_STATUS = 0
          begin
              set @command = '
                  insert into DatabaseFileLog
                  select
                  getdate(),
                  '''+
                  @dbName
                  +''',

                  filename,
                  convert(float,size) * (8192.0/1024.0)/1024.0 as ''MB''

                  from '+@dbName +'.dbo.sysfiles ';
              exec ( @command );
              FETCH NEXT FROM dbName_cursor INTO @dbName ;
          end
          CLOSE dbName_cursor;
          DEALLOCATE dbName_cursor;

          3、查詢結(jié)果
          SELECT * FROM DatabaseFileLog

          posted @ 2011-09-06 10:46 風(fēng)人園 閱讀(210) | 評論 (0)編輯 收藏

          eclipse 注釋模版 設(shè)置


          設(shè)置注釋模板的入口: Window->Preference->Java->Code Style->Code Template 然后展開Comments節(jié)點(diǎn)就是所有需設(shè)置注釋的元素啦。

          常用的,一般兩個

          文件(Files)注釋標(biāo)簽:

          /**  
          * @Title: ${file_name}
          * @Package ${package_name}
          * @Description: ${todo}(用一句話描述該文件做什么)
          * @author A18ccms A18ccms_gmail_com  
          * @date ${date} ${time}
          * @version V1.0  
          */


          類型(Types)注釋標(biāo)簽(類的注釋):

          /**
          * @Description: ${todo}(這里用一句話描述這個類的作用)
          * @author ${user}
          * @date ${date} ${time}
          *
          * ${tags}
          */

          posted @ 2011-08-18 16:30 風(fēng)人園 閱讀(353) | 評論 (0)編輯 收藏

          Spring MVC 使用中的注意事項(xiàng)

              ModelAndView中保存了要傳遞給視圖的對象和具體要使用的視圖文件,自2.0起, Spring MVC提供了Convention over Configuration的機(jī)制,大大簡化了代碼與配置。簡單地說,名字以Controller結(jié)尾的控制器類都會被映射為相應(yīng)的地址,ListArticleController對應(yīng)/listarticle*,如果是MultiActionController則會被映射為一個目錄;向ModelAndView添加對象時可以不用指定鍵(key),單一對象的鍵取決于類名,比如x.y.User的鍵是user,而某一類對象的 Set、List或數(shù)組則稍有些復(fù)雜,取第一個對象的類名加上“List”作為它的鍵,比如這里的articles是一個存放Article對象的 List,它的鍵就是articleList;
          也可以通過執(zhí)行key,來指定變量名稱

          posted @ 2010-12-30 15:51 風(fēng)人園 閱讀(380) | 評論 (0)編輯 收藏

          spring 事務(wù)的回滾問題

              spring的事物配置,默認(rèn)狀態(tài)下,只針對 RuntimeException 進(jìn)行回滾。
          而像SQLException并不是RuntimeException,所以這里需要特別注意。

          這里困擾了我很久,一直沒有想明白為什么在一個事務(wù)里面,部分成功,部分失敗。可能就是這個原因?qū)е碌摹?br /> 也就是說,一些系統(tǒng)級別的異常,前期都需要轉(zhuǎn)化成 RuntimeException 。這樣就可以進(jìn)行回滾了。

          但是這樣的只需要修改底層,另外一個偷懶的方法,在每個service類上直接指定rollback = Exception.class。這樣所有的異常都會回滾。但是這樣有沒有副作用,但是不清楚。

          異常一直是我沒有搞定的一塊內(nèi)容之一,稱這個機(jī)會研究一下。
          為什么需要分check 和unckeck,兩者有什么不動點(diǎn)。
          如果都是用uncheck,會不會有什么問題?
          待續(xù)。。。

          posted @ 2010-12-14 14:01 風(fēng)人園 閱讀(870) | 評論 (1)編輯 收藏

          hibernate 關(guān)聯(lián)查詢錯誤(Path expected for join)

              以前沒怎么用,現(xiàn)在真用起來的時候還是會有很多白癡問題,哈。
              今天想做一個left join , 關(guān)聯(lián)關(guān)系應(yīng)該是已經(jīng)配好了,但是調(diào)用hql就是報錯,也不知道怎么回事。繼續(xù)研究ing。

          posted @ 2009-12-10 14:00 風(fēng)人園 閱讀(4918) | 評論 (1)編輯 收藏

          Hibernate主從數(shù)據(jù)的操作

          struts2+spring2.5+hibernate 3.3

          在hibernate的操作中,特別是主從數(shù)據(jù)的操作。

          一般有這么幾個地方需要注意,以前也一直沒有拿hibernate好好用過,現(xiàn)在真正用起來,問題還是挺多了。這幾天一直在調(diào)試解釋這種問題。

          主數(shù)據(jù)中的一對一關(guān)聯(lián),這里的關(guān)聯(lián)數(shù)據(jù)從頁面提交的時候是否可以直接映射到主數(shù)據(jù)對象中?暫時不清楚,可以測試一下。

          然后是明細(xì)數(shù)據(jù)的操作,現(xiàn)在動態(tài)產(chǎn)生的行數(shù)據(jù),然后手動解析,生成明細(xì)對象。整個過程個人感覺比較麻煩,暫時也想不出有什么好的解決方案。

          這里在級聯(lián)保存數(shù)據(jù)的時候,首先要清除掉原來的明細(xì)數(shù)據(jù),然后再把頁面提交過來的數(shù)據(jù)加上。
          不知道一般是不是這樣弄的。否則沒法清楚原來的數(shù)據(jù)。


          posted @ 2009-11-17 19:30 風(fēng)人園 閱讀(361) | 評論 (0)編輯 收藏

          通過MyEclipse生成annotation方式的entity類

              通過搜索和閱讀myEclipse的幫助文件,發(fā)現(xiàn)這是可以實(shí)現(xiàn)的。不過前提是,你使用的hibernate是3.2版本。這樣就可以支持以注解的方式生成實(shí)體類了。跟hbm配制文件方式基本是一樣的。

              昨天特地好好的看了一下MyEclipse的幫助,里面關(guān)于ajax web開發(fā)的工具感覺還是挺好用的,以前一直也沒有了解一下里面的功能,以后要好好用一下,還是可以有不少幫助的。
              今天先起個頭,明天寫一個詳細(xì)的操作說明,這樣也方便自己,免得忘了。

          posted @ 2009-11-15 19:02 風(fēng)人園 閱讀(500) | 評論 (0)編輯 收藏

          Jxls 導(dǎo)出excel

           1     public static void exportExcel(String templateFileName, Map beans, 
           2             HttpServletRequest request,HttpServletResponse response){
           3         try {
           4             response.setContentType("application/vnd.ms-excel");
           5             response.setHeader("Content-Disposition""attachment; filename=excel.xls");
           6             XLSTransformer transformer = new XLSTransformer();
           7 
           8             
           9             InputStream is = new BufferedInputStream(
          10                     new FileInputStream(RequestUtil.getRealPath(request, templateFileName)));
          11             
          12             HSSFWorkbook workbook = transformer.transformXLS(is, beans);
          13             OutputStream os = response.getOutputStream();
          14             workbook.write(os);
          15             is.close();
          16             os.flush();
          17             os.close();
          18         } catch (Exception e) {
          19             e.printStackTrace();
          20         }
          21     }
          通過服務(wù)器端獲取模版文件的絕對路徑,然后通過response來輸出到頁面,就可以實(shí)現(xiàn)導(dǎo)出,這個比poi等等都簡單很多,用起來比較舒服。
          服務(wù)器路徑的獲取:request.getSession().getServletContext().getRealPath(name);
          這樣就可以獲得web目錄下某個文件的服務(wù)器端路勁。

          今天在使用的時候發(fā)現(xiàn)一個問題,就是在使用表達(dá)式的時候有一個地方需要注意
          ${item.itemQty}
          像上面的這個表達(dá)式就會出錯,這里也沒有看源代碼,具體不是很清楚,但是看了一下日志,發(fā)現(xiàn),后面的這個item也被替換了,所以覺得這個可能是jxls的bug或者是作者偷懶搞的。

          以后只需要注意字段名不能跟bean的名字一樣,否則就出錯。

          僅此記錄

          posted @ 2009-09-21 16:21 風(fēng)人園 閱讀(2735) | 評論 (1)編輯 收藏

          IronTrackSQL配置

          主要講一下在配置的過程中出現(xiàn)的問題,基本的配置方式網(wǎng)上有很多。
          這里講spring的集成問題。
          可能會出現(xiàn)兩個問題
          1、spring配置:
              

           <bean id="datasourceTarget" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
            <!-- Connection Info -->

           </bean>

              <bean id="dataSource" class="com.p6spy.engine.spy.P6DataSource">
                  <constructor-arg>
                      <ref local="datasourceTarget"/>
                  </constructor-arg>
              </bean>

              這樣就不會出現(xiàn)說找不到合適的驅(qū)動 這個異常。
          2、是p6spy的版本問題,導(dǎo)致spring配置文件失敗
              如果使用上面這個配置,需要1.3版本的p6spy.jar,我用老的,就出現(xiàn)說不能創(chuàng)建dataSource,沒有合適的一個參數(shù)的構(gòu)造函數(shù)。

          這是今天配置IronTrackSQL出現(xiàn)的兩個問題,讓我折騰了一個下午,所以記下來。
          還有一個問題就是
          Warning: Could not instantiate IronTrack server: java.net.BindException: Address already in use: JVM_Bind
          地址占用的問題,好像有兩個server啟動了。我重啟一下就會出現(xiàn)這個問題,第一次啟動就沒有問題,暫時不知道什么原因。
          找到了為什么重復(fù)啟動的問題,項(xiàng)目啟動了兩次,導(dǎo)致后一次啟動端口被暫用。
          總的來說還是不錯的,但是還搞不清楚怎么正確使用。
          繼續(xù)努力中

          posted @ 2009-09-17 15:46 風(fēng)人園 閱讀(481) | 評論 (0)編輯 收藏

          代碼質(zhì)量隨想

                  干了這么多年的代碼工,對于代碼質(zhì)量的理解,個人認(rèn)為就是一個,可維護(hù)性,除非你開發(fā)的東東是一錘子買賣,否則后期的投入會多的可怕,而且對于錯誤就沒有辦法控制了

                  下面引用別人的一段話來說明一下什么是高質(zhì)量的代碼:
                          高質(zhì)量的代碼,除了符合產(chǎn)品的功能設(shè)計需求外,還應(yīng)該便于維護(hù)、執(zhí)行效率高、經(jīng)過充分測試并且擁有較好的穩(wěn)定性。

                  但是從我個人來講,可維護(hù)性是第一位的,其他都是必須的,沖突的話就應(yīng)該適當(dāng)取舍。便于維護(hù)必然會影響到一點(diǎn)點(diǎn)的效率,但是這個肯定是可以接受的。是可以通過其他方式來彌補(bǔ)的。
                  不能為了追求所謂的高效,而破壞了系統(tǒng)的維護(hù)性,這樣導(dǎo)致后期維護(hù)會有很大的問題,從而可能導(dǎo)致低效。

                  這里介紹幾個工具,來提高代碼質(zhì)量。findbugs就是其中的一個,可以對代碼提出很好的修改建議。

          purifyplus 一個運(yùn)行時檢測系統(tǒng),可惜不免費(fèi)。


          備注: rational team concert 協(xié)作開發(fā)系統(tǒng),集成版本控制、工作項(xiàng)和構(gòu)建

          posted @ 2009-09-02 12:19 風(fēng)人園 閱讀(208) | 評論 (0)編輯 收藏

          ECP--之信息提示

                  一般,系統(tǒng)中把提示信息保存在request中傳遞會頁面,但是有些情況是redirect的,這樣就導(dǎo)致了request失效。在ROR中,有一個scope是夸兩個request的,不知道那個是怎么實(shí)現(xiàn)的。
                  現(xiàn)在用session來代替這個東西,只是顯示完成之后,就立刻清除這個數(shù)據(jù)。感覺比較挫,只能湊合著用了。
                  每次新開發(fā)一個系統(tǒng),如果不用現(xiàn)成的東西來做,都要搞很多很多東西,什么東西好像都要自己來,特別是頁面上的東西,感覺挺煩的。寫寫js,改改css,調(diào)調(diào)table/div。感覺挺無聊的。
                  總而言之,這樣子都是因?yàn)檫@家公司的it部門太弱了,幾乎沒有一點(diǎn)技術(shù)積累,這么多年了,什么東西都沒有留下,就留下了一堆垃圾,讓我改的挺郁悶的。現(xiàn)在正在用自己的東西重新。有些東西又沒法改,一些現(xiàn)成的組件也不一定能用,不能用的只能自己重新寫一遍,來實(shí)現(xiàn)這個功能。

                  作為一個技術(shù)部門,結(jié)果什么技術(shù)都沒有,感覺挺悲哀的,特別是一個技術(shù)部門的老大,結(jié)果是個門外漢,被手下人看不起,這個也挺慘的,作老大做成這樣,連死的心都有了,悲劇啊。

                  作為一個技術(shù)部門的主管,可以不做技術(shù),但是不能不懂技術(shù)。這樣才能服眾。

          posted @ 2009-08-31 14:37 風(fēng)人園 閱讀(156) | 評論 (0)編輯 收藏

          ECP--之彈出窗口解決方案(json傳遞)

                  在應(yīng)用中,彈出式窗口選擇數(shù)據(jù),這種解決方案是很普遍的。
                  彈出窗口,有兩種方式,一種是:showModalDialog,使用模式窗口,這種方式的好處有兩個地方,一、可以直接返回數(shù)據(jù),二、在最前面顯示,避免用戶誤操作,窗口被遮蔽。
                  但是這種方式個人感覺比較致命的地方就是因?yàn)檫@個是一個對話框,在form提交的時候只能新開一個頁面(可能我沒有發(fā)現(xiàn)其他的方式)。但是也有其他的方式,如加iframe,但是這樣感覺頁面太煩了,需要兩個頁面才能實(shí)現(xiàn),比較麻煩。

                  第二種:window.open,這種方式也有一個問題,就是會被當(dāng)做廣告攔截掉,還算不是很致命。
          我的方案就是這個,下面上代碼。
          傳遞格式通過json,這樣我可以自己定義需要回填那些域,返回值這邊就是竟可能的完整。


          /*
          彈出窗口
          endtarget: string 目標(biāo)窗口
          無返回
          */

          function fopenWindow(endtarget){
              window.open( endtarget, 
          """left=0, top=0, width=800px, height=600px, scrollbars=1, resizable=1, menubar=0, location=0, status=0, toolbar=0, " );
          }


          /*
          window.open的回調(diào)函數(shù)
          根據(jù)傳入的json格式,賦值相應(yīng)的域值

          cmp:string 域id
          retval :json 所選行的數(shù)據(jù)
          無返回
          */

          function fopenCallback(cmp, retval){
              
              
          //alert("call back start." + cmp);
              var obj = eval('(' + cmp + ')');
              
              
          for(var e in obj ){
                  
          //alert(obj[e]);
                  document.getElementById(obj[e]).value = retval[obj[e]]
              }

          }


          window.openCallback 
          = fopenCallback;

          /* 
          獲取url上的參數(shù)
          返回:key value 對
          */

          function GetUrlParms()    
          {
              
          var args=new Object();   
              
          var query=location.search.substring(1);//獲取查詢串   
              var pairs=query.split("&");//在逗號處斷開   
              for(var i=0;i<pairs.length;i++)   
              
          {   
                  
          var pos=pairs[i].indexOf('=');//查找name=value   
                  if(pos==-1)   continue;//如果沒有找到就跳過   
                  var argname=pairs[i].substring(0,pos);//提取name   
                  var value=pairs[i].substring(pos+1);//提取value   
                  args[argname]=unescape(value);//存為屬性   
              }

              
          return args;
          }
                      

          /*
          行雙擊方法,用戶選擇行數(shù)據(jù)。
          通過回調(diào)函數(shù),完成賦值,最后關(guān)閉窗口
          rtnval: string 行數(shù)據(jù)
          */

          function Dialog_onDblClick(rtnval)
          {
              
          //var rtnval = {prodId: prodId, prodName: prodName};
               
              
          var args = new Object();
              args 
          = GetUrlParms();
              
          var cmp = args['cmp']
              
              window.opener.openCallback(cmp, rtnval); 
              window.close();
          }


          主頁面 域id通過json字符串跟url傳遞后彈出頁面
          function popProductDialog(){
              var endtarget = "<%=path%>/bas/product.do?method=dialog";
              var cmp = "{a: 'prodId', b: 'prodName'}";
                 //fshowModalDialog(endtarget, cmp);
                
                 fopenWindow(endtarget+ "&cmp=" + cmp);
                
             }

          彈出框
          function Document_onDblClick(value1,value2)
                      
          {
                          
          var rtnval = {clientId:value1, clientName:value2};    
                              Dialog_onDblClick(rtnval);

                      }
          彈出頁面解析獲得域id,并通過循環(huán)域id從返回值中獲取數(shù)據(jù),并進(jìn)行賦值。

          這里唯一需要變的就是,彈出頁面的返回值,可能因?yàn)樾枨蟮脑黾樱枰祷馗嗟臄?shù)據(jù),或者就一次性將所有數(shù)據(jù)都作為json數(shù)據(jù)返回。

          這樣客戶在調(diào)用的時候,只要域id不超出返回字段的范圍,就可以正確使用了。

          posted @ 2009-08-31 10:39 風(fēng)人園 閱讀(575) | 評論 (0)編輯 收藏

          ibatis3中感覺比2不方便的地方


          1、動態(tài)sql里面 原來的dynamic,現(xiàn)在沒有了,只能用is代替。但是if里面的判斷 沒有isEmpty這種方便的標(biāo)簽,需要判斷需要同時判斷 null 和 ""。這個比較麻煩,希望能在正式版本中加上。

          2、annotion方式的評價,個人感覺沒有什么意義。從我來講,用iBATIS的主要原因是因?yàn)橐幚肀容^復(fù)雜的sql,所以通常sql都會很長,就是因?yàn)椴幌胪ㄟ^字符串的方式寫在代碼里,要是寫在代碼里,直接用hibernate的原生sql就好了,何必還要用iBATIS呢。sql寫在xml里的好處是顯而易見的,可以直接將調(diào)試好的sql從sql的編輯器中復(fù)制過來,這樣可以省掉很多麻煩的事情,放在sql里面很長,又沒有辦法將格式弄好,要是換行什么的就更麻煩。

          一個比較有用好的改進(jìn)就是namespace了,這個功能以前在2.X想用一直沒有用成。有了這個,很多通用的地方可以省略。

          posted @ 2009-08-26 16:30 風(fēng)人園 閱讀(402) | 評論 (0)編輯 收藏

          ibatis3及代碼生成工具試用

                  ibatis3現(xiàn)在還是beta版,但是已經(jīng)可以很好的使用了。
                  主要增強(qiáng)的方面有namespace這個東西,以前2的時候一直以為可以用的,結(jié)果沒有效果,害我還郁悶了半天,這樣以后就不會再有命名沖突了。
                  然后就是annotion的支持,這樣就可以不適用xml文件來保存sql了,但是感覺還是寫在xml里面比較舒服,特別是比較長的sql,個人感覺。
                  第三個就是動態(tài)sql的增強(qiáng),增加很多有用的標(biāo)簽。可以讓動態(tài)sql使用更加方便。
                  在看完之后暫時感覺有那么幾個比較好的改變,等正式版出來之后可能還有更多改進(jìn)。

                  接著講下abator這個代碼生成工具,感覺還可以,生成的sqlmap配置文件還可以用下,其他的就算了,還是自己手寫吧。

                  最后提到一下ibatis-3-migrations,這個東西暫時還沒有看明白,好像是數(shù)據(jù)庫schema的一個管理工具。正在啃g(shù)uide,看看到底有什么好處,上次看有個人的文章說,就是因?yàn)闆]有這個東西才沒有用ibatis,所以這個東東應(yīng)該很強(qiáng)大,我要看下。

          posted @ 2009-08-21 10:36 風(fēng)人園 閱讀(845) | 評論 (1)編輯 收藏

          主站蜘蛛池模板: 密山市| 新竹县| 盐山县| 英超| 师宗县| 聂荣县| 来安县| 通许县| 东明县| 逊克县| 嘉善县| 呼和浩特市| 安陆市| 上高县| 垣曲县| 赫章县| 庐江县| 黑山县| 普洱| 松阳县| 定西市| 嘉鱼县| 青河县| 德惠市| 灵璧县| 安化县| 张掖市| 叶城县| 阜阳市| 淮安市| 响水县| 上高县| 天全县| 叶城县| 岳普湖县| 两当县| 武山县| 阳原县| 拜城县| 瑞丽市| 安龙县|