溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

編寫SpringMVC控制器的實用小技巧有哪些

發(fā)布時間:2021-11-25 14:55:13 來源:億速云 閱讀:109 作者:柒染 欄目:編程語言

這期內(nèi)容當(dāng)中小編將會給大家?guī)碛嘘P(guān)編寫SpringMVC控制器的實用小技巧有哪些,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

編寫完成后,控制器會調(diào)用一個業(yè)務(wù)類來處理業(yè)務(wù)相關(guān)任務(wù),進而重定向客戶到邏輯視圖名。Springdispatcher servlet會對邏輯視圖名進行解析,并渲染結(jié)果或輸出。這就是一個典型的“請求—響應(yīng)”的完整流程。

1.使用@controllerstereotype

創(chuàng)建一個能夠處理單個或多個請求的控制器類,最簡單的方法就是使用@controllerstereotype注解一個類,如:

import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller publicclassHomeController {   @RequestMapping("/")   publicString visitHome() {     // do something before returning view name     return"home";   } }

如上所示,visitHome()方法通過重定向跳轉(zhuǎn)到視圖名home來處理應(yīng)用程序內(nèi)容路徑(/)收到的請求。

注意:只有在Spring配置文件中啟用了注解驅(qū)動,才能使用@controllerstereotype。

啟用注解驅(qū)動后,Spring的容器(container)會自動掃描如下包中的類:

帶有@controller注解的類會被標(biāo)記成控制器。由于其簡單方便,且不再需要對配置文件中的控制器聲明beans,這一方法非常實用。

注意:使用@controller注解可以創(chuàng)建一個多動作控制器類,可同時處理多個不同的請求。如:

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

如上所示,有三個處理器(handler)在分別處理三個請求,/listUsers,/saveUser,和/deleteUser。

2.實現(xiàn)控制器接口

在Spring MVC中創(chuàng)建控制器還可以用另一個經(jīng)典的方法,即對一個類實現(xiàn)Controller接口。如:

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

實現(xiàn)類必須重寫handleRequest()方法(當(dāng)收到相匹配的請求時,Spring dispatcher servlet會調(diào)用handleRequest)。由該控制器處理的請求URL模式在Spring的內(nèi)容配置文件中的定義如下:

這一方法的缺點在于其控制類無法同時處理多個請求URL。

3.繼承AbstractController類

如果想要輕松控制受支持的HTTP方法、會話和內(nèi)容緩存,讓控制類繼承AbstractController類是理想的方法。如:

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

上例創(chuàng)建了一個配置了受支持的方法、會話和緩存的單動作控制器,能夠在控制器的bean聲明中被指明。如:

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

這一配置表明該控制器handler方法僅支持POST方法。了解更多配置(如會話、緩存),參見AbstractController。

SpringMVC還提供了多個支持特定目的的控制器類,包括:

AbstractUrlViewController  MultiActionController  ParameterizableViewController  ServletForwardingController  ServletWrappingController  UrlFilenameViewController

4.為處理器指定URL映射

這是編寫控制器類必不可少的一步,旨在處理一個及以上特定請求。Spring MVC提供了@RequestMapping注解,用于指定URL映射。如:

這一步映射了URL模式/login,并用注解或注解類對其進行了處理。@RequestMapping注解用于類上時,類變成了單動作控制器。如:

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

@RequestMapping注解用于方法上時,則可生成多動作控制器。如:

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

@RequestMapping注解也可用于指定多個URL模式,并用單一方法對其進行處理。如:

此外,該注解還有其他的屬性,在一些情況下能發(fā)揮作用,如下一小節(jié)將講到的method屬性。

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

使用@RequestMapping注解的method屬性,可以指定處理器方法支持的HTTP方法(包括GET、POST、PUT等)。如:

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

如上所示,對于同一個URL模式/login,該控制器有兩個處理方法。第一個方法用于GET方法,第二個則用于POST方法。

了解更多@RequestMapping注解相關(guān)知識,參見@RequestMapping注解。

6.將請求參數(shù)映射至處理器方法

SpringMVC的特征之一,就是可以使用@RequestParam注解將請求參數(shù)作為處理器方法的常規(guī)參數(shù)取回。這是一個將控制器從ServletAPI的HttpServletRequest接口中解耦出來的好方法。

如:

@RequestMapping(value = "/login", method = RequestMethod.POSTpublic String doLogin(@RequestParamString username @RequestParamString password) {}

Spring將方法參數(shù)用戶名及密碼和命名相同的HTTP請求參數(shù)綁定到一起。這也就意味著可用如下方式調(diào)用一個URL(以GET請求方法為例):

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

類型轉(zhuǎn)換也自動完成了。如果對一個integer類型的參數(shù)聲明如下:

則Spring會在處理方法中自動將請求參數(shù)的值(String類型)轉(zhuǎn)換為指定類型(integer)。

為防止參數(shù)名與變量名不同,可將參數(shù)實名指定如下:

@RequestParam注解還有另外兩個屬性,可在一些情況下發(fā)揮作用。其中一個屬性是required,可指定一個參數(shù)是強制參數(shù)還是可選參數(shù)。如:

這就意味著參數(shù)country是可選的,在請求中可略去。當(dāng)請求中沒有參數(shù)country時,則變量country為空值。

另一個屬性是defaultValue,可在請求參數(shù)為空時充當(dāng)回退值(fallbackvalue)。如:

當(dāng)方法參數(shù)類型為Map<String,String>時,Spring也支持將所有參數(shù)作為Map對象。如:

則映射參數(shù)包含所有鍵值對形式的請求參數(shù)。了解更多@RequestParam注解相關(guān)知識,參見@RequestParam注解。

7.返回模型和視圖

處理器方法在處理完業(yè)務(wù)邏輯后,會返回一個視圖,該視圖隨后由Springdispatcher servlet進行解析。Spring支持handler方法返回String對象或ModelAndView對象。如下所示,handler方法返回了一個String對象,并表示了視圖名LoginForm:

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

這是返回視圖名最簡單的方法。但是如果想要發(fā)送其他數(shù)據(jù)到視圖,則必須返回ModelAndView對象。如:

@RequestMapping("/listUsers") public ModelAndView listUsers() {   List<User> listUser = new ArrayList<>();   // get user list from DAO...   ModelAndView modelView = new ModelAndView("UserList");   modelView.addObject("listUser", listUser);   return modelView; }

如上所示,該處理器方法返回了一個ModelAndView對象,該對象視圖名為UserList,并有一個可用在視圖中的User對象集。

Spring是一個非常靈活的框架,支持將ModelAndView對象聲明為處理器方法的參數(shù),而無需再重新創(chuàng)建一個。因此,上例可以重寫為:

@RequestMapping("/listUsers") public ModelAndView listUsers(ModelAndView modelView) {   List<User> listUser = new ArrayList<>();   // get user list from DAO...   modelView.setViewName("UserList");   modelView.addObject("listUser", listUser);   return modelView; }

了解更多ModelAndView類相關(guān)知識,參見ModelAndView類。

8.將對象放入模型

在MVC架構(gòu)的應(yīng)用程序中,控制器將數(shù)據(jù)輸入到模型中,該模型則被用在視圖中。從上一節(jié)中的舉例中可以看到,ModelAndView類的addObject()用于將對象以名值對的形式放入模型中:

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

Spring同樣支持聲明處理器方法中的Map類型參數(shù)。Spring使用這一映射存儲將放入模型的對象。如:

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

這一方法比使用ModelAndView對象更加簡單。Spring支持用戶靈活選擇Map對象和ModelAndView對象。

9.處理器方法中的重定向

當(dāng)條件允許時,只需在URL前加上redirect:/就可將用戶重定向跳轉(zhuǎn)到另一個URL。如:

// check login status.... if (!isLogin) {   returnnew ModelAndView("redirect:/login"); } // return a list of Users

在上述代碼中,沒有登陸的用戶將會跳轉(zhuǎn)到/loginURL。

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

Spring中的@ModelAttribute注解支持將表單字段綁定到表單返回對象,BingingRequest接口則支持驗證表單字段。這使得處理表單提交變得非常簡單。一個處理和驗證表單數(shù)據(jù)的典型處理器方法的代碼如下所示:

@Controller publicclassRegistrationController {   @RequestMapping(value = "/doRegister", method = RequestMethod.POST)   publicString doRegister(     @ModelAttribute("userForm") User user, BindingResult bindingResult) {     if (bindingResult.hasErrors()) {       // form validation error     } else {       // form input is OK     }     // process registration...     return"Success";   } }

了解更多@ModelAttribute注解和BindingResult接口相關(guān)知識,參見Spring官方文檔:

Using @ModelAttribute on a method argument  Using @ModelAttribute on a method  Interface BindingResult

11.處理文件上傳

Spring支持自動將上傳數(shù)據(jù)綁定到CommonsMultiparFile數(shù)組對象,這使得在處理器方法中處理文件上傳變得非常簡單。Spring使用Apache CommonsFileUpload作為深層多部分解析器(underlyingmultipart resolver)。

簡單上傳用戶文件的代碼如下所示:

@RequestMapping(value = "/uploadFiles", method = RequestMethod.POST) publicStringhandleFileUpload(     @RequestParam CommonsMultipartFile[] fileUpload) throws Exception {   for (CommonsMultipartFile aFile : fileUpload){     // stores the uploaded file     aFile.transferTo(new File(aFile.getOriginalFilename()));   }   return"Success"; }

了解Spring MVC處理文件上傳的完整方法,參見Spring MVC 文件上傳教程。

12.在處理器中自動注入業(yè)務(wù)類

為了讓控制器將業(yè)務(wù)邏輯處理委托到相關(guān)業(yè)務(wù)類,可以使用@Autowired注解,讓Spring自動將業(yè)務(wù)類的實際實現(xiàn)注入到控制器中。如:

@Controller publicclassUserController {   @Autowired   private UserDAO userDAO;   publicString listUser() {     // handler method to list all users     userDAO.list();   }   publicString saveUser(User user) {     // handler method to save/update a user     userDAO.save(user);   }   publicString deleteUser(User user) {     // handler method to delete a user     userDAO.delete(user);   }   publicString getUser(int userId) {     // handler method to get a user     userDAO.get(userId);   } }

本例中所有與用戶管理相關(guān)的業(yè)務(wù)邏輯都由UserDAO接口的實現(xiàn)提供。如:

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

如上所示,使用@Autowired注解使處理器方法可以將任務(wù)委托到業(yè)務(wù)類:

了解更多@Autowired注解相關(guān)知識,參見Annotation TypeAutowired。

13.獲取HttpServletRequest和HttpServletResponse

有些情況要求在處理器方法中直接獲取HttpServletRequest或HttpServletResponse對象。在Spring靈活的框架中,僅需給處理器方法加上一個相關(guān)參數(shù)就可以完成此任務(wù)。如:

@RequestMapping("/download") publicStringdoDownloadFile(     HttpServletRequest request, HttpServletResponse response) {   // access the request   // access the response   return"DownloadPage"; }

Spring支持檢測并自動將HttpServletRequest和HttpServletResponse對象注入到方法中。這樣一來,就可以直接獲取請求和響應(yīng),如獲取InputStream、OutputStream或返回特定的HTTP代碼。

14.遵守單一職責(zé)原則

在Spring MVC中設(shè)計和編寫控制器時,應(yīng)遵循以下兩個非常實用的操作:

不要用控制器類來執(zhí)行業(yè)務(wù)邏輯,應(yīng)該用控制器類將業(yè)務(wù)處理委托到相關(guān)的業(yè)務(wù)類。這可以保證控制器專注于其指定職責(zé),即控制應(yīng)用程序的工作流。如:

@Controller publicclassUserController {   @Autowired   private UserDAO userDAO;   publicString listUser() {     // handler method to list all users     userDAO.list();   }   publicString saveUser(User user) {     // handler method to save/update a user     userDAO.save(user);   }   publicString deleteUser(User user) {     // handler method to delete a user     userDAO.delete(user);   }   publicString getUser(int userId) {     // handler method to get a user     userDAO.get(userId);   } }

給每個業(yè)務(wù)領(lǐng)域創(chuàng)建一個獨立的控制器。如,用UserController控制用戶管理的工作流,用OrderController控制訂單處理的工作流,等等:

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

上述就是小編為大家分享的編寫SpringMVC控制器的實用小技巧有哪些了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI