Spring REST實踐之Spring Web MVC

Spring概要

Spring Framework提供了依賴注入模型和麪向切面編程,簡化了基礎型代碼的編寫工做以及更好的可以與其它框架和技術整合起來。Spring Framework由data access、instrumentation、messaging、testing、Web
integration等模塊組成。開發者能夠只關心本身應用程序相關模塊。web

依賴注入

依賴注入是Spring Framework的核心,可以下降模塊之間的耦合度。爲了可以更好的理解依賴注入的概念,舉個例子解釋一下:考慮網上購物的場景,完成一個訂單服務須要與訂單倉庫組件和用戶通知組件交互。在傳統的實現方式中,訂單服務能夠建立訂單倉庫組件和用戶通知組件對象,雖然這麼作沒有什麼錯,可是它會致使難於維護、難於測試和高耦合性。利用依賴注入,開發者能夠委託Spring Framework管理模塊間的依賴關係,因此在上面的場景中,Spring Framework能夠建立訂單倉庫組件和用戶通知組件,並注入到訂單服務中。這樣訂單服務就不用建立管理訂單倉庫組件和用戶通知組件,很是方便測試、維護,以及替換訂單倉庫組件和用戶通知組件的實現方式。spring

AOP

AOP實現了橫切邏輯,像日誌、事務、監控、安全都屬於橫切邏輯。AOP提供了切面在一個集中的地方來完成這些橫切邏輯,而不是將這些橫切邏輯遍及業務代碼各處。Spring Framework採用代理的方式實現AOP,當目標bean被調用時,代理會中斷調用並執行橫切邏輯,最後才執行目標bean的方法。Spring提供了JDK動態代理和CGLIB代理方式,若是目標對象實現了接口,Spring會使用JDK動態代理建立AOP代理,反之會使用CGLIB代理實現。編程

Spring Web MVC概要

Spring Web MVC是基於MVC的架構,提供了豐富的註解和組件。通過近幾年的發展,Spring Web MVC支持了試圖解析和豐富的數據綁定功能。安全

Model View Controller Pattern

Model View Controller交互圖

Spring Web MVC Architecture

Spring Web MVC's architecture

Spring Web MVC Components

Controller

控制器可用 @Controller註解聲明。架構

Model

Model用於保持模型的屬性,可用addAttribute和addAttributes方法增長模型的屬性。mvc

public interface Model {
     
    Model addAttribute(String attributeName, Object attributeValue);
     
    Model addAttribute(Object attributeValue);
     
    Model addAllAttributes(Collection<?> attributeValues);
     
    Model addAllAttributes(Map<String, ?> attributes);

    Model mergeAttributes(Map<String, ?> attributes);
     
    boolean containsAttribute(String attributeName);
     
    Map<String, Object> asMap();
}

View

Spring Web MVC支持JSP、Velocity、Freemarker和XSLT等視圖技術,經過View接口完成這個功能。app

View Interface API:
public interface View
{
String getContentType();框架

void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception;
}

View Interface的核心功能是負責呈現響應內容,這個功能須要重載render方法實現,getContentType方法返回內容類型。Spring Web MVC內置了MappingJackson2JsonView、XsltView等實現View接口的類。ide

@RequestParam

@RequestParam用於綁定請求中的參數到控制器中的參數。post

@RequestMapping

@RequestMapping將一個請求映射到控制器的一個方法。

@RequestMapping的參數:
Method:Restricts a mapping to a specific HTTP method such as GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE

Produces:Narrows mapping to media type that is produced by the method

Consumes:Narrows mapping to media type that the method consumes

Headers:Narrows mapping to the headers that should be present name Allows you to assign a name to the mapping

params:Restricts a mapping to the supplied parameter name and value

Path Variables

@PathVariable可以訪問 @RequestMapping指定的路徑中佔位符參數。

View Resolver

View Resolver可以根據控制器返回的邏輯視圖名,選擇合適的視圖解析器呈現視圖。

public interface ViewResolver
{
    View resolveViewName(String viewName, Locale locale) throws Exception;
}

ContentNegotiatingViewResolver、BeanNameViewResolver、InternalResourceViewResolver、TilesViewResolver等實現了ViewResolver接口。

Exception Handler

@Controller
public class HomeController {
    @ExceptionHandler(SQLException.class)
    public Object handleSQLException() {
    
    }
     
    @RequestMapping("/stream")
    public void streamMovie(HttpServletResponse response) throws SQLException {
     
    }
}

@ExceptionHandler註解表示在HomeController控制器中的方法拋出SQLException未處理的異常,都由handleSQLException來進行處理。可是此方式有個缺陷,就是隻能處理HomeController及其子類的方法拋出的未處理異常。爲解決這個問題,Spring提供了 @ControllerAdvice註解,在應用中凡是用 @RequestMapping註解標記的方法拋出未處理的異常均可以由 @ControllerAdvice註解標註的類中的相應異常處理方法進行處理。

@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
 
    @ExceptionHandler(SQLException.class)
    public Object handleSQLException() {

    }
}

Interceptors

Interceptors能夠執行一些處理器關注的橫切點業務。

HandlerInterceptor API
public interface HandlerInterceptor{
void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);

void postHandle(HttpServletRequest request, HttpServletResponse response, Object
    handler, ModelAndView modelAndView);
    
    boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object
    handler);
}

HandlerInterceptorAdapter實現HandlerInterceptor接口中的方法的默認實現,自定義的攔截器能夠繼承HandlerInterceptor類,覆蓋本身關注的方法便可。

Spring Web MVC Interceptor例子:

public class SimpleInterceptor extends HandlerInterceptorAdapter {
    private static final Logger logger = Logger.getLogger(SimpleInterceptor.class);
     
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
        Object handler) throws Exception {
        logger.info("Inside the prehandle");
         
        return false;
    }
}

攔截器註冊例子:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.apress.springrest.web" })
public class WebConfig extends WebMvcConfigurerAdapter {
 
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LocaleChangeInterceptor());
        registry.addInterceptor(new SimpleInterceptor()).addPathPatterns("/auth/**");
    }
}
相關文章
相關標籤/搜索