SpringMVC框架

SpringMVC的基本概念

什麼是MVC
是一種基於兩種形式,一種是C/S架構,也就是客戶端/服務器,
另一種是B/S架構,也就是瀏覽器/服務器. 在JavaEE中,幾乎全是基於B/S架構的開發,
那麼在B/S架構中,系統標準的三層架構包括:表現層,業務層,持久層.

什麼是SpringMVC?
SpringMVC是一種基於java實現的MVC設計模型的請求驅動類型的輕量級WEB框架,爲目前最主流的MVC框架之一,他通過一套註解,讓一個簡單的java類成爲處理請求的控制器,無需實現任何接口.同時還支持RESTful編程風格的請求
MVC設計模型:
M: model 模型 javaBean對象 一般用於封裝數據
V: view 視圖 JSP/Html 一般用於展示數據
C: Controller 控制器 Servlet 一般用於處理程序邏輯

SpringMvc和Struts2:

共同點:
他們都是表現層的框架,都是基於MVC模型編寫的
他們的底層都離不開ServletAPI
他們的處理請求的機制都是一個核心控制器
區別:
SpringMVC的入口是Servlet , Struts2的入口是Filter
SpringMVC是基於方法設計的, Struts2是基於類設計的,Struts2每次執行都會創建一個動作類,而SpringMVC只會創建一個類,執行時調用類中的方法.
SpringMVC更加簡潔,同時還支持JSR303,處理ajax的請求更方便
Struts2的OGNL表達式使頁面的開發效率相比SpringMVC更高,但執行效率並沒有比JSTL提升,尤其是struts2的表單標籤,遠沒有html執行效率高.

SpringMVC搭建環境

在New Module的 Properties屬性添加插件(解決maven項目創建過慢):
Name:archetypeCatalog Value:internal
創建java目錄: java,resource目錄

pom.xml文件

<properties>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 <maven.compiler.source>1.7</maven.compiler.source>
 <maven.compiler.target>1.7</maven.compiler.target>
 <spring.version>5.0.2.RELEASE</spring.version>
</properties>

<!--Spring MVC依賴-->
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>${spring.version}</version>
</dependency>
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-web</artifactId>
   <version>${spring.version}</version>
</dependency>
<dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>javax.servlet-api</artifactId>
   <version>3.1.0</version>
   <scope>provided</scope>
</dependency>
<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-context</artifactId>
 <version>${spring.version}</version>
</dependency>

web.xml文件配置:

<!--  前端控制器的配置-->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    //springmvc提供的類
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  
    <!--加載springmvc.xml配置文件-->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.xml</param-value>
    </init-param>

    <!--一般servlet只有當發送請求時才創建
       配置該參數,只要服務器一啓動,就會創建servlet對象,
       servlet對象一創建,就會去加載springmvc.xml文件
    -->
    <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>dispatcherServlet</servlet-name> 
            <url-pattern>/</url-pattern>  / :不管發什麼請求,都會經過servlet
        </servlet-mapping>

    <!--配置解決中文亂碼的過濾器-->
    <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/</url-pattern>     / :不管發什麼請求,都會經過過濾器
    </filter-mapping>

springmvc.xml文件配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        https://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
     
     <!--開啓註解的掃描-->
     <context:component-scan base-package="com.tulun"></context:component-scan>
     <!--配置視圖解析器-->
     <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
         <!--prefix: 文件所在的目錄-->
         <property name="prefix" value="/WEB_INF/pages/"/>
         <!--文件的後綴名-->
         <property name="suffix" value=".jsp"/>
     </bean>

     <!--開啓SpringMVC框架的註解的支持-->
     <mvc:annotation-driven/>
</beans>

index.jsp文件:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>入門程序</h3>

    <a href="hello">入門程序</a>
</body>
</html>

HelloController.java文件:

//控制器的類 ,用來接收請求
@Controller
public class HelloController {
    //在方法上面添加請求的映射
    //(path="/hello"  那麼以後/hello就是該方法的請求路徑)
    @RequestMapping(path = "/hello")
public String sayHello() {
    System.out.println("Hello SpringMVC");
  //默認返回的值爲當前jsp文件的名字
    return "success";
    }
}

WEB-INF目錄下添加pages/success.jsp文件:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h3>入門成功</h3>
</body>
</html>

運行的步驟

1.導入依賴
2.在web.xml配置前端控制器(在起啓動服務器的時候就加載springmvc.xml文件)
3.在index.jsp文件創建一個鏈接 
入門程序
4.在springmvc.xml文件

 <!--開啓註解的掃描-->
     <context:component-scan base-package="com.tulun"></context:component-scan>

當你點開該鏈接,就會去該包下的類查找index.jsp文件的 的值(也就是類中的方法)
5.找到之後

@RequestMapping(path="/hello")
public String sayHello() {
    System.out.println("Hello SpringMVC");
    //默認返回的值爲當前jsp文件的名字
    return "success";
}

6.接下來在springmvc.xml文件配置視圖解析器

<!--配置視圖解析器-->
 <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
         <!--prefix: 文件所在的目錄-->  
         <property name="prefix" value="/WEB-INF/pages/"/>
         <!--文件的後綴名-->
         <property name="suffix" value=".jsp"/>
 </bean>```

以上兩個配置的意義:就會去在/WEB-INF/pages/目錄下找名字爲success.jsp的文件
所以需要在該目錄下創建該文件success.jsp(例:此處爲成功請求頁面)

常用註解

@RequestMapping註解

用於建立請求URL和處理請求方法之間的對應關係
可以放在方法上,也可以是類
試例:

<a href="controller/testRequestMapping">RequestMapping註解</a>

@RequestMapping(path = "/controller")
public class HelloController {
     @RequestMapping(path = "/testRequestMapping")
     public String testRequestMapping() {
     }
}

屬性:

value和path的作用是一樣的

@RequestMapping(path = "/controller")
public class HelloController {
    @RequestMapping(value = "/testRequestMapping")
    public String testRequestMapping() {
    }
}

method: 請求方式

//method={RequestMethod.POST} 表示該方法的請求必須爲 post 方式 (爲枚舉類型)
   @RequestMapping(path = "/testRequestMapping",method={RequestMethod.POST})
   public String testRequestMapping() {
   }

params: 請求的時候必須傳入一個 username的參數 如果params = {“username=hehe”}傳入的參數必須爲這樣 ?username=hehe

    @RequestMapping(path = "/testRequestMapping",params ={"username"})
    public String testRequestMapping() {
    }
<a href="controller/testRequestMapping?username=haha">RequestMapping註解</a>

@RequestParam:

把請求中指定名稱的參數給控制器中的形參賦值

<a href="anno/testRequestParam?name=haha">RequestParam</a>

@RequestMapping("/testRequestParam")
public String testRequestParam(@RequestParam(value = "name") String username) {
  System.out.println("執行了...");
  return "success";
}

@RequestBody:

獲取到請求體的內容

<form action="/anno/testRequestBody" method="post">
  姓名: <input type="text" name="username"/><br/>
  密碼: <input type="text" name="age"/><br/>
  <input type="submit" value="提交"/>
</form>

/**
* 獲取到請求體的內容
* @param body
* @return
*/
@RequestMapping("testRequestBody")
public String testRequestBody(@RequestBody String body) {
  System.out.println("執行了...");
  return "success";
}

@PathVaribale:

和restful風格很像 path="/user/{id}" 傳一個佔位符

  RESTful風格URL:
   優點:節後清晰,符合標準,易於理解,擴展方便,更利於緩存
原來方式:
    UserController類
path="/user/save"
save

path="/user/update"
update

path="/user/findAll"
findAll

restful方式: 根據不同的請求方式,找到方法執行
   UserController類
path="/user" post
save

path="/user"   put
update

path="/user"  get
findAll

path="/user/{id}"  get
findById(id)

localhost:8080/user/10  get(請求方式)   查詢的是findById
localhost:8080/user       get 查詢的是findAll

@SessionAttribute

anno.jsp文件

<%--SessionAttritubes--%>
<a href="anno/testSessionAttributes">SessionAttributes</a>
<a href="anno/getSessionAttribute">SessionAttributes</a>
<a href="anno/delSessionAttribute">SessionAttributes</a>
AnnoController.java
@SessionAttributes("msg")   //將數值存入Session域
public class AnnoController {
    
	/**
	 * testSessionAttributes註解  向session存值
	 * @return
	 */
	@RequestMapping("/testSessionAttribute")
	public String testSessionAttributes(Model model) {
	    System.out.println("testSessionAttributes...");
	    //將一組鍵值對存入model對象 會存儲到Request域對象中
	    model.addAttribute("msg","meimei");
	    return "success";
	}
	/**
	 * 獲取值
	 * @param modelMap
	 * @return
	 */
	@RequestMapping("/getSessionAttribute")
	public String testGetSessionAttributes(ModelMap modelMap) {
	    System.out.println("testSessionAttributes...");
	    String msg = (String)modelMap.get("msg");
	    System.out.println(msg);
	    return "success";
	}
	/**
	 * 刪除值
	 * @param sessionStatus
	 * @return
	 */
	@RequestMapping("/delSessionAttribute")
	public String testDelSessionAttributes(SessionStatus sessionStatus) {
	    System.out.println("testSessionAttributes...");
	    //清空Session域
	    sessionStatus.setComplete();
	    return "success";
	}
}

success.jsp

                                          <!--說明不忽略EL表達式-->
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
${ requestScope }
${ sessionScope }

返回值

response.jsp文件

<a href="user/testString">TestString</a>

<a href="user/testVoid">TestVoid</a>

UserController.java文件

//返回值爲字符串
@RequestMapping(path = "/testString")
public String testString(Model model) {
    System.out.println("testString...");
    //模擬從數據庫中查詢User對象
    User user = new User();
    user.setUname("fly");
    user.setAge(19);
    user.setDate(new Date());
    //model存對象
    model.addAttribute("user",user); //存入request域
    return "success";
}
//返回值爲void  注:如果沒有返回值,會默認去WEB-INF/pages/user/找testVoid.jsp文件
@RequestMapping(path = "/testVoid")
public void testVoid(HttpServletRequest request,HttpServletResponse response) throws Exception {
    System.out.println("testVoid...");
    //請求轉發 手動轉發不會調用視圖解析器 所以要自己寫路徑
    request.getRequestDispatcher("WEB-INF/pages/success.jsp").forward(request,response);
    //重定向 會重定向請求index.jsp
    response.sendRedirect(request.getContextPath()+"/index.jsp");
    
    //設置中文亂碼
    response.setCharacterEncoding("UTF-8");
    response.setContentType("text/html;charset=UTF-8");
    //會直接進行響應
    response.getWriter().println("你好");
}

異常處理

     異常處理思路:Controller調用service ,service調用dao,異常都是向上拋出的,最終由DispatcherServlet異常處理器進行異常的處理.
    SpringMVC異常處理:在前端控制器配置一個 異常處理器(組件). 
1.編寫自定義異常類(做提示信息的)
public class SysException extends Exception{

    //存儲提示信息
    private String message;

    public SysException(String message) {
        this.message = message;
    }

    @Override
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

2.編寫異常處理器

public class SysExceptionResolver implements HandlerExceptionResolver {

    /**
     * 處理異常的業務邏輯
     * @param request
     * @param response
     * @param o
     * @param e
     * @return
     */
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) {
        //獲取異常對象
        SysException exception = null;
        if(e instanceof SysException) {
            exception = (SysException)e;
        } else {
            exception = new SysException("系統正在維護...");
        }

        //創建ModelAndView
        ModelAndView mv = new ModelAndView();
        mv.addObject("errorMsg",exception.getMessage());
        //表示往哪去跳轉
        mv.setViewName("error");
        return mv;
    }
}

3.配置異常處理器(跳轉到提示頁面)

<!--配置異常處理器-->
<bean id="sysExceptionResolver" class="com.tulun.exception.SysExceptionResolver"></bean>

SpringMVC攔截器

 攔截器是springMVC框架自己的,只有使用了SpringMVC框架後才能用
 過濾器是servlet規範中的一部分,任何web項目都可以使用
 攔截器只會攔截訪問的控制器(Controller)的方法,如果訪問的是jsp,html,css,image都不會攔截
 過濾器是url-pattern中配置了 /* 之後,對所有訪問資源進行攔截

1.編寫攔截器類 實現HandlerInterceptor接口

public class MyInterceptor implements HandlerInterceptor {
   /**
    * 預處理  在controller方法執行前執行
    * @param request
    * @param response
    * @param handler
    * @return  true:放行,執行下一個攔截器,如果沒有,執行controller方法
    * @throws Exception
    */
   @Override
   public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
       System.out.println("攔截器執行了....前");
       //頁面跳轉
//        request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request,response);
       return true;
   }

   /**
    * 後處理方法 在controller方法執行後 success.jsp執行之前
    * @param request
    * @param response
    * @param handler
    * @param modelAndView
    * @throws Exception
    */
   @Override
   public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
       System.out.println("攔截器執行了....後");
   }

   /**
    * 在success.jsp執行後執行
    * @param request
    * @param response
    * @param handler
    * @param ex
    * @throws Exception
    */
   @Override
   public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
       System.out.println("攔截器執行了....最後");
   }
}

2.配置攔截器

<!--配置攔截器-->
<mvc:interceptors>
    <!--配置攔截器-->
    <mvc:interceptor>
        <!--要攔截的具體的方法-->
        <mvc:mapping path="/user/*"/>
        <!--不要攔截的方法
        <mvc:exclude-mapping path=""/>-->
        <!--配置攔截器對象-->
        <bean id="myInterceptor" class="com.tulun.interceptor.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章