Java框架之Spring MVC(二)

来源:https://www.cnblogs.com/1693977889zz/archive/2017/12/31/8159067.html
-Advertisement-
Play Games

一、Spring MVC 驗證 JSR 303 是ajvaEE6 中的一項子規範 ,叫 Bean Validation 用於對javaBean中的欄位進行校驗。 官方的參考實現是: Hibernate Validator ,此實現和 Hibernate ORM 沒有任何關係 //http://hib ...


一、Spring MVC 驗證

JSR 303 是ajvaEE6 中的一項子規範 ,叫 Bean Validation 用於對javaBean中的欄位進行校驗。

官方的參考實現是: Hibernate Validator ,此實現和 Hibernate ORM 沒有任何關係  //http://hibernate.org/validator

Spring 3.x 也大力支持     JSR 303,使用的是  Hibernate Validator

1) 導包

4.3.1.Final 版本為例

// jboss-logging-3.1.0.CR2.jar

hibernate-validator-4.3.1.Final.jar

jboss-logging-3.1.0.jar、

validation-api-1.0.0.GA.jar

2) 配置文件

<mvc:annotation-driven validator="validator" />
    
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
                <property name="providerClass"  value="org.hibernate.validator.HibernateValidator"/>
                <property name="validationMessageSource" ref="validatemessageSource"/> //不設置則預設為classpath下的 ValidationMessages.properties
</bean>
               
<bean id="validatemessageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">  
               <property name="basename" value="classpath:validatemessages"/>  //配置驗證信息資源文件的路徑
               <property name="fileEncodings" value="utf-8"/>  
               <property name="cacheSeconds" value="120"/>   //緩存時間
</bean>

3) 創建校驗信息用的資源文件,本例在類路徑(src或config)下直接創建即可

validatemessages.properties 內容

name.not.empty=名字不能為空

age.not.inrange=年齡要在合適的範圍內

email.not.correct=郵箱格式不正確

email.not.empty=郵箱不能為空

4) 在實體類上,添加校驗

 public class UserInfo {
                    private  int id;
                    
                    @NotNull(message="用戶名不能為 null")
                    @NotEmpty(message="{name.not.empty}")
                    @Pattern(regexp="13\\d{9}",message="用戶名是按手機驗證的格式不對")
                    private String userName;   
                    
                    @Size(min=3,max=6,message="{password.not.inrange}")
                    private String password;
                    
                    @NotEmpty(message="{email.not.empty}")
                    @Email(message="{email.not.correct}")
                    private String note;
                    private String aihao;
                        
            //也可以將規則添在get 方法上    

5) 控制器 

//在添加用戶這個請求提交上來的時候
@RequestMapping(value="/addUser" ,method=RequestMethod.POST)
public String addUser(Model model, @Valid UserInfo user,BindingResult bResult){
                        if(bResult.hasErrors()){
                            List<ObjectError> errorList=    bResult.getAllErrors();
                            for(ObjectError e:errorList){
                                System.out.println(e.getDefaultMessage());
                            }
                            
                            model.addAttribute("errorList",errorList); //把錯誤信息傳到前臺
                            return "user_add";
                        }
                        
                        else{
                            return "success";
                        }
                    } 

說明: BindingResult 是Errors的子類

@Valid  和  BindingResult 的位置不要寫反

@Valid  寫成了 @Validated 實測也可以

6) 前端頁面

<c:forEach var="e" items="${errorList }">
                       ${e.defaultMessage}
                       </c:forEach>
                                   
                   <form action="${pageContext.request.contextPath }/addUser" method="post">
                   賬號:    <input type="text" name="userName"  /> 
                   密碼:  <input type="text" name="password"  /> 
                   備註:  <input type="text" name="note" /> 
                          <input type=submit value="提交" />
                   </form>

例子 如何詳細的顯示出錯信息

新建頁面 user_add_validate.jsp

 <%@ taglib uri="http://www.springframework.org/tags/form" prefix="x" %>
         <x:form method="post" action="${pageContext.request.contextPath }/addUser">
           賬號:<x:input path="userName" /> <x:errors path="userName" /><br>
            密碼:<x:input path="password" /> <x:errors path="password" /> <br>
           備註:<x:input path="note" /><x:errors path="note" /> <br>
           <input type=submit value="提交" />
    </x:form>

問題:

1) 如果直接訪問  user_add_validate.jsp 出現錯誤 

//java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?

原因是Spring環境沒初始化

<context-param>    
<param-name>contextConfigLocation</param-name>    
<param-value>classpath:springmvc-servlet.xml</param-value>    
</context-param>
<listener>    
         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

2) 需要指定  modelAttribute="user" 這個屬性

<x:form method="post" action="${pageContext.request.contextPath }/addUser" modelAttribute="user"  >
//上面也可以寫成 commandName="user"

3) 不能直接訪問 user_add_validate.jsp 要這樣:

@RequestMapping(value="/addUser",method=RequestMethod.GET)
public String addUser(@ModelAttribute("user") UserInfo user){   //@ModelAttribute("user") 必加
                return "user_add_validate";
}

4) 添加用戶的方法要如下

@RequestMapping(value="/addUser" ,method=RequestMethod.POST)
                public String addUser( @ModelAttribute("user") @Valid UserInfo user,BindingResult bResult){
                    if(bResult.hasErrors()){
                        return "user_add_validate";
                    }
                    else{
                        return "success";
                    }
                } 

附加:

分組校驗

問題: 當一個pojo類被多個業務方法使用,但它的驗證規則不同,如何處理?

可以採用分組校驗

1)定義分組 (其實就是定義介面,空介面就可以,一個介面就是一個分組)

public interface IVG1, IVG2

2)在pojo類上指定校驗屬於哪個分組

public class UserInfo(
@NotEmpty(message="用戶名不能為 null",groups={IVG1.class})

@Size(min=3,max=6,message="{password.not.inrange}",groups={IVG1.class,IVG2.class})
private String password;
                 ...
            }

3)在業務方法上指定驗證的時候使用哪個分組

@RequestMapping(value="/addUser" ,method=RequestMethod.POST)
public String addUser( @ModelAttribute("user") @Validated(value=IVG1.class) UserInfo user,BindingResult bResult){
                    if(bResult.hasErrors()){
                        return "user_add_validate";
                    }
                    else{
                        return "success";
                    }
                } 
//註意,用的是  @Validated 註解 不是 @Valid

二、Spring MVC 數據的回顯

(其實上例就是帶數據回顯的)

pojo類型的數據回顯

@RequestMapping(value="/addUser" ,method=RequestMethod.POST)
public String addUser( @ModelAttribute("user") UserInfo user){
                      ....
                    } 

 頁面的 from上也要加 modelAttribute 或 commondName

<x:form action="${pageContext.request.contextPath }/test" method="post" modelAttribute="user">
<x:input path="userName" />  //註意,要回顯示的數據必須用 這樣的標簽
<x:input path="password" />
</x:form>

 對於簡單類型

用 model.addAttribute(...)  即可

三、Spring MVC 異常處理

SpringMVC 提供全局異常處理器進行統一的異常處理

1) 在controller(Action)內部處理異常

-- login.jsp

 <form action="user/login" method="post" >
                        賬號:<input type="text" name="userName" /> 
                        密碼:<input type="text" name="password" />
                        <input type="submit" />

-- 自定義異常類 //不定義也可以

public class MyException extends Exception{
                        private String msg;
                        public MyException(String msg){
                            super(msg);
                            this.msg=msg;
                        }
                        
                        public void writeLog(){
                            System.out.println("---異常信息"+this.msg+"已經記錄-");
                        }
                    
                    }

-- action 中的處理

@RequestMapping(value="/login")
public String login(HttpSession session,String userName,String password) throws MyException {
                        UserInfo user=new UserDao().getLoginUser(userName, password);
                        if(user==null){
                            throw new MyException("用戶登錄失敗");  //如果登錄失敗,拋出異常
                            }
                            session.setAttribute("user", user);
                            return "success";
                        }
                        
                        @ExceptionHandler(value={MyException.class}) //這裡是進行異常處理的地方
                        public String exectionProcessAAA(MyException e,HttpServletRequest request){
                        request.setAttribute("e_msg", e.getMessage());
                        e.writeLog();
                        return "error" ;  //全局的一個異常處理頁面    
                    }

2) 全局異常處理

--在配置文件中加入配置

<bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">     
<property name="exceptionMappings">     
    <props>     
    <prop key="cat.beans.MyException">error_process_1</prop>   //可以看到,可以為每種異常指定一個result視圖
    <prop key="java.lang.Exception">error_process_2</prop>     
    <prop key="java.lang.Throwable">error_process_3</prop>     
    </props>     
</property>     
</bean>  

在異常處理頁面

${exception.message}  //這樣即可取出異常信息

四、Spring MVC 文件上傳

1) 單文件上傳

== 在配置文件中

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" >
                 <property name="defaultEncoding" value="UTF-8" />  //這裡面的這些屬性可以不用,一個都不寫也不會出錯
                 <property name="maxUploadSize" value="5400000" />
                 <property name="uploadTempDir" value="uploadTempDir" />
</bean>

== 頁面

<form method="post"  action="${pageContext.request.contextPath }/addUserWithImg"    enctype="multipart/form-data" >  
                   <input name="userName" /> 
                   <input name="password"/>  
                   <input name="note"/>  
                   <input type="file" name=upfile />  //註意,這個名字
                   <input type="submit" >
           </form> 

 == 控制層

@RequestMapping(value="/addUserWithImg",method=RequestMethod.POST)
public String addUserWithImg(UserInfo user,MultipartFile upfile /*註意這個名字要和表單元素同名*/ ,HttpServletRequest request ) 
throws IllegalStateException, IOException{ System.out.println(upfile); System.out.println("contentType:"+upfile.getContentType()); //image/pjepg System.out.println("name:"+upfile.getName()); //photo System.out.println("getOriginalFilename:"+upfile.getOriginalFilename()); //zhangsan.jpg System.out.println("getSize:"+upfile.getSize()); new UserDao().addUser(user); String path=request.getServletContext().getRealPath("/upload_files"); File targetFile=new File(path, upfile.getOriginalFilename()); upfile.transferTo(targetFile); return "success"; }

2) 多文件上傳  

<form method="post"  action="${pageContext.request.contextPath }/addUserWithMultImg"    enctype="multipart/form-data" >  
                       <input name="userName" /> 
                       <input name="password"/>  
                       <input name="note"/>  
                       
                       <input type="file" name=upfiles />
                       <input type="file" name=upfiles />
                       <input type="file" name=upfiles />
                       <input type="file" name=upfiles />
                       
                       <input type="submit" >
               </form> 
//註意要加上  @RequestParam
public String ddUserWithMultImg(UserInfo user,@RequestParam("upfiles") MultipartFile [] upfiles ,HttpServletRequest request )
throws IllegalStateException, IOException{ new UserDao().addUser(user); String path=request.getServletContext().getRealPath("/upload_files"); for(MultipartFile f:upfiles){ if(!f.isEmpty()){ File targetFile=new File(path, f.getOriginalFilename()); f.transferTo(targetFile); } } return "success"; }

五、Spring MVC 資源文件的引入

在配置文件中:

<mvc:resources location="/images/" mapping="/images/**" />
<mvc:resources location="/css/" mapping="css/**" />
//也可以放在一個文件夾中,統一的引入,如
<mvc:resources location="/resource/" mapping="resource/**" />

六、Spring MVC 關於json數據處理

1) 傳統方式的 ajax訪問和響應

//請求發起頁面  ajax_test.jsp
$(function(){
$("#btn1").click(function(){
$.ajax({
        url:"testAjax",
        type:"post",
        data:{userName:'admin',password:'123'},
        async:false,
        cache:false,
        dataType:"json",
        success:function(data){
        //alert(data);
        alert(data.id);
        alert(data.note);
                            }
                        });
                    });
                });
        
@RequestMapping("/testAjax")
public void testAjax(HttpServletRequest request,HttpServletResponse response) throws IOException{
                String userName=request.getParameter("userName");
                String password=request.getParameter("password");
                System.out.println(userName+":"+password);
                
                response.setContentType("text/html;charset=utf-8");
            //response.getWriter().print("這是普通數據");
                
                String jsonStr="{\"note\":\"這是備註\",\"id\":\"90\"}";
                response.getWriter().print(jsonStr);
            }

附註: 

@RequestBody 用來處理application/json 類型的請求內容

使用 @ResponseBody 的方式返回json 格式的數據

要導入包 spring mvc 4.1.4

jackson-annotations-2.4.4.jar、

jackson-core-2.4.4.jar、

jackson-databind-2.4.4.jar。

附 3.1 用的是

jackson-core-asl-1.9.11.jar 

jackson-mapper-asl-1.9.11.jar

//例一 從服務端查詢出一個userInfo對象返回
             //服務端
                @RequestMapping("/testAjax2") @ResponseBody  //這裡用 @ResponseBody 註解聲明返回json數據
                public UserInfo testAjax2(UserInfo u) {
                    UserInfo user=new UserDao().getLoginUser(u.getUserName(), u.getPassword());
                    return user;
                }
             //客戶端
                 $.ajax({
                    url:"testAjax2",
                    type:"post",
                    data:{userName:'aaa',password:'aaa'},  //在服務端,用的是pojo類型的對象接收的參數
                    async:false,
                    cache:false,
                    dataType:"json",
                       success:function(data){
                        alert(data.id);
                        alert(data.note);
                    }
                });
//例二 從服務端查詢一組對象返回
                @RequestMapping("/testAjax3") @ResponseBody
                public List<UserInfo> testAjax2() {
                    List<UserInfo> userList=new UserDao().getAllUser();
                    return userList;
                }
                                        
              $("#btn3").click(function(){
                        $.ajax({
                            url:"testAjax3",
                            type:"post",
            
                            async:false,
                            cache:false,
                            dataType:"json",
                            success:function(userList){ //從服務端返回的是一組對象
                                $.each(userList,function(key,user){
                                    $("#div1").append(user.id +"-"+user.userName+"-"+user.password+"<br />");
                                });
                            }
                        });
                    });

七、Spring MVC中 RESTful 風格

REST這個詞,是Roy Thomas Fielding在他2000年的博士論文中提出的,HTTP協議(1.0版和1.1版)的主要設計者、Apache伺服器軟體的作者之一、Apache基金會的第一任主席。長期以來,軟體研究主要關註軟體設計的分類、設計方法的演化,很少客觀地評估不同的設計選擇對系統行為的影響。而相反地,網路研究主要關註系統之間通信行為的細節、如何改進特定通信機制的表現,常常忽視了一個事實,那就是改變應用程式的互動風格比改變互動協議,對整體表現有更大的影響。我這篇文章的寫作目的,就是想在符合架構原理的前提下,理解和評估以網路為基礎的應用軟體的架構設計,得到一個功能強、性能好、適宜通信的架構

REST,即Representational State Transfer的縮寫。我們對這個片語的翻譯是"表現層狀態轉化"。 

如果一個架構符合REST原則,就稱它為RESTful架構。關於 Representational State Transfer (表現層狀態轉化) 的理解。

1)REST的名稱"表現層狀態轉化"中,省略了主語。"表現層"其實指的是"資源"(Resources)的"表現層"。

網路上的一個具體信息,可以用一個URI(統一資源定位符)指向它

2) Representation 表現層

"資源"是一種信息實體,它可以有多種外在表現形式。我們把"資源"具體呈現出來的形式,叫做它的"表現層"(Representation)。

比如,文本可以用txt格式表現,也可以用HTML格式、XML格式

URI只代表資源的實體,不代表它的形式。嚴格地說,有些網址最後的".html"尾碼名是不必要的 因為這個尾碼名錶示格式,屬於 "表現層" 範疇,而URI應該只代表"資源"的位置。它的具體表現形式,應該在HTTP請求的頭信息中用Accept和Content-Type欄位指定,這兩個欄位才是對"表現層"的描述。

3) State Transfer 狀態轉化

HTTP協議,是一個無狀態協議。這意味著,所有的狀態都保存在伺服器端。因此,如果客戶端想要操作伺服器,必須通過某種手段,讓伺服器端發生"狀態轉化"(State Transfer)。而這種轉化是建立在表現層之上的,所以就是"表現層狀態轉化"。客戶端用到的手段,只能是HTTP協議。具體來說,就是HTTP協議裡面,四個表示操作方式的動詞:GET、POST、PUT、DELETE。它們分別對應四種基本操作:

GET用來獲取資源,POST用來新建資源(也可以用於更新資源),PUT用來更新資源,DELETE用來刪除資源。

綜合上面的解釋,我們總結一下什麼是RESTful架構:

(1)每一個URI代表一種資源;

(2)客戶端和伺服器之間,傳遞這種資源的某種表現層;

(3)客戶端通過四個HTTP動詞,對伺服器端資源進行操作,實現"表現層狀態轉化"。

http://localhost:8080/myweb/userAction_show.action?id=5  

rest 風格 

http://www.douban.com/photos/album/49432287/   這是豆瓣上的url rest風格

查詢用戶

http://localhost:8080/myweb/user/5 

刪除用戶

http://localhost:8080/myweb/user/5/delete

//例子

@RequestMapping("/get_user/{id}/{flag}") public String getUser(@PathVariable("id") int idAAA, @PathVariable("flag") String flagAAA){ System.out.println(idAAA +":"+flagAAA); return "success"; }

 請求的url

http://localhost:8080/springmvc-03/get_user/10/search

如果不傳  PathVariable 指定的參數,會報404

八、Spring MVC 攔截器

SpringMVC 中的Interceptor 攔截器也是相當重要和相當有用的,它的主要作用是攔截用戶的請求併進行相應的處理。比如通過它來進行許可權驗證,或者是來判斷用戶是否登陸,或者是像12306 那樣子判斷當前時間是否是購票時間。

方式一: 用實現 HandlerInterceptor  介面的方式

方式二: 繼承抽象類HandlerInterceptorAdapter  (Spring 提供的類,它實現了 HandlerInterceptor)

方式三: 實現WebRequestInterceptor 介面或繼承實現了該介面的類

例子:

1) 攔截器聲明

public class MyInterceptor implements HandlerInterceptor {
            /*==在Controller 方法被調用之前執行,一般用來進行身份驗證,授權等
              == SpringMVC中的Interceptor 攔截器是鏈式的,可以同時存在多個Interceptor,並根據聲明的前後順序依次執行
              == 而且所有的Interceptor中的 preHandle 方法都會在 Controller方法調用之前調用
              == SpringMVC的這種Interceptor鏈式結構也是可以進行中斷的,preHandle的返回值為false的時候整個請求就結束了 */
            public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
                    Object arg2) throws Exception {
                System.out.println("preHandle");
                return true;
            }
        
            /* 一般在處理公用的模型數據,統一指定視圖等操作的時候用
             == 在preHandle方法返回值為true的時候才會執行。
             == 它的執行時間是在是在Controller的方法調用之後,DispatcherServlet進行視圖的渲染之前執行
             == 可以對ModelAndView進行操作。
             == 這個方法的鏈式結構跟正常訪問的方向是相反的,也就是說先聲明的Interceptor攔截器該方法反而會後調用,這跟Struts2裡面的攔截器的執行過程有點像          
            */
            public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
                    Object arg2, ModelAndView modelAndView) throws Exception {
                System.out.println("postHandle");    
            }
            
            /*
             == 在preHandle方法返回值為true的時候才會執行。
             == 該方法將在整個請求完成之後,也就是DispatcherServlet渲染了視圖執行,  
             == 這個方法的主要作用是用於清理資源的,統一的日誌及異常處理等    */
            public void afterCompletion(HttpServletRequest arg0,
                    HttpServletResponse arg1, Object arg2, Exception arg3)
                    throws Exception {
                System.out.println("afterCompletion");    
            }
        }

 2) 在配置文件中加入配置

<mvc:interceptors>   
//如果有 多個攔截器,順序執行   
<mvc:interceptor>   
// 如果不配置或/*,將攔截所有的Controller
<mvc:mapping path="/searchall_forupdate" /> path 配置攔的是請求的url
//<mvc:mapping path="/**" /> 所有的url包擴子url 
<bean class="cat.interceptor.MyInterceptor"></bean>   
</mvc:interceptor>   

</mvc:interceptors> 
//例子,驗證用戶是否登錄
        public class MySessionInterceptor implements HandlerInterceptor {
                    public void afterCompletion(HttpServletRequest arg0,
                            HttpServletResponse arg1, Object arg2, Exception arg3)
                            throws Exception {    }
                
                
                    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
                            Object handler, ModelAndView arg3) throws Exception {}
                
                
                    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                            Object obj) throws Exception {
                        String url=request.getRequestURI();
                        System.out.println(url);
                        if(url.contains("login")){  //如果用戶發的是登錄的請求,則直接放行
                            return true;
                        }
                        else{
                            UserInfo user=(UserInfo)request.getSession().getAttribute("user");
                            if(user!=null){
                                return true;
                            }
                            else{
                                request.setAttribute("msg", "請登錄");
                                request.getRequestDispatcher("login.jsp").forward(request, response);
                                return false;
                            }
                        }
                    }

上面的攔截器的配置文件

<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
    <bean class="cat.interceptor.MyInterceptor"></bean>
</mvc:interceptor>
                    
<mvc:interceptor>
<mvc:mapping path="/**" />
    <bean class="cat.interceptor.MySessionInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>  

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

-Advertisement-
Play Games
更多相關文章
  • 今天想到了一個問題的演算法,就自己去敲了代碼運行,這個問題是經典的斐波那契數列求值。用了for迴圈、遞歸、尾遞歸運行了出來,突然想到一個問題for迴圈的時間複雜度、遞歸的時間複雜度、尾遞歸的時間複雜度那個更小呢?也就是那個演算法更加節省時間效率更高呢? 於是我就把這三個做了比較,發現for迴圈的效率更高 ...
  • #配置模塊#創建import configparserconfig = configparser.ConfigParser()#添加config["DEFAULT"] = {'ServerAliveInterval':'45', 'Compression':'yes', 'CompressionLe ...
  • 如果一個程式只包含固定數量的且其生命期都是己知的對象. 那麼這是一個非常簡單的程式。 通常,程式總是根據運行時才知道的某些條件去創建新對象。在此之前,不會知道所需對象的數量,甚至不知道確切的類型。為解決這個普遍的編程問題,需要在任意時刻和任意位置創建任意數量的對象。所以,就不能依靠創建命名的引用來持 ...
  • 現在正式開始第一篇博客。 先看一個式子: x+y+z=5 2*x+3*y+z=11 x+4*y+z=11 如果問人怎麼解,人家肯定會告訴你,消元啦~ 實際上消元有兩種:加減消元和帶入消元 在電腦上編程實現的話,加減消元會簡單一些。 這樣就有了我們的高斯消元法。 高斯消元就是有多個加減消元構成的,能夠 ...
  • 1.Java I/O 概述 2.Java I/O File類 3.Java I/O 獲取文件目錄並寫入到文本 4.Java I/O 輸入與輸出 5.Java I/O 複製文本文件 6.Java I/O 添加屬性和有用的介面 7.Java I/O Reader & Writer(字元流) 8.Java ...
  • 位元組流、字元流涉及的類比較多,比較容易混淆。因此,有必要針對何時使用位元組流、何時使用字元流、何時使用Buffer類的流做一個歸納。要歸納它們,無需過多的語言,只需抓住它們的重點和特性即可。 在決定何時使用何種類時,以下幾個問題需要考慮清楚。 數據源:表示輸入,或稱為讀。可提供使用的兩個父類為Inpu ...
  • 一、原理 Spring MVC基於模型-視圖-控制器(Model-View-Controller,MVC)模式實現,它能夠幫你構建像Spring框架那樣靈活和松耦合的Web應用程式,將請求處理的邏輯和視圖中的渲染實現解耦。 1、DispatcherServlet是Spring MVC的核心 。Spr ...
  • 本人一直在走.NET技術路線,考慮到後期公司搞JAVA項目,也算是進行技術災備,開始對JAVA技術進行關註。萬事開頭難,也是上來一頭包。沒辦法,頂著上吧。上面開始分給我任務了。就是對後期項目報表進行方案選型。哥們兒花了兩周的時間總算是提供了幾個方案,以供相關人員選擇。特將此次過程整理如下: 一、萬事 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...