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
  • 前言 本文介紹一款使用 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 ...