Java框架之Spring MVC(一)

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

一、Spring簡介 Spring MVC是當前最優秀的 MVC 框架,自從Spring 2.5 版本發佈後,由於支持註解配置,易用性有了大幅度的提高。Spring 3.0 更加完善,實現了對 Struts 2 的超越。現在越來越多的開發團隊選擇了Spring MVC。 1)Spring3 MVC使 ...


一、Spring簡介

Spring MVC是當前最優秀的 MVC 框架,自從Spring 2.5 版本發佈後,由於支持註解配置,易用性有了大幅度的提高。Spring 3.0 更加完善,實現了對 Struts 2 的超越。現在越來越多的開發團隊選擇了Spring MVC。

1)Spring3 MVC使用簡單,學習成本低。學習難度小於Struts2,Struts2用不上的多餘功能太多

2)Spring3 MVC很容易就可以寫出性能優秀的程式,Struts2要處處小心才可以寫出性能優秀的程式(指MVC部分)

3)靈活

√讓我們能非常簡單的設計出乾凈的Web層和薄薄的Web層;

√進行更簡潔的Web層的開發;

√天生與Spring框架集成(如IoC容器、AOP等);

√提供強大的約定大於配置的契約式編程支持;

√能簡單的進行Web層的單元測試;

√支持靈活的URL到頁面控制器的映射;

√非常容易與其他視圖技術集成,如Velocity、FreeMarker等等,因為模型數據不放在特定的API里,而是放在一個Model里(Map數據結構實現,因此很容易被其他框架使用);

√非常靈活的數據驗證、格式化和數據綁定機制,能使用任何對象進行數據綁定,不必實現特定框架的API;

√提供一套強大的JSP標簽庫,簡化JSP開發;

√支持靈活的本地化、主題等解析;

√更加簡單的異常處理;

√對靜態資源的支持;

√支持Restful風格

前端控制器是DispatcherServlet;

應用控制器其實拆為處理器映射器(Handler Mapping)進行處理器管理和視圖解析器(View Resolver)進行視圖管理;

頁面控制器/動作/處理器為Controller介面(僅包含ModelAndView handleRequest(request, response) 方法)的實現(也可以是任何的POJO類);

支持本地化(Locale)解析、主題(Theme)解析及文件上傳等;提供了非常靈活的數據驗證、格式化和數據綁定機制;

提供了強大的約定大於配置(慣例優先原則)的契約式編程支持。

二、配置核心控制器

1) 導包,配置環境

aopalliance-1.0.jar

bean-validator.jar

commons-fileupload-1.2.2.jar

commons-io-2.1.jar

commons-logging-1.2.jar

javax.servlet.jsp.jstl-1.2.1.jar

jsp-api-2.1.jar

jstl-1.2.jar

jstl-api-1.2.jar

mysql-connector-java-5.1.7-bin.jar

servlet-api-2.5.jar

spring-aop-4.1.4.RELEASE.jar

spring-beans-4.1.4.RELEASE.jar

spring-context-4.1.4.RELEASE.jar

spring-core-4.1.4.RELEASE.jar

spring-expression-4.1.4.RELEASE.jar

spring-web-4.1.4.RELEASE.jar

spring-webmvc-4.1.4.RELEASE.jar

standard-1.1.2.jar

2)

配置核心控制器

配置處理器映射器 handler Mapping

配置處理器適配器 handler Adapter

配置視圖解析器

2.1 配置核心控制器

在 web.xml 中

<servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!--  在 spring-webmvc-4.1.4.RELEASE.jar 下 -->
<init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc-servlet.xml</param-value> //手動指定配置文件的路徑
</init-param>
</servlet>
<servlet-mapping>
        <servlet-name>springmvc</servlet-name> 
        <url-pattern>/</url-pattern> // 可以寫成*.do,*.action,但不能寫成杠* 
</servlet-mapping>

說明:

1 預設情況下,載入配置文件是 WEB-INF/servlet名稱-servlet.xml   //springMVC-servlet.xml

2 如果想指定配置文件的路徑,可以加入參數進行指寫

三、配置

配置處理器映射器, 配置處理器適配器,  配置視圖解析器 (即配置主文件)

<!--  配置處理器映射器 handler Mapping -->
<bean name="/search_all" class="cat.controller.UserAction"  />
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />  
         
<!--   配置處理器適配器 handler Adapter -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
           
<!--   配置視圖解析器  -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" />
//Action 中的方法
public class UserAction implements Controller {  //要實現 Controller
       public ModelAndView handleRequest(HttpServletRequest request,
                    HttpServletResponse response) throws Exception {
                    UserDao dao=new UserDao();
                    List<UserInfo> userList=dao.getAllUser();
                    
                    ModelAndView mv=new ModelAndView();
                    mv.addObject("userList", userList); //相當於request.setAttribute();
                    mv.setViewName("user_manage.jsp");
                    
                    return mv;
                } 
            }

訪問的時候 http://localhost:8080/springmvc/search_all

附: user_manage.jsp

<body>
<c:forEach var="u" items="${userList }">
   ${u.id } | ${u.userName } | ${u.password }  <br />
</c:forEach>
</body>

# Default implementation classes for DispatcherServlet s strategy interfaces.
# Used as fallback when no matching beans are found in the DispatcherServlet context.
# Not meant to be customized by application developers.

org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver

org.springframework.web.servlet.HandlerMapping=  //處理器映射器
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping //這個是3.1之前的
//org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping 應該用這個才對

org.springframework.web.servlet.HandlerAdapter=  //處理器適配器

org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter  //這個是3.1之前的
//org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter 應該用這個才對

org.springframework.web.servlet.HandlerExceptionResolver=
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver

org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator

org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

使用註解的方式配置處理器映射器和處理器適配器

1) 配置文件 springmvc-servlet.xml

//開啟掃描  
<context:component-scan base-package="cat.controller" />
                
//開啟註解配置 
<mvc:annotation-driven />
                
/* 有了上面的配置,下麵的就可以不寫了
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" />
*/
            
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
//<property name="prefix"  value="/WEB-INF/jsp/" /> 
<property name="prefix"  value="/" />
<property name="suffix"  value=".jsp" />
</bean>

2)

@Controller  //這裡只能用 @Controller ,不能用 Service
public class UserAction  {
@RequestMapping("/search_all")  //請求的名稱,最好和方法名相同
public ModelAndView getAllUser(){
                                UserDao dao=new UserDao();
                                List<UserInfo> userList=dao.getAllUser();
                                
                                ModelAndView mv=new ModelAndView();
                                mv.addObject("userList", userList); //相當於request.setAttribute();
                                mv.setViewName("user_manage.jsp");
                                
                                return mv;
                            }
                     }

五、@RequestMapping 註解, 和 Action中方法的返回值

在上例中添加用主修改的功能

1) @RequestMappingr 的說明

@RequestMapping 用來將url 和方法名進行 映射 ,一個方法,對應一個url , 比如     @RequestMapping("/search_all") 後面可以加.action 

可以用類,或方法上,用在類上,表示所有方法的根路徑

比如

@RequestMapping("/user")  //寫在類體上
public class UserAction  {    ...  }

RequestMappingr 註解有6個屬性 value,method,consumes,produces,params,headers

--value 指定請求的實際地址 -> @RequestMapping(value="/search_all")=@RequestMapping("/search_all")

--method 指定請求的method類型 (GET,POST,PUT,DELETE等)

例如

@RequestMapping(value="/updateUser" ,method=RequestMethod.POST) 
@RequestMapping(value="/updateUser" ,method={RequestMethod.POST,RequestMethod.GET}) 

說明 如果請求類型不對則出現類似異常 Request method 'GET' not supported

-- consumes:  指定處理請求的提交內容類型(Content-Type),例如application/json, text/html;

-- produces: 指定返回的內容類型,僅當request請求頭中的(Accept)類型中包含該指定類型才返回

-- params: 指定request中必須包含某些參數值時,才讓該方法處理。 //實測發現如果指定了,不傳將出錯

-- headers:指定request中必須包含某些指定的header值,才能讓該方法處理請求。

2) Action中方法的返回值的說明

-- ModelAndView

-- String //如果返回的是String 類型,則代表返回的邏輯視圖名稱 (相當於struts2中的邏輯視圖 )

//例一
@RequestMapping(value="/updateUser" ,method=RequestMethod.GET) 
public String  updateUser(Model model){  //用model 進行傳參
                            UserInfo user=new UserDao().getAdminById(4);
                            model.addAttribute("user", user);
                            return "user_edit";
                        }
//例二 關於請求的轉發和重定向
@RequestMapping(value="/updateUser" ,method=RequestMethod.POST) //只有請求是get請求的時候才有效
public String updateUserSubmit(){
                            System.out.println("-----"); 
                        //return "redirce:search_all" ;    //重定向 search_all是一個請求的名稱
                            return "forward:search_all" ; 
                        }

-- void

//例子
@RequestMapping(value="/udpateUserSubmit")
public void udpateUserSubmit(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException{
                        /* response.sendRedirect("search_all"); //重定向到某個url
                         response.sendRedirect("success");  //404
                         request.getRequestDispatcher("/success.jsp").forward(request, response);*/
                         response.getWriter().print("<h1>哈哈哈,這樣也可以</h1>");
                         response.getWriter().print( "\"userName\":\"張三\",\"password\":\"123\""  );  //返回json數據
                    }

六、參數綁定與值的傳遞

頁面請求發起的時候,如何把值傳給Controller (//Action ),以及如何把模型數據進行傳遞

1) 在 Controller 的形參上,可以直接定使用以下對象

HttpServletRequest

HttpServletResponse

HttpSession

Model //public abstract interface org.springframework.ui.Model

MdelMap // org.springframework.ui.ModelMap

Map<String ,Object>  //普通的map也可以,往這裡放的值,最終就放在了作用域中,在頁面就可以取出 ${key} ;

2) 可以使用簡單類型

//例一
@RequestMapping("/testParam") 
public void testParam(String userName,String password,String note){
                        System.out.println(userName+":"+password+":"+note);
                    }
                //本例的前提 參數名和請求傳上來的參數名要一致
//例二  @RequestParam 註解的作用
@RequestMapping("/testParam2") 
public String testParam2(
                         String userName, 
                         ModelMap mode,
                         @RequestParam("password") String pwd,
                         @RequestParam(value="age",required=true) int age,  //標明是必須的,如果不傳將出錯
                         @RequestParam(value="school",defaultValue="農業工程學院") String school)
                        {
                         System.out.println("userName:"+userName);
                         System.out.println("age:"+age);
                         System.out.println("school:"+school);
                         return "success";
                        }

3) 關於pojo類型(就是bean)  

只要表單元素的名字和方法的參數中的屬性值相同卻可。

@RequestMapping(value="/updateUser",method=RequestMethod.POST)
public String udpateUserSubmit(UserInfo user) {
                        System.out.println(user);  //這裡接收的參數是pojo類型
                        new UserDao().updateUser(user);  
                        return "success";
                    }
//user_edit.jsp
<form action="${pageContext.request.contextPath }/updateUser" method="post">  //註意,提交方式是post
       id:   <input type="text" name="id" value="${user.id }" /> 
       賬號: <input type="text" name="userName" value="${user.userName }" /> 
       密碼: <input type="text" name="password" value="${user.password }" /> 
       備註:  <input type="text" name="note" value="${user.note }" /> 
       <input type=submit value="提交" />
</form>

附:

處理亂碼spring的過濾器

<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
       <init-param>
       <param-name>encoding</param-name>
       <param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>杠*</url-pattern>
</filter-mapping>

如果是get請求的亂碼怎麼處理?

public String test(HttpServletRequest request){
                                        String userName=request.getParameter("userName");
                                        userName=new String(userName.getBytes("iso8859-1"),"utf-8");
                                  }
//上例或 在tomcat 的配置文件中(server.xml中加入  useBodyEncodingForURI=ture )
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="utf-8" useBodyEncodingForURI=ture
/>

4) 關於日期類型

例: 在實體類中添加一個日期類型的欄位

private Date birthday;   //生成get set
//在user_edit.jsp 頁面上 加上欄位   
<input type="text" name="birthday" value="${user.birthday }" />  可以發現,在提交的時候出

解決日期類型的問題有以下幾個方式

方式一:在實體類中加格式化註解

@DateTimeFormat(pattern="yyyy-MM-dd")  //有效,簡單
private Date birthday;

方式二:在控制器中加入一段數據綁定代碼

@InitBinder
public void initBinder(WebDataBinder binder) {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            dateFormat.setLenient(false);
            binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));   //true:允許輸入空值,false:不能為空值
            }
                                
//此方式:對於某個Oontroller可以獨立控制

方式三:要向處理器適配器中註入自定義參數綁定組件

5) 包裝類型的pojo

public class UserInfoCustom {
                             private UserInfo user;  //包裝一個pojo類型
                             private String schoolName;  //get set 方法..
                            }

user_add.jsp //用戶添加頁面

  <form action="${pageContext.request.contextPath }/addUser" method="post">
                           賬號:    <input type="text" name="user.userName"  /> 
                           密碼:     <input type="text" name="user.password"  /> 
                           備註:  <input type="text" name="user.note" /> 
                           學校:  <input type="text" name="schoolName" />   //註意
                                     <input type=submit value="提交" />
                                   </form>
                                            
                        //添加會員,用包裝類型的pojo傳值
                            @RequestMapping(value="/addUser",method=RequestMethod.POST)
                            public String addUser(UserInfoCustom info){
                                System.out.println(info);
                                //new UserDao().addUser(info)
                                return "success";
                            }

6) 數組類型的綁定

user_manage.jsp

<form action="${pageContext.request.contextPath }/deleUser" method="post">
<c:forEach var="u" items="${userList }">
<input type="checkbox" name="ids" value="${u.id } ">    ${u.id } | ${u.userName } | ${u.password }  <br />
</c:forEach>
<input type="submit" value="刪除所選" >
</form>

控制層中業務方法

@RequestMapping("/deleUser")
public String delUsers(Integer [] ids){  //參數名要和頁面中傳的參數名相同
                       for(Integer id:ids){
                                    System.out.println(id);
                                    }
                       //new UserDao().deleteUsers(ids);
                                    return "success";
                       }
                         
//附:也可以如下
@RequestMapping("/deleUser")
public String delUsers(HttpServletRequest request){
                       String [] ids=request.getParameterValues("ids");
                       //new UserDao().deleteUsers(ids);
                       return "success";
}

7) List 類型的數據綁定 (比如批量更新)

包裝類型

public class UserInfoCustomL {
                              private List<UserInfo> userList;  //生成get set 
                      }            

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

-Advertisement-
Play Games
更多相關文章
  • 位元組流、字元流涉及的類比較多,比較容易混淆。因此,有必要針對何時使用位元組流、何時使用字元流、何時使用Buffer類的流做一個歸納。要歸納它們,無需過多的語言,只需抓住它們的重點和特性即可。 在決定何時使用何種類時,以下幾個問題需要考慮清楚。 數據源:表示輸入,或稱為讀。可提供使用的兩個父類為Inpu ...
  • 一、原理 Spring MVC基於模型-視圖-控制器(Model-View-Controller,MVC)模式實現,它能夠幫你構建像Spring框架那樣靈活和松耦合的Web應用程式,將請求處理的邏輯和視圖中的渲染實現解耦。 1、DispatcherServlet是Spring MVC的核心 。Spr ...
  • 本人一直在走.NET技術路線,考慮到後期公司搞JAVA項目,也算是進行技術災備,開始對JAVA技術進行關註。萬事開頭難,也是上來一頭包。沒辦法,頂著上吧。上面開始分給我任務了。就是對後期項目報表進行方案選型。哥們兒花了兩周的時間總算是提供了幾個方案,以供相關人員選擇。特將此次過程整理如下: 一、萬事 ...
  • 一、Spring MVC 驗證 JSR 303 是ajvaEE6 中的一項子規範 ,叫 Bean Validation 用於對javaBean中的欄位進行校驗。 官方的參考實現是: Hibernate Validator ,此實現和 Hibernate ORM 沒有任何關係 //http://hib ...
  • ##importlogginglogging.debug('debug message')logging.info('info message')logging.warning('warning message') # WARNING:root:warning messagelogging.erro ...
  • 註意迭代器和可迭代對象不同#迭代器:1、有iter方法,2、有next方法li=[1,2,3,4,5]d=iter(li) # 等於li.__iter__()print(d) # <list_iteratorobjectat0x00000174316CC3C8>可以通過next方法取出元素。for循 ...
  • 要讀取鍵盤輸入的數據,需要使用輸入流,可以是位元組輸入流,也可以是位元組輸入流轉換後的字元輸入流。 關於鍵盤輸入,有幾點註意的是:(1).鍵盤輸入流為System.in,其返回的是InputStream類型,即位元組流。(2).位元組流讀取鍵盤的輸入時,需要考慮回車符(\r:13)、換行符(\n:10)。( ...
  • 再有兩天就進入2018了,想想還是要準備一下明年的工作方向。回想當初開始學習函數式編程時的主要目的是想設計一套標準API給那些習慣了OOP方式開發商業應用軟體的程式員們,使他們能用一種接近傳統資料庫軟體編程的方式來實現多線程,並行運算,分散式的數據處理應用程式,前提是這種編程方式不需要對函數式編程語 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...