基于注解的 SpringMVC 簡單介紹

jopen 12年前發布 | 115K 次閱讀 SpringMVC Spring MVC Web框架

SpringMVC是一個基于DispatcherServlet的MVC框架,每一個請求最先訪問的都是DispatcherServlet,DispatcherServlet負責轉發每一個Request請求給相應的Handler,Handler處理以后再返回相應的視圖(View)和模型(Model),返回的視圖和模型都可以不指定,即可以只返回Model或只返回View或都不返回。

DispatcherServlet是繼承自HttpServlet的,既然SpringMVC是基于DispatcherServlet的,那么我們先來配置一下DispatcherServlet,好讓它能夠管理我們希望它管理的內容。HttpServlet是在web.xml文件中聲明的。

    <servlet>
        <servlet-name>blog</servlet-name>

    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>blog</servlet-name>

    <url-pattern>*.do</url-pattern>
</servlet-mapping></pre> 

上面聲明了一個名為blog的DispatcherServlet,該Servlet將處理所有以“.do”結尾的請求。在初始化DispatcherServlet的時候,SpringMVC默認會到/WEB-INF目錄下尋找一個叫[servlet-name]-servlet.xml的配置文件,來初始化里面的bean對象,該文件中對應的bean對象會覆蓋spring配置文件中聲明的同名的bean對象。如上面的就會在/WEB-INF目錄下尋找一個叫blog-servlet.xml的文件;當然也可以在Servlet中聲明配置文件的位置。

    <servlet>

    <servlet-name>blog</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>

        <param-value>/WEB-INF/blog-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>

    <servlet-name>blog</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping></pre> 

DispatcherServlet會利用一些特殊的bean來處理Request請求和生成相應的視圖返回。

關于視圖的返回,Controller只負責傳回來一個值,然后到底返回的是什么視圖,是由視圖解析器控制的,在jsp中常用的視圖解析器是InternalResourceViewResovler,它會要求一個前綴和一個后綴

    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/" />
        <property name="suffix" value=".jsp" />
    </bean>

在上述視圖解析器中,如果Controller返回的是blog/index,那么通過視圖解析器解析之后的視圖就是/WEB-INF/blog/index.jsp。

要使用注解的SpringMVC需要在SpringMVC的配置文件中進行聲明,具體方式為先引入mvc命名空間,然后利用<mvc:annotation-driven />進行聲明。

<beans xmlns="http://www.springframework.org/schema/beans&quot;
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance&quot; xmlns:context="http://www.springframework.org/schema/context&quot;
    xmlns:mvc="http://www.springframework.org/schema/mvc"</span>  xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-3.0.xsd
     http://www.springframework.org/schema/mvc
     http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

<mvc:annotation-driven />

</beans></pre>

主要是說說Controller.

一個類使用了@Controller進行標記的都是Controller

@Controller
public class BlogController {

}</pre>

有了Controller之后,那么到底是怎樣請求一個Controller具體的方法的呢,那是通過@RequestMapping來標記的,@RequestMapping可以標記在類上面,也可以標記在方法上,當方法上和類上都標記了@RequestMapping的時候,那么對應的方法對應的Url就是類上的加方法上的,如下面的index方法,其對應的URL應為類上的/blog加上index方法上的/index,所以應為/blog/index,所以當請求/blog/index.do的時候就會訪問BlogController的index方法。

@Controller
@RequestMapping("/blog")
public class BlogController {

@RequestMapping("/index")
public String index(Map<String, Object> map) {
    return "blog/index";
}

}</pre>

在上面的代碼中,如果index方法上沒有RequestMapping注解,而只有BlogController類上有,且該類只有一個方法的時候,直接請求類上的URL就會調用里面的方法,即直接請求/blog.do的時候就會調用index方法。

在RequestMapping中還可以指定一個屬性method,其主要對應的值有RequestMethod.GET和RequestMethod.POST,利用該屬性可以嚴格的控制某一方法只能被標記的請求路徑對應的請求方法才能訪問,如指定method的值為GET,則表示只有通過GET方式才能訪問該方法,默認是都可以訪問。

在SpringMVC中常用的注解還有@PathVariable,@RequestParam,@PathVariable標記在方法的參數上,利用它標記的參數可以利用請求路徑傳值,看下面一個例子

   @RequestMapping(value="/comment/{blogId}", method=RequestMethod.POST)
    public void comment(Comment comment,@PathVariable int blogId, HttpSession session, HttpServletResponse response) throws IOException {

}</pre> 

在該例子中,blogId是被@PathVariable標記為請求路徑變量的,如果請求的是/blog/comment/1.do的時候就表示blogId的值為1. 同樣@RequestParam也是用來給參數傳值的,但是它是從頭request的參數里面取值,相當于request.getParameter("參數名")方法。

在Controller的方法中,如果需要WEB元素HttpServletRequest,HttpServletResponse和HttpSession,只需要在給方法一個對應的參數,那么在訪問的時候SpringMVC就會自動給其傳值,但是需要注意的是在傳入Session的時候如果是第一次訪問系統的時候就調用session會報錯,因為這個時候session還沒有生成。

接下來討論一下方法的返回值,主要有一下情況:

  • 返回一個ModelAndView,其中Model是一個Map,里面存放的是一對對的鍵值對,其可以直接在頁面上使用,View是一個字符串,表示的是某一個View的名稱
  • 返回一個View,也就是一個字符串,這個時候如果需要給頁面傳值,可以給方法一個Map參數,該Map就相當于一個Model,往該Model里面存入鍵值對就可以在頁面上進行訪問了
  • 返回一個Model也就是一個Map,這個時候將解析默認的生成的view name。
  • 什么也不返回,這個時候可以利用HttpServletResponse進行返回,也可以直接使用printStream進行返回
下面是一個簡單的實例
        @RequestMapping("/{owner}/index")
    public String userIndex(Map<String, Object> map,@PathVariable String owner, HttpServletRequest request) throws ParserException {
        List<DefCategory> categories = categoryService.find(owner);
        int offset = Util.getOffset(request);
        Pager<Blog> pager = blogService.find(owner, 0, offset, maxResults);
        int totalRecords = pager.getTotalRecords();
        List<Blog> blogs = pager.getData();
        Util.shortBlog(blogs);

    List<Message> messages = messageService.find(owner, 0, 5).getData();
    Util.shortMessage(messages, 20);
    map.put("messages", messages);
    map.put("totalRecords", totalRecords);
    List<BlogStore> stores = storeService.find(owner, 0, 5).getData();
    map.put("maxResults", maxResults);
    map.put("blogs", blogs);
    map.put("totalRecords", totalRecords);
    map.put("owner", userService.find(owner));
    map.put("defCategories", categories);
    map.put("stores", stores);
    return "blog/userIndex";
}</pre> 

</div> 來自: http://haohaoxuexi.iteye.com/blog/1343761

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!