国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Spring之旅第十站:MVC配置、上傳文件、異常處理、跨重定向請求、為控制器添加通知

leanote / 1957人閱讀

摘要:依賴于對請求的支持。使用解析兼容的沒有構造器參數,也沒有要設置的參數,這樣,在應用上下文中,將其聲明為就會非常簡單。默認是沒有限制的整個請求的容量。

Spring MVC 高級的技術

本章內容:

Spring MVC配置的替代方案

處理文件上傳

在控制器中處理異常

使用flash屬性

稍等還沒結束

說明

如果你有幸能看到。后面的章節暫時不更新了,改變學習方式了。重要理解思想,這本書寫的太好了。記得要看作者的代碼,書上只是闡述了知識點。還有以后會把重點放在GitHub上,閱讀別人的代碼,自己理解的同時在模仿出來,分享給大家。你們的點贊就是對我的支持,謝謝大家了。

1、本文參考了《Spring 實戰》重點內容,參考了作者GitHub上的代碼,推薦使用chrome上的GitHub插件Insight.io,FireFox也有。

2、本文只為記錄作為以后參考,要想真正領悟Spring的強大,請看原書。跟著作者套路來,先別瞎搗騰!!!

3、在一次佩服老外,國外翻譯過來的書,在GiuHub上大都有實例。看書的時候,跟著敲一遍,效果很好。

4、代碼和筆記在這里GitHub,對你有幫助的話,歡迎點贊。

5、每個人的學習方式不一樣,找到合適自己的就行。2018,加油。

6、Java 8 In Action 的作者Mario Fusco、Spring In Action 、Spring Boot In Action的作者Craig Walls

7、知其然,也要知其所以然。有些是在Atom上手敲的,有拼寫錯誤,還請見諒。

8、從Spring Web Flow 開始,我要加快速度了,邏輯可能不完整,一切以原書為準,自己只是記錄。加深印象。

談一些個人感受

1、趕快學習Spring吧,Spring MVC 、Spring Boot 、微服務。

2、重點中的重點,學習JDK 8 Lambda,Stream,Spring 5 最低要求JDK1.8.

3、還有Netty、放棄SH吧,不然你會落伍的。

4、多看一些國外翻譯過來的書,例如 Xxx In Action 系列。權威指南系列。用Kindle~

5、寫代碼之前先寫測試,這就是老外不同之處。學到了很多技巧。

6、再一次佩服老外對細節的處理。值得我們每一個人學習

在很多方面,Spirng MVC(整個Spirng也是如此),也有還沒結束這樣的感覺。

在第五章,我們學習了Sprng MVC的基礎知識,以及如何編寫控制器來處理各種請求,基于這些知識。我們在第六章學習了如何創建JSP和Thymeleaf視圖,這些視圖會將模型數據展示給用戶。你可能認為我們已經掌握了Spring MVC的全部知識,但是,稍等!還沒結束。

在本章中,我們將會看到如何編寫控制器處理文件上傳,如何處理控制器所拋出的異常,以及如何在模型中傳遞數據,使其能夠在重定向(redirect)之后依然存活。

但,首先我要兌現一個承諾。在第5章中,我們快速展現了如何通過AbstractAnnotationConfigDispatcherServletInitializer搭建Spring MVC,當時,我們承諾會為讀者展現其他的配置方案。所以,在介紹文件上傳和異常處理之前,我們花時間探討一下如何使用其他方式來搭建DispatcherServletContextLoaderListener

7.1 Spring MVC 配置的替代方案

盡管對很多Spring應用來說,這是一種安全的假設,但是并不一定能滿足我們的要求。除了DispatcherServlet以外,我們還可能需要額外的DispatcherServletFilter,我們可能還需要對DispatcherServlet本身做一些額外的配置:或者,如果我們需要將應用部署到Servlet3.0之前的容器中,那么還需要將DispatcherServlet配置到傳統的web.xml中。

7.1.1 自定義DispatcherServlet配置
public class SpitterWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

  @Override
  protected Class[] getRootConfigClasses() {
    return new Class[] { RootConfig.class };
  }

  @Override
  protected Class[] getServletConfigClasses() {
    return new Class[] { WebConfig.class };
  }

  @Override
  protected String[] getServletMappings() {
    return new String[] { "/" };
  }

}

AbstractAnnotationConfigDispatcherServletInitializer所完成的事其實比看上去要多,在SpitterWebInitializer中我們所編寫的三個方法僅僅是必須要重載的三個抽象方法,但實際上還有更多的方法可以進行重載,從而實現額外的配置。

此類的方法之一就是customizeRegistration().在AbstractAnnotationConfigDispatcherServletInitializerDispatcherServlet注冊到Servlet容器中就會調用customizeRegistration(),并將Servlet注冊后得到的Registration.Dynamic傳遞進來,通過重載customizeRegistration()方法,我們就可以對DispatcherServlet進行額外的配置。

在本章稍后,我們將會看到如何在Spirng MVC中處理multiparty請求和文件上傳。如果計劃使用Servlet3.0對multiparty配置的支持,那么我們需要使用DispatcherServlet的registration來啟用multilpart請求。我們可以重載customizeRegistration()方法來設置MultipartConfigElement,

@Override
protected void customizeRegistration(Dynamic registration) {
    registration.setMultipartConfig(
            new MultipartConfigElement("C:Temp"));   //設置上傳文件目錄
}

借助customizeRegistration()方法中的ServletRegistration.Dynamic我們能夠完成更多的任務,

包括通過調用setLoadOnstartup()設置load-on-startup 優先級,

通過setInitParameter()設置初始化參數,

通過調用setMultipartConfig()配置Servlet3.0對multipart的支持,

7.1.2 添加其他的Servlet和Filter

按照AbstractAnnotationConfigDispatcherServletInitializer的定義,它會創建DispatcherServletContextLoaderListener.但是如果你想要注冊其他的Servlet、Filter、Listener的話,那該怎么辦?

基于Java的初始化器(initializer)的一個好處在于我們可以定義任意數量的初始化類。如果我們想要往Web容器中注冊其他組件的話,只需要創建一個 新的初始化類就可以了,最簡單的方式就是實現Spring的WebApplicationInitializer并注冊一個Servlet。

public class MyServletInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
      Dynamic  myServlet = servletContext.addServlet("myServlet",myServlet.class);
      myServlet.addMapping("/custom/**");
    }
}

以上程序相當基礎的Servlet注冊初始化器類,它注冊了一個Servlet并將其映射到了一個路徑上,我們也可以通過這種方式來手動注冊DispatcherServlet.(但是沒必要,因為AbstractAnnotationConfigDispatcherServletInitializer沒用太多代碼就將這項任務完成得很漂亮)

類似的,我們還可以創建新的WebApplicationInitializer來實現注冊Listener和 Filter,

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
    javax.servlet.FilterRegistration.Dynamic filter = servletContext.addFilter("myFilter",myFilter.class);
    filter.addMappingForUrlPatterns(null,false,"/custom/*");
}

如果你將應用部署到Servlet3.0的容器中,那么WebApplicationInitializer提供了一種通用的方法,實現在Java中注冊Servlet和Filter、Listener,如果你只是注冊Filter,并且該Filter只會映射到DispatcherServlet上的話,那么AbstractAnnotationConfigDispatcherServletInitializer還有一種快捷的方式。

為了注冊Filter并將其映射到DispatcherServlet,所需要做的僅僅是重載AbstractAnnotationConfigDispatcherServletInitializer的getServletFilter()方法。

@Override
protected Filter[] getServletFilters() {
    return new Filter[] {new Myfilter()};
}

這個方法返回一個javax.servlet.filter數組。在這里沒有必要聲明它的映射路徑,getServletFilter()方法返回所有Filter都會被映射到DispatcherServlet上。

如果要將應用部署到Servlet3.0上,那么Spring容器提供了多種注冊方式,而不必創建web.xml文件,但是,如果你不想采取上述方案的話,也是可以的,假設你將應用部署到不支持Servlet3.0的容器中(或者你只希望使用web.xml),那么我們完全可以按照傳統的方式,通過web.xml配置Spirng MVC,

7.1.3 在web.xml中聲明DispatcherServlet

在典型的Spirng MVC應用中,我們會需要DispatcherServletContextLoaderListener.AbstractAnnotationConfigDispatcherServletInitializer會自動注冊它們,但如果需要在web.xml中注冊的話,那就需要我們自己動手來完成了。



    appServlet
    
        index.html
    
    
    
        contextConfigLocation
        classpath:spring/applicationContext-*.xml
    
    
        org.springframework.web.context.ContextLoaderListener
    
    
    
        CharacterEncodingFilter
        org.springframework.web.filter.CharacterEncodingFilter
        
            encoding
            utf-8
        
    
    
        CharacterEncodingFilter
        /*
    
    
    
        appServlet
        org.springframework.web.servlet.DispatcherServlet
    
        
            contextConfigLocation
            classpath:spring/springmvc.xml
        
        1
    
    
        appServlet
        /
    

ContextLoaderListenerDispatcherServlet各自都會加載一個Spirng應用上下文。上下文ContextLoaderLocation指定了一個XMl文件的地址,這個文件定義了根據應用上下文,它會被ContextLoaderListener加載。根上下文會從"/WEB-INF/spring/applicationContext-*.xml"中加載bean的定義

DispatcherServlet會根據Servlet的名字找到一個文件,并基于該文件加載應用上下文。

如果你希望指定DispatcherServlet配置文件的話,那么可以在Servlet指定一個ContextLoaderLocation初始化參數。



  appServlet
  org.springframework.web.servlet.DispatcherServlet
  
  
    contextConfigLocation
    classpath:spring/springmvc.xml
  
  1


  appServlet
  /

現在我們已經看到了如何以多種不同的方式來搭建Spring MVC,那么接下來我們看一下如何使用Spring MVC來處理文件上傳。

7.2 處理multipart形式的數據

在Web應用中,允許用戶上傳內容是很常見的需求,在Facebook和Flickr這樣的網站中,允許用戶會上傳圖片和視頻,并與家人朋友分享。還有一些服務器中允許用戶上傳照片,然后按照傳統的方式將其打印在紙上,或者咖啡杯上。

Spittr應用有兩個地方需要文件上傳。當新用戶注冊的時候,我們希望能夠上傳一張照片,從而與他的個人信息相關聯。當用戶提交新的Spittle時,除了文本信息外,他們可能還會上傳一張照片。

一般表單提交所形成的請求結果是非常簡單的,就是以"&"符號分割的多個name-value對,盡管這種方式簡單,并且對于典型的基于文本的表單提交也足夠滿足需求,但是對于二進制數據,就顯得力不從心了。與之不同的是multipart格式的數據會將一個表單拆分為多個部分(part),每個部分對應一個輸入域。在一般的表單輸入域中,它所對應的部分中會放置文本數據,但是如果是上傳文件的話,它所對應的部分可以是二進制。

Content-Type 他表它的類型。盡管multipart請求看起來很復雜,但是在SpringMVC中處理它卻很容易,在編寫控制器方法處理文件上傳之前,我們必須配置一個multipart解析器,通過它來告訴DispatcherServlet該如何讀取multipart請求。

7.2.1 配置multipart解析器

DispatcherServlet并沒有實現愛你任何解析multipart請求數據的功能。它將該任務委托給了Spring中的MultipartResolver策略接口的實現,通過這個實現類來解析multipart請求中的內容。從Spirng 3.1開始,Spirng內置了兩個MultipartResolver的實現供我們選擇。

CommonsMultipartResolver:使用Jakarta Commons FileUpload解析multipart請求。

StandardServletMultipartResolver:依賴于Servlet3.0對multipart請求的支持。

一般來講StandardServletMultipartResolver可能會是優選方案,他使用Servlet所提供的功能支持。并不需要依賴任何其他的項目。如果,我們需要將項目部署到Sevrvlet3.0之前的容器中,或者還沒有使用Spring 3.1 或者更高的版本,那么可能就需要 CommonsMultipartResolver了。

使用Servlet3.0解析multipart

兼容Servlet3.0的StandardServletMultipartResolver沒有構造器參數,也沒有要設置的參數,這樣,在Spring應用上下文中,將其聲明為bean就會非常簡單。

@Bean
public MultipartResolver multipartResolver() throws IOException {
    return new StandardServletMultipartResolver();
}

如果我們采用Servlet初始化類的方式來配置DispatcherServlet的話,這個初始化類應該已經實現了WebApplicationInitializer,那么我們可以在ServletRegistration上調用setMultipartConfig()方法,傳入一個MultipartConfigElement實例,具體的配置如下:

@Override
protected void customizeRegistration(Dynamic registration) {
    registration.setMultipartConfig(
            new MultipartConfigElement("C:Temp"));
}
}

通過重載customizeRegistration()方法(它會得到一個Dynamic作為參數)類配置multipart的具體細節。

到目前為止,我們所使用的是只有一個參數的MultipartConfigElemenet構造器,這個參數指定的是文件系統中一個絕對目錄,上傳文件將會臨時寫入該目錄,但是,我們還可以通過其他的構造器來限制上傳文件的大小,除了臨時路徑的位置,其他的構造器可以接受的參數如下:

上傳文件的最大容量(以字節為單位)。默認是沒有限制的

整個multipart請求的容量。不會關心有多少個part以及每個part的大小。默認是沒有限制的。

在上傳的過程中,如果文件大小達到了一個指定最大容量,將會寫入到臨時文件路徑中,默認值為0,也就是所有上傳的文件都會寫入磁盤上。

例如,假設我們想要限制文件的大小不超過2MB,整個請求不超過4MB,而且所有的文件都要寫入磁盤,

@Override
protected void customizeRegistration(Dynamic registration) {
    registration.setMultipartConfig(
            new MultipartConfigElement("C:Tempuploads",2097152, 4194304, 0));
}

如果使用更為傳統的web.xml來配置MultipartConfigResolver的話,那么可以使用中的元素


  appServlet
  org.springframework.web.servlet.DispatcherServlet
  1
  
    C:Tempuploads
    2097152
    4194304 
  

配置Jakarta Commons FileUpload Multipart解析器

Spring內置了CommonsMultipartResolver,可以作為StandardServletMultipartResolver的替代方案。

7.2.2 處理multipart請求。

已經配置好multipart請求的處理器,那么接下來我們就編寫控制器方法來接收上傳的文件。要實現這一點,最常見的方法就是在某個控制器方法參數上添加@RequestPart注解。

:

標簽現在將enctype屬性設置為multipart/form-data,這會告訴瀏覽器以multipart數據的形式提交表單,而不是以表單數據的形式進行提交。還添加了一個新的< input>域其type為file。 accept屬性用來將文件類型限制為jpeg,png,gif格式的。根據name屬性,圖片數據將會發送到multipart請求中的profilePicture之中。

現在我們需要修改processRegistration()方法,使其能夠接受上傳的圖片。其中一種方式就是添加btye數組,并為其添加@RequestPart注解。

@RequestMapping(value="/register", method=POST)
public String processRegistration(
    @RequestPart(value = "profilePictures") byte[] profilePicture,
    @Valid Spitter spitter,
    Errors errors) {

當表單提交的時候,profilePicture屬性將會給定一個byte數組,這個數組中包含了請求中對應的part的數據(通過@RequestPart指定的)。如果沒有選擇文件,那么這個數據為空(而不是null),獲取到圖片數據后,processRegistration()方法剩下的任務就是將文件保存到某個地方。

接受MultipartFile

使用上傳文件的原始byte比較簡單,但是功能有限。因此,Spring提供了MultipartFile接口,它為處理multipart數據提供了內容更為豐富的對象。

package org.springframework.web.multipart;
/**
 * A representation of an uploaded file received in a multipart request.
 * @author Juergen Hoeller
 * @author Trevor D. Cook
 */
public interface MultipartFile {
    /**
     * Return the name of the parameter in the multipart form.
     * @return the name of the parameter (never {@code null} or empty)
     */
    String getName();
    /**
     * Return the original filename in the client"s filesystem.
     */
    String getOriginalFilename();
    /**
     * Return the content type of the file.
     */
    String getContentType();
    /**
     * Return whether the uploaded file is empty, that is, either no file has
     * been chosen in the multipart form or the chosen file has no content.
     */
    boolean isEmpty();
    /**
     * Return the size of the file in bytes.
     */
    long getSize();
    /**
     * Return the contents of the file as an array of bytes.
     */
    byte[] getBytes() throws IOException;
    /**
     * Return an InputStream to read the contents of the file from.
     */
    InputStream getInputStream() throws IOException;
    /**
     * Transfer the received file to the given destination file.
     */
    void transferTo(File dest) throws IOException, IllegalStateException;
}

可以看到,MultipartFile提供了獲取文件上傳文件byte的方式,還能獲取原始的文件名,大小以及內容類型、還提供了一個InputStream用來將文件數據以流的方式進行讀取。

除此之外,還提供了一個transferTo()方法,它能夠幫助我們將上傳文件寫入到文件系統中。作為樣例,我們在可以在processRegistration()方法中添加如下的幾行代碼,從而將上傳的圖片文件寫入到文件系統中

profilePicture.transferTo(
        new File("date/spittr" + profilePicture.getOriginalFilename()));

將文件保存到本地文件系統中是非常簡單的,但是這需要我們對這些文件進行管理。我們需要確保有足夠的空間,確保當出現硬件故障時,文件進行了備份,還需要在集群的多個服務器之間處理這些圖片文件的同步。

以Part的形式接受上傳的文件

Spring MVC接受javax.servlet.http.Part作為控制器方法的參數,如果使用part來替換MultiFile的話,那么processRegistration()方法簽名會變成如下的形式。

@RequestMapping(value="/register", method=POST)
public String processRegistration(
    @RequestPart(value="profilePictures", required=false) Part fileBytes,
    RedirectAttributes redirectAttributes,
    @Valid Spitter spitter,
    Errors errors) throws IOException {
  if (errors.hasErrors()) {
    return "registerForm";
  }

Part接口

package javax.servlet.http;
public interface Part {
  public InputStream getInputStream() throws IOException;

  public String getContentType();

  public String getName();

  public String getSubmittedFileName();

  public long getSize();

  public void write(String fileName) throws IOException;

  public void delete() throws IOException;

  public String getHeader(String name);

  public Collection getHeaders(String name);

  public Collection getHeaderNames();
}

很多情況下,Part方法的名稱與MultiPartFile方法的名稱是完全相同的。有一些比較類似,但是稍有差別。
比如getSubmittedFileName()方法對應getOriginalFilename().類似的,write()方法對應于transfer()方法,借助該方法我們能夠將上傳的文件寫入文件系統中。

值得一提的是,如果沒有在編寫控制器方法的時候,通過Part參數的形式接受文件上傳,那就沒必要配置MultipartResolver了。只有使用MultipartFile的時候 ,我們才需要MultipartResolver.

7.3 處理異常

Spring提供了多種方式將異常轉換為響應

特定的Spring異常將會自動映射為指定的HTTP狀態碼

異常上可以添加@RequestStatus注解,從而將其映射為某一個HTTP狀態

在方法上添加@ExceptionHandle注解,使其用來處理異常。

處理異常最簡單的方式就是將其映射到HTTP狀態碼上。

7.3.1 將異常映射 為HTTP狀態碼

異常一般由Spring自身拋出,作為DispatcherServlet處理過程中或執行校驗時出現問題的結果。

Spring提供了一種機制,能夠通過使用@RequestStatus注解將其映射為HTTP狀態碼

@RequestMapping(value="/{spittleId}", method=RequestMethod.GET)
public String spittle(
    @PathVariable("spittleId") long spittleId,
    Model model) {
  Spittle spittle = spittleRepository.findOne(spittleId);
  if (spittle == null) {
    throw new SpittleNotFoundException();     //這里會拋出異常
  }
  model.addAttribute(spittle);
  return "spittle";
}

如果資源沒有找到的話,HTTP狀態碼404是最為精確的響應狀態碼

@ResponseStatus(value=HttpStatus.NOT_FOUND, reason="Spittle Not Found")
public class SpittleNotFoundException extends RuntimeException {
}
7.3.2 編寫異常處理方法

如果響應中不僅包含狀態碼,還要包含所產生的錯誤信息,需要按照請求的方式來處理異常。

@RequestMapping(method=RequestMethod.POST)
public String saveSpittle(SpittleForm form, Model model) {
  try {
    spittleRepository.save(new Spittle(null, form.getMessage(), new Date(),
        form.getLongitude(), form.getLatitude()));
    return "redirect:/spittles";
  } catch (DuplicateSpittleException e) {     //捕獲異常
    return "error/duplicate";
  }
}
@RequestMapping(method=RequestMethod.POST)
public String saveSpittle(SpittleForm form, Model model) {
    spittleRepository.save(new Spittle(null, form.getMessage(), new Date(),
        form.getLongitude(), form.getLatitude()));
    return "redirect:/spittles";
    return "error/duplicate";
}

它只關注成功保存Spittle的情況,所以只需要一個執行路徑,很容易理解和測試。

@ExceptionHandler(DuplicateSpittleException.class)
public String handleNotFound() {
  return "error/duplicate";
}

方法上加上@ExceptionHandler注解后,當方法拋出異常的時候,將委托該方法來處理,它能夠處理同一個控制器中所有的方法拋出的異常。

7.4 為控制器添加通知

如果控制器類的特定切面能夠 運用到整個應用程序的所有控制器中,那么這將會便利很多。,為了 避免重復,我們會創建一個基礎的控制器,所有的控制器類要擴展這個類,從而繼承通用的@ExceptionHandler方法。

Spring3.2 引入了一個新的解決方法:控制器通知。控制器通知(controllerAdvice)是任意帶有@ControllerAdvice注解的類,這個類會包含一個或多個 如下類型的方法:

@ExceptionHandle注解標注的方法

@InitBinder注解標注的方法

@ModelAttribute注解標注的方法。

@ControllerAdvice
public class AppWideExceptionHandler {

  @ExceptionHandler(DuplicateSpittleException.class)
  public String handleNotFound() {
    return "error/duplicate";
  }

}
7.5 跨重定向請求傳遞數據

“redirect:”前綴能讓重定向功能變得更簡單,但是,請稍等,Spirng為重定向功能還提供了一些其他的輔助功能。

當一個處理器方法完成之后,該方法所指定的模型數據會將復制到請求中,并作為請求中的屬性,請求會轉發(forward)到視圖上進行渲染。

對于 重定向來說,模型并不能徹底數據,有一些其他方法,能夠從發起重定向的方法傳遞數據給處理重定向的方法

使用URL模板以路徑變量和/或查詢參數的形式傳遞數據

通過flash屬性發生數據

7.5.1 通過URL模板進行重定向
@RequestMapping(value="/register", method=POST)
public String processRegistration(
        @Valid SpitterForm spitterForm,
        Errors errors) throws IllegalStateException, IOException {

    if (errors.hasErrors()) {
        return "registerForm";
    }
    Spitter spitter = spitterForm.toSpitter();
    spitterRepository.save(spitter);
    MultipartFile profilePicture = spitterForm.getProfilePicture();
    profilePicture.transferTo(new File("/tmp/spittr/" + spitter.getUsername() + ".jpg"));
    return "redirect:/spitter/" + spitter.getUsername();    //根據名字重定向
}

通過路徑變量和查詢參數的形式跨重定向傳遞數據是很簡單直接的方式,但是也有限制它只能發送簡單的值,如String和數字的值。在URl中,并沒有 辦法發送更為復雜的值,但這正是flash屬性能夠提供幫助。

### 7.5.2 使用flash屬性。

有個方案是將Spittr放到會話中,會話能長期存在,并且會話能夠跨多個請求,所以我們可以在重定向之前將Spittr放到會話中,并在重定向后,從會話中取出 ,當然,我們需要負責在重定向之后在會話中將其清理掉。

Spring提供了將數據發送為flash屬性的功能,按照定義,flash屬性會一直攜帶這些數據,直到下一次請求,然后才消失

Spring提供了通過RedirectAttributes設置flash屬性的方式,這是Spring3.1引入的Modwl的一個子接口 。 RedirectAttributes提供了Model的所有功能。除此之外,還有幾個方法用來設置flash屬性。

public String processRegistration(
   @RequestPart(value="profilePictures", required=false) Part fileBytes,
   RedirectAttributes redirectAttributes,
   @Valid Spitter spitter,
   Errors errors) throws IOException {
 if (errors.hasErrors()) {
   return "registerForm";
 }

 spitterRepository.save(spitter);
 redirectAttributes.addAttribute("username", spitter.getUsername());
   //調用方法,將spitter作為ket,Spitter作為值。也可以不設置值,根據值得類型自行判斷。
 redirectAttributes.addFlashAttribute(spitter);
 return "redirect:/spitter/" + spitter.getUsername();

在重定向之前,所有的flash屬性都會復制到會話中,在重定向結束后,存在會話中的 flash屬性會被取出,并從會話中轉移到模型之中。

@RequestMapping(value="/{username}", method=GET)
public String showSpitterProfile(
        @PathVariable String username, Model model) {
  if (!model.containsAttribute("spitter")) {
    model.addAttribute(
        spitterRepository.findByUsername(username));
  }
  return "profile";
}

showSpitterProfile()方法首先檢查是否存在key為sptter的modle屬性。如果模型中包含的話,那就什么都不用做了。包含的Spitter對象將會傳遞到視圖中進行渲染。如果不包含則從spitterRepository中查找Spitter,并將其放到模型中。

7.6 小節(最喜歡這里)

在Spirng中,總是會有“還沒有結束”的感覺更多的特性,更多的選擇,以及實現開發目標的更多方式。Spring MVC有很多功能和技巧。

當然,Spirng MVC的環境搭建是由多種可選方案的一個領域。在本章中,我們首先看來一下搭建Spring MVC中DispatcherServletContextLoaderListener的多種方式。還看到了如何調整DispatcherServlet的注冊功能以及如何注冊自定義的Servlet和FIlterr。如果你需要將應用部署到更老的服務器上,我們還快速了解了如何使用web.xml聲明DispatcherServletContextLoaderListener.

然后我們了解 如何處理Spirng MVC控制器所拋出的異常,盡管帶有@Requestmapping注解的方法可以在自身的代碼中處理異常,但是如果將異常處理的代碼抽取到多帶帶的方法中,那么控制器的代碼會整潔很多。

為了采用一致的方式處理通用的任務,包括在應用中的所有控制器 中處理異常,Spirng 3.2 引入了@ControllerAdvice,他所創建的類能夠將控制器的通用行為抽取到同一個方法。

最后,我們看了下如何跨重定向傳遞數據,包括Spring對flash屬性的支持:類似于模板,但是能在重定向后存活下來。這樣的話,就能采用非常恰當的方式為POST請求執行一個重定向回應。而且能夠將處理POST請求時的模型數據傳遞過來,然后再重定向后使用或展現這些模型數據。

如果你有疑惑的話,那么可以告訴你,這就是我所說的“更多的功能”,其實,我們并沒有討論到Spirng MVC 的每個方面。我們將會在16章中重新討論 Spirng MVC,到時你會看到如何使用它來創建REST API。

但現在,我們將會暫時放下Spring MVC,看一下Spirng web Flow,這是一個構建在Spirng MVC 之上的流程框架,它能夠引導用戶執行一系列向導步驟。

納悶,你忘記總結文件上傳了。期待下一章。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/68576.html

相關文章

  • Spring之旅第十二站:Spring Security 數據存儲、攔截請求 、認證用戶、*、

    摘要:啟用安全性這個簡單的默認配置指定了如何保護請求,以及客戶端認證用戶的方案。基于數據庫進行認證用戶數據通常會存儲在關系型數據庫中,并通過進行訪問。必須經過認證其他所有請求都是允許的,不需要認證。要求用戶不僅需要認證,還要具備權限。 Spring Security Spring Security 是基于Spring 應用程序提供的聲明式安全保護的安全框架。Spring Sercurity ...

    YuboonaZhang 評論0 收藏0
  • Spring之旅第八站:Spring MVC Spittr舞臺的搭建、基本的制器請求的輸入、表

    摘要:請求旅程的第一站是的。的任務是將請求發送控制器控制器是一個用于處理請求的組件。處理映射器根據請求攜帶的信息來進行決策。這樣的結果就是,只能找到顯示聲明在配置類中的控制器。 構建Spring Web應用 說明 如果你有幸能看到。 1、本文參考了《Spring 實戰》重點內容,參考了GitHub上的代碼 2、本文只為記錄作為以后參考,要想真正領悟Spring的強大,請看原書。 3、在一次...

    maybe_009 評論0 收藏0
  • 超實用百道Java面試題

    摘要:是的簡稱,運行環境,為的運行提供了所需的環境。分割字符串,返回分割后的字符串數組。當計算的值相同時,我們稱之為沖突,的做法是用鏈表和紅黑樹存儲相同的值的。迭代器取代了集合框架中的,迭代器允許調用者在迭代過程中移除元素。 Java基礎1.JDK和JRE有什么區別? JDK 是java development kit的簡稱,java開發工具包,提供java的開發環境和運行環境。JRE 是j...

    MkkHou 評論0 收藏0
  • 通過項目逐步深入了解Spring MVC(一)

    摘要:是一個基于的框架。控制器將視圖響應給用戶通過視圖展示給用戶要的數據或處理結果。有了減少了其它組件之間的耦合度。 相關閱讀: 本文檔和項目代碼地址:https://github.com/zhisheng17/springmvc 轉載請注明出處和保留以上文字! 了解 Spring: Spring 官網:http://spring.io/ 一個好的東西一般都會有一個好的文檔解釋說明,如果你...

    whataa 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<