Struts 2 入門

来源:http://www.cnblogs.com/dkz1/archive/2017/12/06/7992564.html
-Advertisement-
Play Games

Struts 2 入門: 一:Struts 2執行流程: 1 客戶端發送請求; 2這個請求經過一系列的過濾器(Filter)(這些過濾器中有一個叫做ActionContextCleanUp的可選過濾器,這個過濾器對於Struts2和其他框架的集成很有幫助,例如:SiteMeshPlugin) 3接著 ...


Struts 2  入門:

一:Struts 2執行流程:

1 客戶端發送請求;
2這個請求經過一系列的過濾器(Filter)(這些過濾器中有一個叫做ActionContextCleanUp的可選過濾器,這個過濾器對於Struts2和其他框架的集成很有幫助,例如:SiteMeshPlugin)
3接著FilterDispatcher被調用,FilterDispatcher詢問ActionMapper來決定這個請是否需要調用某個Action。FilterDispatcher的功能如下:

       (1)執行Actions
       (2)清除ActionContext
       (3)維護靜態內容
       (4)清除request生命周期內的XWork的interceptors

4如果ActionMapper決定需要調用某個Action,FilterDispatcher把請求的處理交給ActionProxy
5 ActionProxy通過ConfigurationManager詢問框架的配置文件,找到需要調用的Action類
6ActionProxy創建一個ActionInvocation的實例。
7ActionInvocation實例使用命名模式來調用,在調用Action的過程前後,涉及到相關攔截器(Intercepter)的調用。
8一旦Action執行完畢,ActionInvocation負責根據struts.xml中的配置找到對應的返回結果。返回結果通常是(但不總是,也可能是另外的一個Action鏈)一個需要被表示的JSP或者FreeMarker的模版。在表示的過程中可以使用Struts2框架中繼承的標簽。在這個過程中需要涉及到ActionMapper

 

 

二:攔截器與過濾器:

 

1、攔截器是基於java反射機制的,而過濾器是基於函數回調的。2、過濾器依賴於servlet容器,而攔截器不依賴於servlet容器。
3、攔截器只能對Action請求起作用,而過濾器則可以對幾乎所有請求起作用。
4、攔截器可以訪問Action上下文、值棧里的對象,而過濾器不能。
5、在Action的生命周期中,攔截器可以多次調用,而過濾器只能在容器初始化時被調用一次。

 

在上述過程中所有的對象(Action,Results,Interceptors,等)都是通過ObjectFactory來創建的。Struts2的目標很簡單--使Web開發變得更加容易。為了達成這一目標,Struts2中提供了很多新特性,比如智能的預設設置、annotation的使用以及"慣例重於配置"原則的應用,而這一切都大大減少了XML配置。Struts2中的Action都是POJO,這一方面增強了Action本身的可測試性,另一方面也減小了框架內部的耦合度,而HTML表單中的輸入項都被轉換成了恰當的類型以供action使用。開發人員還可以通過攔截器(可以自定義攔截器或者使用Struts2提供的攔截器)來對請求進行預處理和後處理,這樣一來,處理請求就變得更加模塊化,從而進一步減小耦合度。模塊化是一個通用的主題--可以通過插件機制來對框架進行擴展;開發人員可以使用自定義的實現來替換掉框架的關鍵類,從而獲得框架本身所不具備的功能;可以用標簽來渲染多種主題(包括自定義的主題);Action執行完畢以後,可以有多種結果類型--包括渲染JSP頁面,Velocity和Freemarker模板,但並不僅限於這些

 

三:Struts  2概述

  1. Struts 2缺陷:

(1.)表單成支持單一

(2.)對Servlet  api的依賴

(3.)不利於代碼的重用

2.Struts 2的獲取:

         官方網站:http://struts.apache.org

         資源包:http://strust.apache.org/download.cgi

  1. Strust 2項目的基礎jar文件:

文件名      ---------------------     說明

Struts2-core-xxx.jar :Struts2框架的核心類庫。

xwork-core-xxx.jar:XWork類庫,Struts2的構建基礎。

Ognl-xxx.jar:Struts2使用的一種表達式語音類庫

Freemarker-xxx.jar:Struts2的標簽模板使用類庫

Javassist-xxx.GA.jar:對位元組代碼進行處理

Commons-fileupload-xxx.jar:文件上傳時需要使用

Commons-io-xxx.jar:Java  Io擴展

Commons-lang-xxx.jar:包含一些資料庫類型的工具類。

四:Action介面中常量字元串的邏輯含義

         常量---------值------------------------------邏輯含義

         SUCCESS:  success:表示程式處理異常,並返回給用戶成功後的結果

         NONE    none    表示處理正常結束,但不返回給用戶任何提示

         ERROR   error     表示處理結果失敗

         INPUT   input    表示需要更多用戶輸入才能順利執行

         LOGIN   login    表示需要用戶正確登錄後才能順利執行   

五:Struts 2配置詳解

<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd" >
<struts>

    <!-- include節點是struts2中組件化的方式 可以將每個功能模塊獨立到一個xml配置文件中 然後用include節點引用 -->
    <include file="struts-default.xml"></include>
    
    
    <!-- package提供了將多個Action組織為一個模塊的方式
        package的名字必須是唯一的 package可以擴展 當一個package擴展自
        另一個package時該package會在本身配置的基礎上加入擴展的package
        的配置 父package必須在子package前配置 
        name:package名稱
        extends:繼承的父package名稱
        abstract:設置package的屬性為抽象的 抽象的package不能定義action 值true:false
        namespace:定義package命名空間 該命名空間影響到url的地址,例如此命名空間為/test那麼訪問是的地址為http://localhost:8080/struts2/test/XX.action
     -->
    <package name="com.kay.struts2" extends="struts-default" namespace="/test">
        <interceptors>
            <!-- 定義攔截器 
                name:攔截器名稱
                class:攔截器類路徑
             -->
            <interceptor name="timer" class="com.kay.timer"></interceptor>
            <interceptor name="logger" class="com.kay.logger"></interceptor>
            <!-- 定義攔截器棧 -->
            <interceptor-stack name="mystack">
                <interceptor-ref name="timer"></interceptor-ref>
                <interceptor-ref name="logger"></interceptor-ref>
            </interceptor-stack>
        </interceptors>
        
        <!-- 定義預設的攔截器 每個Action都會自動引用
         如果Action中引用了其它的攔截器 預設的攔截器將無效 -->
        <default-interceptor-ref name="mystack"></default-interceptor-ref>
        
        
        <!-- 全局results配置 -->
        <global-results>
            <result name="input">/error.jsp</result>
        </global-results>
        
        <!-- Action配置 一個Action可以被多次映射(只要action配置中的name不同)
             name:action名稱
             class: 對應的類的路徑
             method: 調用Action中的方法名
        -->
        <action name="hello" class="com.kay.struts2.Action.LoginAction">
            <!-- 引用攔截器
                name:攔截器名稱或攔截器棧名稱
             -->
            <interceptor-ref name="timer"></interceptor-ref>
        
            <!-- 節點配置
                name : result名稱 和Action中返回的值相同
                type : result類型 不寫則選用superpackage的type struts-default.xml中的預設為dispatcher
             -->
         <result name="success" type="dispatcher">/talk.jsp</result>
         <!-- 參數設置 
             name:對應Action中的get/set方法 
         -->
         <param name="url">http://www.sina.com</param>
        </action>
    </package>
</struts>

補充:

struts.xml是我們在開發中利用率最高的文件,也是Struts2中最重要的配置文件。

一下分別介紹一下幾個struts.xml中常用到的標簽

1、<include>

利用include標簽,可以將一個struts.xml配置文件分割成多個配置文件,然後在struts.xml中使用<include>標簽引入其他配置文件。

比如一個網上購物程式,可以把用戶配置、商品配置、訂單配置分別放在3個配置文件user.xml、goods.xml和order.xml中,然後在struts.xml中將這3個配置文件引入:

struts.xml:

?

1

2

3

4

5

6

7

8

9

10

<?xmlversion="1.0"encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

    "http://struts.apache.org/dtds/struts-2.0.dtd">

  

<struts>

    <includefile="user.xml"/>

    <includefile="goods.xml"/>

    <includefile="order.xml"/>

</struts>

 

user.xml:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<?xmlversion="1.0"encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

    "http://struts.apache.org/dtds/struts-2.0.dtd">

  

<struts>

    <packagename="wwfy"extends="struts-default">

        <actionname="login"class="wwfy.user.LoginAction">

            <!--省略Action其他配置-->

        </action>

        <actionname="logout"class="wwfy.user.LogoutAction">

            <!--省略Action其他配置-->

        </action>

    </package>

</struts>

 

2、<constant>

在之前提到struts.properties配置文件的介紹中,我們曾經提到所有在struts.properties文件中定義的屬性,都可以配置在struts.xml文件中。而在struts.xml中,是通過<constant>標簽來進行配置的:

?

1

2

3

4

5

6

7

8

9

10

11

12

<?xmlversion="1.0"encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

    "http://struts.apache.org/dtds/struts-2.0.dtd">

  

<struts>

    <!--設置開發模式-->

    <constantname="struts.devMode"value="true"/>

    <!--設置編碼形式為GB2312-->

    <constantname="struts.i18n.encoding"value="GB2312"/>

    <!--省略其他配置信息-->

</struts>

 

3、<package>

1、包屬性介紹

在Struts2框架中是通過包來管理action、result、interceptor、interceptor-stack等配置信息的。包屬性如下:

屬性

是否必需

描述

name

包名,作為其它包應用本包的標記

extends

設置本包繼承其它包

namespace

設置包的命名空間

abstact

設置為抽象包

 

2、extends屬性的詳解

當一個包通過配置extends屬性繼承了另一個包的時候,該包將會繼承父包中所有的配置,包括action、result、interceptor等。

由於包信息的獲取是按照配置文件的先後順序進行的,所以父包必須在子包之前被定義。

通常我們配置struts.xml的時候,都繼承一個名為“struts-default.xml”的包,這是struts2中內置的包。

 

3、namespace的詳解

namespace主要是針對大型項目中Action的管理,更重要的是解決Action重名問題,因為不在同一個命名空間的Action可以使用相同的Action名的。

1)如果使用命名空間則URL將改變

比如我們有一下配置文件

?

1

2

3

4

5

<packagename="wwfy"extends="struts-default">

    <actionname="login"class="wwfy.action.LoginAction">

        <result>/success.jsp</result>

    </action>

</package>

 

則此配置下的Action的URL為http://localhost:8080/login.action

 

假如為這個包指定了命名空間

?

1

2

3

4

5

<packagename="wwfy"extends="struts-default"namespace="/user">

    <actionname="login"class="wwfy.action.LoginAction">

        <result>/success.jsp</result>

    </action>

</package>

 

則此配置下的Action的URL為http://localhost:8080/user/login.action

2)預設命名空間

Struts2中如果沒有為某個包指定命名空間,該包使用預設的命名空間,預設的命名空間總是""。

3)指定根命名空間

當設置了命名空間為“/”,即指定了包的命名空間為根命名空間時,此時所有根路徑下的Action請求都會去這個包中查找對應的資源信息。

假若前例中路徑為http://localhost:8080/login.action則所有http://localhost:8080/*.action都會到設置為根命名空間的包中尋找資源。

 

4、<action>與<result>

1、<action>屬性介紹

屬性名稱

是否必須

功能描述

name

請求的Action名稱

class

Action處理類對應具體路徑

method

指定Action中的方法名

converter

指定Action使用的類型轉換器

如果沒有指定method則預設執行Action中的execute方法。

2、<result>屬性介紹

屬性名稱

是否必須

功能描述

name

對應Action返回邏輯視圖名稱,預設為success

type

返回結果類型,預設為dispatcher

 

3、通配符的使用

隨著result的增加,struts.xml文件也會隨之變得越來越複雜。那麼就可以使用通配符來簡化配置:

例如下麵這個案例:

Action為Test.java

 

?

1

2

3

4

5

6

7

8

9

10

11

12

13

publicclassTest {

    publicString test1(){

        return"result1";

    }

      

    publicString test2(){

        return"result2";

    }

      

    publicString test3(){

        return"result3";

    }

}

 

struts.xml中配置為

?

1

2

3

4

5

<packagename="wwfy"extends="struts-default">

    <actionname="test*"class="wwfy.action.test{1}">

        <resultname="result{1}">/result{1}.jsp</result>

    </action>

</package>

4、訪問Action方法的另一種實現方式

在Struts2中如果要訪問Action中的指定方法,還可以通過改變URL請求來實現,將原本的“Action名稱.action”改為“Action名稱!方法名稱.action”在struts.xml中就不需要指定方法名了。

 

5、<exception-mapping>與<global-exception-mapping>

這兩個標簽都是用來配置發生異常時對應的視圖信息的,只不過一個是Action範圍的,一個是包範圍的,當同一類型異常在兩個範圍都被配置時,Action範圍的優先順序要高於包範圍的優先順序.這兩個標簽包含的屬性也是一樣的:

屬性名稱

是否必須

功能描述

name

用來表示該異常配置信息

result

指定發生異常時顯示的視圖信息,這裡要配置為邏輯視圖

exception

指定異常類型

 

兩個標簽的示例代碼為:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<?xmlversion="1.0"encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

    "http://struts.apache.org/dtds/struts-2.0.dtd">

  

<struts>

    <packagename="default"extends="struts-default">

        <global-exception-mappings>

            <exception-mappingresult="邏輯視圖"exception="異常類型"/>

        </global-exception-mappings>

        <actionname="Action名稱">

            <exception-mappingresult="邏輯視圖"exception="異常類型"/>

        </action>

    </package>

</struts>

 

6、<default-class-ref>

當我們在配置Action的時候,如果沒有為某個Action指定具體的class值時,系統將自動引用<default-class-ref>標簽中所指定的類。在Struts2框架中,系統預設的class為ActionSupport,該配置我們可以在xwork的核心包下的xwork-default.xml文件中找到。

有特殊需要時,可以手動指定預設的class

?

1

2

3

4

5

6

7

packagewwfy.action;

  

publicclassDefaultClassRef {

    publicvoidexecute(){

        System.out.println("預設class開始執行……");

    }

}

 

在struts.xml中配置

 

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

<?xmlversion="1.0"encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

    "http://struts.apache.org/dtds/struts-2.0.dtd">

  

<struts>

    <packagename="wwfy"extends="struts-default">

        <!-- 指定預設class為Test -->

        <default-class-refclass="wwfy.action.DefaultClassRef"/>

        <actionname="test1">

            <result>/index.jsp</result>

        </action>

    </package>

</struts>

 

7、<default-action-ref>

如果在請求一個沒有定義過的Action資源時,系統就會拋出404錯誤。這種錯誤不可避免,但這樣的頁面並不友好。我們可以使用<default-action-ref>來指定一個預設的Action,如果系統沒有找到指定的Action,就會指定來調用這個預設的Action。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

<?xmlversion="1.0"encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

    "http://struts.apache.org/dtds/struts-2.0.dtd">

  

<struts>

    <packagename="wwfy"extends="struts-default">

          

        <default-action-refname="acctionError"></default-action-ref>

        <actionname="acctionError">

            <result>/jsp/actionError.jsp</result>

        </action>

    </package>

</struts>

 

8、<default-interceptor-ref>

該標簽用來設置整個包範圍內所有Action所要應用的預設攔截器信息。事實上我們的包繼承了struts-default包以後,使用的是Struts的預設設置。我們可以在struts-default.xml中找到相關配置:

?

1

<default-interceptor-refname="defaultStack"/>

 

在實際開發過程中,如果我們有特殊的需求是可以改變預設攔截器配置的。當時一旦更改這個配置,“defaultStack”將不再被引用,需要手動最加。

 

9、<interceptors>

通過該標簽可以向Struts2框架中註冊攔截器或者攔截器棧,一般多用於自定義攔截器或攔截器棧的註冊。該標簽使用方法如下:

?

1

2

3

4

5

6

<interceptors>

    <interceptorname="攔截器名"class="攔截器類"/>

    <interceptor-stackname="攔截器棧名">

        <interceptor-refname="攔截器名">

    </interceptor-stack>

</interceptors>

 

10、<interceptor-ref>

通過該標簽可以為其所在的Action添加攔截器功能。當為某個Action單獨添加攔截器功能後,<default-interceptor-ref>中所指定的攔截器將不再對這個Action起作用。

 

11、<global-results>

該標簽用於設置包範圍內的全局結果集。在多個Action返回相同邏輯視圖的情況下,可以通過<global-results>標簽統一配置這些物理視圖所對應的邏輯視圖。

?

1

2

3

4

5

6

7

8

9

10

11

12

<?xmlversion="1.0"encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

    "http://struts.apache.org/dtds/struts-2.0.dtd">

  

<struts>

    <packagename="wwfy"extends="struts-default">

        <global-results>

            <resultname="test">/index.jsp</result>

        </global-results>

    </package>

</struts>

 六:Struts 2訪問Servlet  API對象

  1. 最常用的Servlet  api三個介面:

HttpServletRequest

HttpSession

ServletContext

  1. Servlet  API解耦的訪問方式:

//解偶方式獲得session request

ActionContext context=ActionContext.getContext();

//獲得session

Map session=context.getSession();

//獲得request

         Map request=(Map)context.get("request");

  1. 關於註入的概念:

簡單的說就是通過框架自動對Action屬性進行賦值,和Spring中的依賴註入類似。

七:Struts 2標簽:

1.<%@ taglib  prefix=”s” uri=”/struts-tags”%>

2.UI標簽:可分為三大部分:

         表單標簽

         非表單標簽

Ajax標簽

 

表單標簽的圖解:

標簽

說明

<s:form>…..</s:form>

獲取相應的form值

<s:textfield>……..</>

文本框輸入

<s:password>……..</>

密碼框輸入

<s:textarea>………</>

文本域輸入

<s:radio>……………..</>

單選按鈕

<s:checkbox>………….</>

覆選框

<s:submit>………….</>

提交按鈕

<s:reset>………………</>

重置按鈕

<s:hidden>……………</>

隱藏域標簽

 

 

  1. 通用標簽:

 

名稱

標簽

根據表達式的值,判斷將要執行的內容        

                

條件標簽

<s:if>…..</>

<s:elseif>……</>

<s:else>……….</>

 

迭代標簽

 <s:iterator>………….</>

用於遍歷集合

 

 

 

註意:

(1.)三個標簽中只有<s:if……./>標簽可以單獨使用。

(2.)三個標簽可以組合使用<s:elseif……../>標簽與<s:else……/>標簽不能單獨使用,必須與<s:if…../>標簽結合才能使用。

(3.)<s:if……./>標簽可以與多個<s:elseif……./>結合使用,但是只能與一個<s:else……../>標簽結合在一起。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 之前做過一個項目,其中一項功能是查看社交信息流帖子。很多帖子中都包含視頻,手機上播放視頻後,會有層級混亂的問題。 當時的解決方案是動態的將視頻放入Iframe中。以後如果有其他的解決方式會追加進來。 視頻使用的是16:9的比例。 示例: HTML: CSS: JS: ...
  • ECMA script(發音為“ek-ma-script”)和 javaScript 的關係以及和瀏覽器的關係 雖然JavaScript和ECMAscript通常被人們用來表達相同的含義,但javacript的含義卻比ECMA-script多很多。一個完整的JavaScript實現應該由下列三個不用 ...
  • 採用MUI開發APP時,頁面跳轉傳值無疑是很多初學者遇到的難題之一,我在開發時也遇到了同樣的問題,所以在這裡總結了一下,方便以後查閱。 一、頁面預載入時傳值 通過上述方法預載入頁面,然後在載入的那個頁面中接受參數。 二、通過mui.openWindow打開視窗向頁面傳遞參數 這種傳值方法通常我們的做 ...
  • 今天看到一個kata,提出一個“emirps”的概念:一個質數倒轉後得到的是一個不同的質數,這個數叫做“emirps”。 例如:13,17是質數,31,71也是質數,13和17是“emirps”。 但是質數757,787,797是迴文質數,這意味著反轉的數字與原始數字相同,所以它們不被認為是“emi ...
  • 說明:這裡主要介紹jQuery的分頁插件twbsPagination。當然了還有其他的分頁插件,感覺上這個插件還是比較簡單易用的。 步驟一:建立page.jsp頁面,引用jquery.twbsPagination.js,page.js <script src="<%=basePath%>js/jqu ...
  • 裝飾者模式: 動態地將責任附加到對象上。想要擴展功能,裝飾者提供有別於繼承的另一種選擇。 舉例: 不知道大家學校的食堂是什麼點餐制度(或者大家就直接想成吃火鍋,我們要火鍋料 + 配菜),我們學校的點餐是:主食大米 + 你想要吃的菜(每個菜都裝在小碗中)。現在問題來了,我點的是大米(0.8元) + 紅 ...
  • Observer Pattern(觀察者模式)定義: 在對象之間定義一對多的依賴,這樣一來,當一個對象改變狀態,依賴它的對象都會收到通知,並自動更新。 乾說定義肯定沒有舉例理解的透徹。想到Observer Pattern(觀察者模式)就來舉個生活中的例子來幫助我們更好消化和理解其具體含義。 舉例: ...
  • 看到這個問題,作為IT行業中的從業者,我的腦海中無數個有關產品經理的段子在策馬奔騰呼嘯而來,然鵝,基本都是黑產品的梗,那麼我們來分析一下為什麼想“打”產品經理呢?如果你是設計師、程式員、測試、美工、運營等需要和產品合作的任意一員。 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...