1.使用@Controller構造型-這樣就完成了典型的請求

點擊藍色“最碼農”關注我喲

加個“星標”,每天下午18:03,一起學技術

通常,在Spring MVC中,我們編寫一個控制器類來處理來自客戶端的請求。然后,控制器調用業務類來處理與業務相關的任務,然后將客戶端重定向到邏輯視圖名稱,該名稱由Spring的調度程式Servlet解析,以呈現結果或輸出。這樣就完成了典型的請求-響應周期的往返。今天整理了一下編寫Spring MVC控制器的14個技巧,你今天get到了嗎?\(≧▽≦)/


1.使用@Controller構造型

這是創建可以處理一個或多個請求的控制器類的最簡單方法。僅通過用構造型注釋一個類@Controller,例如:

importorg.springframework.stereotype.Controller;
importorg.springframework.web.bind.annotation.RequestMapping;
@Controller
publicclassHomeController{
@RequestMapping("/")
publicStringvisitHome(){

return"home";
}
}

如你所見,visitHome()方法通過重定向到名為home的視圖來處理來自應用程式上下文路徑(/)的請求。

注意:@Controller原型只能在Spring的配置文件中啟用注解驅動時使用:


<annotation-driven/>

啟用注釋驅動時,Spring容器自動在以下語句指定的包下掃描類:

<context:component-scanbase-package="net.codejava.spring"/>

@Controller注釋注釋的類被配置為控制器。這是最可取的,因為它很簡單:無需在配置文件中為控制器聲明bean。

注意:通過使用@Controller注解,您可以擁有一個多動作控制器類,該類能夠處理多個不同的請求。例如:

@Controller
publicclassMultiActionController{
@RequestMapping("/listUsers")
publicModelAndViewlistUsers(){
}
@RequestMapping("/saveUser")
publicModelAndViewsaveUser(Useruser){
}
@RequestMapping("/deleteUser")
publicModelAndViewdeleteUser(Useruser){
}
}

正如你可以在上面的控制器類看,有處理三種不同的請求3種處理方法 /listUsers/saveUser/deleteUser分別。


2.實現控制器接口

在Spring MVC中創建控制器的另一種(也許是經典的)方法是讓類實現Controller接口。例如:

importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importorg.springframework.web.servlet.ModelAndView;
importorg.springframework.web.servlet.mvc.Controller;
publicclassMainControllerimplementsController{
@Override
publicModelAndViewhandleRequest(HttpServletRequestrequest,
HttpServletResponseresponse)throwsException{
System.out.println("Welcomemain");
returnnewModelAndView("main");
}
}

實現類必須重寫該handleRequest()方法,當匹配請求進入時,該方法將由Spring調度程式Servlet調用。此控制器處理的請求URL模式在Spring的上下文配置文件中定義如下:

<beanname="/main"class="net.codejava.spring.MainController"/>

但是,此方法的缺點是控制器類無法處理多個請求URL。


3.擴展AbstractController類

如果要輕松控制受支持的HTTP方法,會話和內容緩存。擴展你的控制器AbstractController類是理想的選擇。請考慮以下示例:

importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importorg.springframework.web.servlet.ModelAndView;
importorg.springframework.web.servlet.mvc.AbstractController;
publicclassBigControllerextendsAbstractController{
@Override
protectedModelAndViewhandleRequestInternal(HttpServletRequestrequest,
HttpServletResponseresponse)throwsException{
System.out.println("You'rebig!");
returnnewModelAndView("big");
}
}

這將創建具有有關受支持的方法,會話和緩存的配置的單動作控制器,然后可以在控制器的bean聲明中指定這些配置。例如:


<beanname="/big"class="net.codejava.spring.BigController">
<propertyname="supportedMethods"value="POST"/>
</bean>

此配置指示POST此控制器的hander方法僅支持該方法。

Spring MVC還提供了幾種針對特定目的而設計的控制器類,包括:

  • AbstractUrlViewController

  • MultiActionController

  • ParameterizableViewController

  • ServletForwardingController

  • ServletWrappingController

  • UrlFilenameViewController


4.為處理程式方法指定URL映射

這是編碼控制器類時必須執行的強制性任務,該控制器類旨在處理一個或多個特定請求。Spring MVC提供了@RequestMapping注釋,該注解用于指定URL映射。例如:


@RequestMapping("/login")

這映射了/login要由帶注解的方法或類處理的URL模式。當在類級別使用此注解時,該類將成為單動作控制器。例如:


importorg.springframework.stereotype.Controller;
importorg.springframework.web.bind.annotation.RequestMapping;
importorg.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping("/hello")
publicclassSingleActionController{
@RequestMapping(method=RequestMethod.GET)
publicStringsayHello(){
return"hello";
}
}

@RequestMapping注解在方法級別使用的,你可以有一個多動作控制器。例如:

importorg.springframework.stereotype.Controller;
importorg.springframework.web.bind.annotation.RequestMapping;
@Controller
publicclassUserController{
@RequestMapping("/listUsers")
publicStringlistUsers(){
return"ListUsers";
}
@RequestMapping("/saveUser")
publicStringsaveUser(){
return"EditUser";
}
@RequestMapping("/deleteUser")
publicStringdeleteUser(){
return"DeleteUser";
}
}

@RequestMapping注釋還可以用于指定一個方法要處理的多個URL模式。例如:


@RequestMapping({"/hello","/hi","/greetings"})

此外,此注解還具有在某些情況下可能有用的其他屬性,例如method


5.為處理程式方法指定HTTP請求方法

可以使用注解的method屬性 指定處理程式方法支持哪種HTTP方法(GET,POST,PUT等)@RequestMapping。這是一個例子:

importorg.springframework.stereotype.Controller;
importorg.springframework.web.bind.annotation.RequestMapping;
importorg.springframework.web.bind.annotation.RequestMethod;
@Controller
publicclassLoginController{
@RequestMapping(value="/login",method=RequestMethod.GET)
publicStringviewLogin(){
return"LoginForm";
}
@RequestMapping(value="/login",method=RequestMethod.POST)
publicStringdoLogin(){
return"Home";
}
}

此控制器有兩個處理相同URL模式的方法/login,但前者用于GET方法,而后者用于POST方法。

有關使用@RequestMapping注解的更多資訊,請參見@RequestMapping注解。


6.將請求參數映射到處理程式方法

Spring MVC的很酷的功能之一是,您可以使用@RequestParam注解將請求參數作為處理程式方法的常規參數進行檢索。這是將控制器HttpServletRequest與Servlet API 的接口分離的好方法。

@RequestMapping(value="/login",method=RequestMethod.POST)
publicStringdoLogin(@RequestParamStringusername,
@RequestParamStringpassword){
}


Spring將方法參數用戶名密碼綁定到具有相同名稱的HTTP請求參數。這意味著您可以按以下方式調用URL(如果請求方法是GET):

http://localhost:8080/spring/login?username=scott&password=tiger

類型轉換也是自動完成的。例如,如果您聲明integer如下類型的參數:


@RequestParamintsecurityNumber

然后,Spring將在處理程式方法中自動將請求參數(字符串)的值轉換為指定的類型(整數)。

如果參數名稱與變量名稱不同,則可以如下指定參數的實際名稱:

@RequestParam("SSN")intsecurityNumber

@RequestParam注解也有兩個額外的屬性,這可能是在某些情況下是有用的。該屬性指定參數是否為必需。例如:required


@RequestParam(required=false)Stringcountry

這意味著該參數country是可選的;因此,它可能會從請求中丟失。在上面的示例中,country如果請求中不存在此類參數,則變量將為null。

另一個屬性是defaultValue,可以在請求參數為空時用作后備值。例如:


@RequestParam(defaultValue="18")intage

Map如果方法參數是type,Spring還允許我們將所有參數作為對象 訪問Map<String, String>。例如:

doLogin(@RequestParamMap<String,String>params)

然后,映射參數包含鍵-值對形式的所有請求參數。有關使用@RequestParam注釋的更多資訊,請參見@RequestParam注解。


7.返回模型和視圖

處理完業務邏輯后,處理程式方法應返回一個視圖,然后由Spring的調度程式servlet對其進行解析。Spring允許我們ModelAndViewhandler方法中返回String或對象。在以下示例中,該handler方法返回一個String并表示一個名為的視圖LoginForm


@RequestMapping(value="/login",method=RequestMethod.GET)
publicStringviewLogin(){
return"LoginForm";
}

這是返回視圖名稱的最簡單方法。但是,如果要將其他數據發送到視圖,則必須返回一個ModelAndView對象。考慮以下處理程式方法:

@RequestMapping("/listUsers")
publicModelAndViewlistUsers(){
List<User>listUser=newArrayList<>();
//從DAO獲取用戶列表…
ModelAndViewmodelView=newModelAndView("UserList");
modelView.addObject("listUser",listUser);
returnmodelView;
}

如您所見,此處理程式方法返回一個ModelAndView保存視圖名稱UserListUser對象和一個可在視圖中使用的對象集合。


Spring也非常靈活,因為您可以將ModelAndView對象聲明為處理程式方法的參數,而不用創建一個新的對象。因此,以上示例可以重寫如下:

@RequestMapping("/listUsers")
publicModelAndViewlistUsers(ModelAndViewmodelView){
List<User>listUser=newArrayList<>();
//從DAO獲取用戶列表…
modelView.setViewName("UserList");
modelView.addObject("listUser",listUser);
returnmodelView;
}

了解有關該類的更多資訊,請參見 :ModelAndView class。


8.將對象放入模型

在遵循MVC架構的應用程式中,控制器(C)應該將數據傳遞到模型(M)中,然后在視圖(V)中使用該模型。正如我們在前面的示例中看到的那樣,該類的addObject()方法ModelAndView是以名稱-值對的形式將對象放入模型中:


modelView.addObject("listUser",listUser);
modelView.addObject("siteName",newString("CodeJava.net"));
modelView.addObject("users",1200000);

同樣,Spring非常靈活。你可以Map在處理程式方法中聲明類型的參數。Spring使用此映射存儲模型的對象。讓我們看另一個例子:


@RequestMapping(method=RequestMethod.GET)
publicStringviewStats(Map<String,Object>model){
model.put("siteName","CodeJava.net");
model.put("pageviews",320000);
return"Stats";
}

這比使用ModelAndView對象還要簡單。根據你的喜好,可以使用Map或使用ModelAndView對象。在這里要感謝Spring的靈活性。


9.處理程式方法中的重定向

如果你希望在滿足條件的情況下將用戶重定向到另一個URL,請redirect:/在URL之前追加。以下代碼段給出了一個示例:

//檢查登入狀態....
if(!isLogin){
returnnewModelAndView("redirect:/login");
}
//返回用戶列表

在上面的代碼中,/login如果未登入,用戶將被重定向到該 URL。


10.處理表格提交和表格驗證

通過提供@ModelAttribute用于將表單字段綁定到表單支持對象的注解以及BindingResult用于驗證表單字段的界面,Spring使處理表單提交變得容易。下面的代碼片段顯示了一種典型的處理程式方法,該方法負責處理和驗證表單數據:

@Controller
publicclassRegistrationController{
@RequestMapping(value="/doRegister",method=RequestMethod.POST)
publicStringdoRegister(
@ModelAttribute("userForm")Useruser,BindingResultbindingResult){
if(bindingResult.hasErrors()){
//表單驗證錯誤
}else{
//表單輸入沒問題
}
//注冊過程……
return"Success";
}
}

從Spring的官方文檔中了解有關@ModelAttribute注釋和BindingResult接口的更多資訊 :

  • 在方法參數上使用@ModelAttribute

  • 在方法上使用@ModelAttribute

  • 接口綁定結果

11.處理文件上傳

通過自動將上傳數據綁定到CommonsMultipartFile對象數組,Spring還使在處理程式方法中處理文件上傳變得容易。Spring使用Apache Commons FileUpload作為基礎的多部分解析器。


以下代碼段顯示了從客戶端上傳文件有多么容易


@RequestMapping(value="/uploadFiles",method=RequestMethod.POST)
publicStringhandleFileUpload(
@RequestParamCommonsMultipartFile[]fileUpload)throwsException{
for(CommonsMultipartFileaFile:fileUpload){
//存儲上傳的文件
aFile.transferTo(newFile(aFile.getOriginalFilename()));
}
return"Success";
}

12.在控制器中自動裝配業務類

控制器應將業務邏輯的處理委托給相關的業務類。為此,您可以使用@Autowired注解讓Spring自動將業務類的實際實現注入控制器。考慮以下控制器類的代碼段:

@Controller
publicclassUserController{
@Autowired
privateUserDAOuserDAO;
publicStringlistUser(){
//列出所有用戶的處理方法
userDAO.list();
}
publicStringsaveUser(Useruser){
//保存/更新用戶的處理方法
userDAO.save(user);
}
publicStringdeleteUser(Useruser){
//刪除用戶的處理方法
userDAO.delete(user);
}
publicStringgetUser(intuserId){
//獲取用戶的處理方法
userDAO.get(userId);
}
}

在此,與用戶管理有關的所有業務邏輯都由該UserDAO接口的實現提供。例如:

interfaceUserDAO{
List<User>list();
voidsave(Useruser);
voidcheckLogin(Useruser);
}

有關@Autowired注解的更多資訊,請參見注釋類型自動裝配。


13.訪問HttpServletRequest和HttpServletResponse

在某些情況下,您需要直接在處理程式方法中訪問HttpServletRequestHttpServletResponse對象。通過Spring的靈活性,只需在處理方法中添加相關參數即可。例如:


@RequestMapping("/download")
publicStringdoDownloadFile(
HttpServletRequestrequest,HttpServletResponseresponse){
//訪問請求
//訪問響應
return"DownloadPage";
}

Spring檢測并自動將HttpServletRequestHttpServletResponse對象注入方法中。然后,可以訪問請求和響應如獲取InputStreamOutputStream或返回一個特定的HTTP代碼。

14.遵循單一責任原則

最后,在設計和編寫Spring MVC控制器時,有兩個很好的實踐是你應該遵循的:

  • 控制器類不應執行業務邏輯。相反,它應該將業務處理委托給相關的業務類別。這使控制器始終專注于其設計職責是控制應用程式的工作流程。例如:


@Controller
publicclassUserController{
@Autowired
privateUserDAOuserDAO;
publicStringlistUser(){
userDAO.list();
}
publicStringsaveUser(Useruser){
userDAO.save(user);
}
publicStringdeleteUser(Useruser){
userDAO.delete(user);
}
publicStringgetUser(intuserId){
userDAO.get(userId);
}
}
  • 為每個業務域創建每個單獨的控制器。例如,UserController用于控制用戶管理的OrderController工作流程,用于控制訂單處理的工作流程等。例如:


@Controller
publicclassUserController{
}
@Controller
publicclassProductController{
}
@Controller
publicclassOrderController{
}
@Controller
publicclassPaymentController{
}

這14個小技巧,可以幫助你正確有效地在Spring MVC中編寫控制器類。如果你有其他提示或建議,請隨時在評論中分享您的想法。

作者|不墜青云~

來源 |csdn.net/Summer_Lyf/article/details/102911215


圖片
掃碼關注最新動態
關鍵時刻,第一時間送達

– END –


世界第三大瀏覽器正在消亡
什么是死亡之 Ping 攻擊?
發現:字節跳動的內卷從男休息室開始的
0 条回复 A文章作者 M管理員
    暫無討論,說說你的看法吧