1. 程式人生 > 程式設計 >編寫Spring MVC控制器的14個技巧(小結)

編寫Spring MVC控制器的14個技巧(小結)

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

1.使用@Controller構造型

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

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HomeController {
 @RequestMapping("/")
 public String visitHome() {
 
 return "home";
 }
}

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

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

<annotation-driven />

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

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

由@Controller註釋註釋的類被配置為控制器。這是最可取的,因為它很簡單:無需在配置檔案中為控制器宣告bean。

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

@Controller
public class MultiActionController {
 @RequestMapping("/listUsers")
 public ModelAndView listUsers() {
 }
 @RequestMapping("/saveUser")
 public ModelAndView saveUser(User user) {
 }
 @RequestMapping("/deleteUser")
 public ModelAndView deleteUser(User user) {
 }
}

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

/saveUser,和/deleteUser分別。

2.實現控制器介面

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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
public class MainController implements Controller {
 @Override
 public ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse response) throws Exception {
 System.out.println("Welcome main");
 return new ModelAndView("main");
 }
}

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

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

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

3.擴充套件AbstractController類

如果要輕鬆控制受支援的HTTP方法,會話和內容快取。擴充套件你的控制器AbstractController類是理想的選擇。請考慮以下示例:

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
public class BigController extends AbstractController {
 @Override
 protected ModelAndView handleRequestInternal(HttpServletRequest request,HttpServletResponse response) throws Exception {
 System.out.println("You're big!");
 return new ModelAndView("big");
 }
}

這將建立具有有關受支援的方法,會話和快取的配置的單動作控制器,然後可以在控制器的bean宣告中指定這些配置。例如:

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

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

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

  • AbstractUrlViewController
  • MultiActionController
  • ParameterizableViewController
  • ServletForwardingController
  • ServletWrappingController
  • UrlFilenameViewController

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

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

@RequestMapping("/login")

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

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping("/hello")
public class SingleActionController {
 @RequestMapping(method = RequestMethod.GET)
 public String sayHello() {
 return "hello";
 }
}

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

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class UserController {
 @RequestMapping("/listUsers")
 public String listUsers() {
 return "ListUsers";
 }
 @RequestMapping("/saveUser")
 public String saveUser() {
 return "EditUser";
 }
 @RequestMapping("/deleteUser")
 public String deleteUser() {
 return "DeleteUser";
 }
}

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

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

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

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

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

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class LoginController {
 @RequestMapping(value = "/login",method = RequestMethod.GET)
 public String viewLogin() {
 return "LoginForm";
 }
 @RequestMapping(value = "/login",method = RequestMethod.POST)
 public String doLogin() {
 return "Home";
 }
}

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

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

6.將請求引數對映到處理程式方法

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

@RequestMapping(value = "/login",method = RequestMethod.POST)
public String doLogin(@RequestParam String username,@RequestParam String password) {
}

Spring將方法引數使用者名稱和密碼繫結到具有相同名稱的HTTP請求引數。這意味著您可以按以下方式呼叫URL(如果請求方法是GET):

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

型別轉換也是自動完成的。例如,如果您宣告integer如下型別的引數:

@RequestParam int securityNumber

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

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

@RequestParam("SSN") int securityNumber

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

@RequestParam(required = false) String country

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

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

@RequestParam(defaultValue = "18") int age

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

doLogin(@RequestParam Map<String,String> params)

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

7.返回模型和檢視

處理完業務邏輯後,處理程式方法應返回一個檢視,然後由Spring的排程程式servlet對其進行解析。Spring允許我們ModelAndView從handler方法中返回String或物件。在以下示例中,該handler方法返回一個String並表示一個名為的檢視LoginForm:

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

這是返回檢視名稱的最簡單方法。但是,如果要將其他資料傳送到檢視,則必須返回一個ModelAndView物件。考慮以下處理程式方法:

@RequestMapping("/listUsers")
public ModelAndView listUsers() {
 List<User> listUser = new ArrayList<>();
 // 從DAO獲取使用者列表…
 ModelAndView modelView = new ModelAndView("UserList");
 modelView.addObject("listUser",listUser);
 return modelView;
}

如您所見,此處理程式方法返回一個ModelAndView儲存檢視名稱UserList的User物件和一個可在檢視中使用的物件集合。

Spring也非常靈活,因為您可以將ModelAndView物件宣告為處理程式方法的引數,而不用建立一個新的物件。因此,以上示例可以重寫如下:

@RequestMapping("/listUsers")
public ModelAndView listUsers(ModelAndView modelView) {
 List<User> listUser = new ArrayList<>();
 //從DAO獲取使用者列表…
 modelView.setViewName("UserList");
 modelView.addObject("listUser",listUser);
 return modelView;
}

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

8.將物件放入模型

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

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

同樣,Spring非常靈活。你可以Map在處理程式方法中宣告型別的引數。Spring使用此對映儲存模型的物件。讓我們看另一個例子:

@RequestMapping(method = RequestMethod.GET)
public String viewStats(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) {
 return new ModelAndView("redirect:/login");
}
// 返回使用者列表

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

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

通過提供@ModelAttribute用於將表單欄位繫結到表單支援物件的註解以及BindingResult用於驗證表單欄位的介面,Spring使處理表單提交變得容易。下面的程式碼片段顯示了一種典型的處理程式方法,該方法負責處理和驗證表單資料:

@Controller
public class RegistrationController {
 @RequestMapping(value = "/doRegister",method = RequestMethod.POST)
 public String doRegister(
  @ModelAttribute("userForm") User user,BindingResult bindingResult) {
  if (bindingResult.hasErrors()) {
   // 表單驗證錯誤
  } else {
   // 表單輸入沒問題
  }
  // 註冊過程……
  return "Success";
 }
}

從Spring的官方文件中瞭解有關@ModelAttribute註釋和BindingResult介面的更多資訊 :

  • 在方法引數上使用@ModelAttribute
  • 在方法上使用@ModelAttribute
  • 介面繫結結果

11.處理檔案上傳

通過自動將上傳資料繫結到CommonsMultipartFile物件陣列,Spring還使在處理程式方法中處理檔案上傳變得容易。Spring使用Apache Commons FileUpload作為基礎的多部分解析器。

以下程式碼段顯示了從客戶端上傳檔案有多麼容易

@RequestMapping(value = "/uploadFiles",method = RequestMethod.POST)
public String handleFileUpload(
  @RequestParam CommonsMultipartFile[] fileUpload) throws Exception {
 for (CommonsMultipartFile aFile : fileUpload){
  // 儲存上傳的檔案
  aFile.transferTo(new File(aFile.getOriginalFilename()));
 }
 return "Success";
}

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

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

@Controller
public class UserController {
 @Autowired
 private UserDAO userDAO;
 public String listUser() {
  // 列出所有使用者的處理方法
  userDAO.list();
 }
 public String saveUser(User user) {
  // 儲存/更新使用者的處理方法
  userDAO.save(user);
 }
 public String deleteUser(User user) {
  // 刪除使用者的處理方法
  userDAO.delete(user);
 }
 public String getUser(int userId) {
  // 獲取使用者的處理方法
  userDAO.get(userId);
 }
}

在此,與使用者管理有關的所有業務邏輯都由該UserDAO介面的實現提供。例如:

interface UserDAO {
 List<User> list();
 void save(User user);
 void checkLogin(User user);
}

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

13.訪問HttpServletRequest和HttpServletResponse

在某些情況下,您需要直接在處理程式方法中訪問HttpServletRequest或HttpServletResponse物件。通過Spring的靈活性,只需在處理方法中新增相關引數即可。例如:

@RequestMapping("/download")
public String doDownloadFile(
  HttpServletRequest request,HttpServletResponse response) {
 // 訪問請求
 // 訪問響應
 return "DownloadPage";
}

Spring檢測並自動將HttpServletRequest和HttpServletResponse物件注入方法中。然後,可以訪問請求和響應如獲取InputStream,OutputStream或返回一個特定的HTTP程式碼。

14.遵循單一責任原則

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

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

@Controller
public class UserController {
 @Autowired
 private UserDAO userDAO;
 public String listUser() {
  userDAO.list();
 }
 public String saveUser(User user) {
  userDAO.save(user);
 }
 public String deleteUser(User user) {
  userDAO.delete(user);
 }
 public String getUser(int userId) {
  userDAO.get(userId);
 }
}

為每個業務域建立每個單獨的控制器。例如,UserController用於控制使用者管理的OrderController工作流程,用於控制訂單處理的工作流程等。例如:

@Controller
public class UserController {
}
@Controller
public class ProductController {
}
@Controller
public class OrderController {
}
@Controller
public class PaymentController {
}

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。