<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    風(fēng)人園

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

    2009年8月31日

    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ù)庫(kù)的方式實(shí)現(xiàn)Spring Securityremember-me功能

    4. 獲取登錄用戶信息。

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

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

    spring security 參數(shù)配置

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

    posted @ 2018-03-19 20:33 風(fēng)人園 閱讀(431) | 評(píng)論 (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)人園 閱讀(385) | 評(píng)論 (0)編輯 收藏

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

    為了解決一些比較費(fèi)時(shí)且不是很緊要的任務(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) { 注:需要注意,同一個(gè)對(duì)象里面方法調(diào)用,不會(huì)作為異步方法執(zhí)行。

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

    android ResourceNotFoundException


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

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

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

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

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

    Android 自定義ListView adapter(zt)

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

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

    Android之SimpleAdapter簡(jiǎn)單實(shí)例和SimpleAdapter參數(shù)說(shuō)明(zt)

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

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

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

    首先是布局文件,這里需要兩個(gè)布局文件,一個(gè)是放置列表控件的Activity對(duì)應(yīng)的布局文件 main.xml,另一個(gè)是ListView中每一行信息顯示所對(duì)應(yīng)的布局 list_item.xml 這一步需要注意的問(wèn)題是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顯示每一列對(duì)應(yīng)的list_item中控件的id

    String[] userName
    ={"zhangsan","lisi","wangwu","zhaoliu"}; //這里第一列所要顯示的人名
    String[] userId={"1001","1002","1003","1004"}; //這里是人名對(duì)應(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對(duì)象;
    list=new ArrayList<HashMap<String,String>>();
    //將數(shù)據(jù)存放進(jìn)ArrayList對(duì)象中,數(shù)據(jù)安排的結(jié)構(gòu)是,ListView的一行數(shù)據(jù)對(duì)應(yīng)一個(gè)HashMap對(duì)象,
    //HashMap對(duì)象,以列名作為鍵,以該列的值作為Value,將各列信息添加進(jìn)map中,然后再把每一列對(duì)應(yīng)
    //的map對(duì)象添加到ArrayList中

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


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

    }


    另外對(duì)點(diǎn)擊某一行作出響應(yīng)的方法是覆寫(xiě)onListItemClick方法,根據(jù)返回的position(從0開(kāi)始):
    @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)人園 閱讀(153) | 評(píng)論 (0)編輯 收藏

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



    單數(shù)據(jù){'singer':{'id':01,'name':'tom','gender':'男'}} 
    多個(gè)數(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號(hào)"+id + ", 姓名:" + name + ",性別:" + gender); 
            }
     catch (JSONException e) 
                System.out.println(
    "Json parse error"); 
                e.printStackTrace(); 
            }
     
        }
     
        
    //解析多個(gè)數(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號(hào)"+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)人園 閱讀(160) | 評(píng)論 (0)編輯 收藏

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



    1. //第一種方式    
    2.         Button Btn1 = (Button)findViewById(R.id.button1);//獲取按鈕資源    
    3.         Btn1.setOnClickListener(new Button.OnClickListener(){//創(chuàng)建監(jiān)聽(tīng)    
    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)聽(tīng)接口

    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)人園 閱讀(904) | 評(píng)論 (0)編輯 收藏

    打開(kāi)activity的幾種方式


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


    二、傳遞參數(shù)
    public void OpenNew(View v) {
        
    //新建一個(gè)顯式意圖,第一個(gè)參數(shù)為當(dāng)前Activity類(lèi)對(duì)象,第二個(gè)參數(shù)為你要打開(kāi)的Activity類(lèi)
        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)閉的頁(yè)面  
        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對(duì)象  
            OtherActivity.this.setResult(3, intent);  
            
    //馬上關(guān)閉Activity  
            this.finish();  
        }
      
          
        
    //2.上面的頁(yè)面關(guān)閉時(shí),此頁(yè)面進(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ù)接收頁(yè)面中復(fù)寫(xiě)activity的onActivityResul()方法  
        @Override  
        
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
            
    super.onActivityResult(requestCode, resultCode, data);  
            
    int tel = 0;  
            
    //根據(jù)返回碼resultCode來(lái)判斷下一步進(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)人園 閱讀(442) | 評(píng)論 (0)編輯 收藏

    spring mvc @ExceptionHandler 異常處理

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

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

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

    比如rest controller,增加一個(gè)
        @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";
        }
     

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

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

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

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

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

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

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

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

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

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

    解決Tomcat Error listenerStart 問(wèn)題

    昨天部署web應(yīng)用到Tomcat之后,無(wú)法成功啟動(dòng),并且控制臺(tái)沒(méi)有詳細(xì)的錯(cuò)誤信息,
    頂多就兩行提示信息,例如:
    嚴(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目錄下的信息,除了這兩句話,也沒(méi)別的輔助內(nèi)容.
    給查錯(cuò)帶來(lái)了困難,在這種情況下,是因?yàn)門(mén)omcat自身的默認(rèn)日志沒(méi)有將一些錯(cuò)誤信息輸出到控制臺(tái)或文件,
    這個(gè)時(shí)候則需要配置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

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

    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
    以上兩個(gè)鏈接基本沒(méi)用,大家可以搜索一下,csdn上面有人提供jar包下載,這里附件也不能加,沒(méi)有辦法。

    在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\下面.

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

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

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


    標(biāo)記一下:) 

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

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

    提示無(wú)法載入 c.tld等信息

    只要?jiǎng)h除 WEB-INF/lib 下的上述兩個(gè)文件即可

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

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

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

    淺談Hibernate的flush機(jī)制

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

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

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

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

    轉(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 上,還需要配置一下,缺一個(gè)文件,否則無(wú)法啟動(dòng)

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

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

    2、整合spring
    mq的spring 配置文件, 此處三個(gè)bean
     mq 服務(wù)器配置,sender ,監(jiān)聽(tīng)器
    完成系統(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>
        
        
    <!--=============================  隊(duì)列監(jiān)聽(tīng)器  ==========================  -->
        
        
    <!-- 日志 隊(duì)列監(jiān)聽(tīng)器 
        
    <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è)置 消息為 ‘持久化’ 消息,隊(duì)列服務(wù)器重啟后,會(huì)重新載入
                    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的使用,比較簡(jiǎn)單。

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

    僅作記錄

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

    同一臺(tái)電腦登陸多個(gè)賬號(hào)的問(wèn)題

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

    打開(kāi)的是兩個(gè)瀏覽器還是兩個(gè)頁(yè)簽,
    比如 IE7這種支持多頁(yè)簽的,也就是在一個(gè)瀏覽器里面同時(shí)打開(kāi)多個(gè)頁(yè)簽的這種,是共用一個(gè)Session的,
    但是比如IE6這種一次只能打開(kāi)一個(gè)瀏覽器的,就沒(méi)有問(wèn)題,

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


    也算是解決了一個(gè)問(wèn)題吧:)

    這里標(biāo)記一下

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

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

     

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


    2、通過(guò)游標(biāo)遍歷所有數(shù)據(jù)庫(kù)
    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) | 評(píng)論 (0)編輯 收藏

    eclipse 注釋模版 設(shè)置


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

    常用的,一般兩個(gè)

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    struts2+spring2.5+hibernate 3.3

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

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

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

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

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


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

    通過(guò)MyEclipse生成annotation方式的entity類(lèi)

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

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

    posted @ 2009-11-15 19:02 風(fēng)人園 閱讀(500) | 評(píng)論 (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     }
    通過(guò)服務(wù)器端獲取模版文件的絕對(duì)路徑,然后通過(guò)response來(lái)輸出到頁(yè)面,就可以實(shí)現(xiàn)導(dǎo)出,這個(gè)比poi等等都簡(jiǎn)單很多,用起來(lái)比較舒服。
    服務(wù)器路徑的獲?。簉equest.getSession().getServletContext().getRealPath(name);
    這樣就可以獲得web目錄下某個(gè)文件的服務(wù)器端路勁。

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

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

    僅此記錄

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

    IronTrackSQL配置

    主要講一下在配置的過(guò)程中出現(xiàn)的問(wèn)題,基本的配置方式網(wǎng)上有很多。
    這里講spring的集成問(wèn)題。
    可能會(huì)出現(xiàn)兩個(gè)問(wè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>

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

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

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

    代碼質(zhì)量隨想

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

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

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

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

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


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

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

    ECP--之信息提示

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

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

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

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

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

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

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


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

    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ù)
    無(wú)返回
    */

    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 對(duì)
    */

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

        
    return args;
    }
                

    /*
    行雙擊方法,用戶選擇行數(shù)據(jù)。
    通過(guò)回調(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();
    }


    主頁(yè)面 域id通過(guò)json字符串跟url傳遞后彈出頁(yè)面
    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);

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

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

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

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

    主站蜘蛛池模板: 亚洲国产高清在线| 亚洲人成7777影视在线观看| 亚洲欧洲校园自拍都市| 99亚洲精品卡2卡三卡4卡2卡| 一级毛片不卡免费看老司机| 巨波霸乳在线永久免费视频 | 亚洲综合色丁香婷婷六月图片| 一级黄色免费网站| 黄页网站在线观看免费高清| 亚洲男人第一无码aⅴ网站| 亚洲精品国产成人| 一级毛片免费不卡| 中文字幕人成无码免费视频| 亚洲人成无码久久电影网站| 亚洲宅男天堂a在线| 国产VA免费精品高清在线| 久久WWW色情成人免费观看| 亚洲日韩精品A∨片无码| 亚洲熟伦熟女专区hd高清| 日本免费中文字幕| 国产免费拔擦拔擦8x| 亚洲国产精品成人综合色在线婷婷 | 亚洲AV无码专区亚洲AV桃| 午夜理伦剧场免费| 亚洲AV日韩精品一区二区三区| 亚洲精品456在线播放| 国产精品1024在线永久免费| 成人在线免费观看| 亚洲精品资源在线| APP在线免费观看视频| 又黄又爽无遮挡免费视频| 亚洲中文字幕久在线| 日韩视频在线观看免费| 亚洲免费一区二区| 亚洲综合国产成人丁香五月激情 | 污污网站18禁在线永久免费观看| 又粗又大又长又爽免费视频| 国产精品亚洲一区二区麻豆| 777成影片免费观看| 亚洲毛片αv无线播放一区| 成人午夜免费视频|