Spring-MVC

2019-06-14

Spring 框架提供了構(gòu)建 Web 應(yīng)用程序的全功能 MVC 模塊,可以取代Servlet,構(gòu)建輕量級框架。

SpringMVC基本配置

編寫Spring控制器

@Controller
public class LoginController{
    //給處理方法添加RequestMapping注解
    //對應(yīng)前端請求地址http://localhost:8080/TestApp/login.do
    @RequestMapping("/login.do")
    public String login(Users users) {
        if ("admin".equals(users.getUsername()) 
            && "123456".equals(users.getPassword())) {
            return "index";
        } else {
            return "login";
        }
    }
}

可以使用@RequestMapping添加類級別注解

@Controller
@RequestMapping ("/UsersController")
public class UsersController {
    @RequestMapping ("/login.do")
    public String login() {
        return "login";
    }
    @RequestMapping ("/register.do")
    public String register () {
        return "register";
    }
}
//對應(yīng)地址http://localhost:8080/TestApp/UsersController/login.do

SpringMVC默認的響應(yīng)類型為服務(wù)器轉(zhuǎn)發(fā),如果不想通過視圖解析器進行響應(yīng),可以使用如下語句:
  return "redirect:/xxx.jsp" //重定向
  return "forward:/xxx.jsp"  //服務(wù)器轉(zhuǎn)發(fā)

編寫SpringMVC核心配置文件 spring-mvc.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:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context-4.3.xsd
                           http://www.springframework.org/schema/aop 
                           http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
                           http://www.springframework.org/schema/tx 
                           http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
                           http://www.springframework.org/schema/mvc
                           http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">

    <!--啟用spring mvc注解 -->
    <mvc:annotation-driven />

    <!--設(shè)置使用注解的類所在的包路徑 -->
    <context:component-scan base-package="com.jevon.controller" />

    <!--視圖解析器 -->
    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--prefix和suffix:配置視圖頁面的前綴和后綴(前綴[邏輯視圖名]后綴 -->
        <property name="prefix" value="/" />
        <property name="suffix" value=".jsp" />
        <!--JstlView視圖類 -->
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
        <property name="contentType">
            <value>text/html;charset=utf-8</value>
        </property>
    </bean>

    <!-- 靜態(tài)資源不經(jīng)過controller -->
    <mvc:resources mapping="/images/**" location="/images/" />
    <mvc:resources mapping="/css/**" location="/css/" />
    <mvc:resources mapping="/js/**" location="/js/" />

</beans>

配置web.xml,啟動Spring

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee  
         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">
    <!--指定配置文件路徑 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <!--通過ContextLoaderListener啟用spring容器 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!--請求監(jiān)聽器 -->
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>
    <!--核心控制器 -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
    <!--請求編碼過濾器 -->
    <filter>
        <filter-name>encodingFilter</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>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!--啟動頁 -->
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>login.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
</web-app>

請求處理方法的參數(shù)

如果需要在請求處理方法中使用Servlet API類型,可以將這些類型作為請求參數(shù)來接收處理。

可以編寫控制器父類攔截Servlet API進行封裝。

public class GenericController {
    protected HttpServletRequest request;
    protected HttpServletResponse response;
    protected HttpSession session;
    protected ServletContext application;

    //被@ModelAttribute注釋的方法會在此controller每個方法執(zhí)行前被執(zhí)行, 可以用來攔截請求、控制登錄權(quán)限等
    @ModelAttribute
    public void setServletApi(HttpServletRequest request,HttpServletResponse response) {
        this.request = request;
        this.response = response;
        this.session = request.getSession();
        this.application = request.getServletContext();
    }
}

參數(shù)類型自動轉(zhuǎn)換

在SpringMVC框架中,對于常用的數(shù)據(jù)類型,開發(fā)者無須手動進行類型轉(zhuǎn)換,SpringMVC框架有許多內(nèi)置的類型轉(zhuǎn)換器用于完成常用的類型轉(zhuǎn)換。

ModelAndView返回值

? SpringMVC提供了org.springframework.web.servlet.ModelAndView類封裝邏輯視圖及返回值。該類可以添加Map結(jié)構(gòu)數(shù)據(jù)。

new ModelAndView(邏輯視圖);

new ModelAndView(邏輯視圖,鍵,值);

ModelAndView mv = new ModelAndView();
mv.setViewName(邏輯視圖);
mv.addObject(鍵,值);

SpringMVC的工作流程

1560472921825.png
  • 客戶端請求被DispatcherServlet(前端控制器)接收,然后根據(jù)url映射到業(yè)務(wù)控制器,然后調(diào)用業(yè)務(wù)控制器的方法做業(yè)務(wù)邏輯處理。
  • 業(yè)務(wù)控制器返回ModelAndView對象(邏輯視圖)給DispatcherServlet。
  • DispatcherServlet將獲取的邏輯視圖傳給ViewResolver視圖解析器,將邏輯視圖解析成物理視圖。
  • ViewResolver將物理視圖返回給DispatcherServlet。
  • DispatcherServlet將渲染后的物理視圖響應(yīng)給客戶端。

Ajax響應(yīng)

與Servlet用法基本相同,通過上面的controller父類獲取到response對象,拿到輸出流寫入即可

Spring4的控制器可以使用response對象做出ajax響應(yīng),并利用@ResponseBody注解自動將數(shù)據(jù)生成json響應(yīng)給瀏覽器。

@RequestMapping("/UsersController_findById.do")
public @ResponseBody Users findById(String id) {
    return this.usersService.findById(id);
}

@RequestMapping("/UsersController_findAll.do")
public @ResponseBody List<Users> findAll() {
    List<Users> lists = this.usersService.findAll();
    return lists;
}

@RequestMapping("/UsersController_findAllByMap.do")
public @ResponseBody List<Map<String, String>> findAllByMap () {
    List<Map<String, String>> lists = this.usersService.findAll();
    return results;
}

文件上傳

SpringMVC框架的文件上傳基于commons-fileupload組件實現(xiàn),只不過SpringMVC框架在原有文件上傳組件上做了進一步封裝,簡化了文件上傳的代碼實現(xiàn)。

上傳表單

<form action="FileController_upload.do" method="post" enctype="multipart/form-data">
    <p>
        請選擇照片:<input type="file" name="photo" />
    </p>
    <input type="submit" value="上傳" />
</form>

控制器

//處理文件上傳 如果上傳多個文件,
//可以設(shè)定MultipartFile數(shù)組或List集合參數(shù) List<MultipartFile> photo
@RequestMapping("/FileController_upload.do")
public String upload(MultipartFile photo) throws Exception {
    if (photo.isEmpty()) {
       System.out.println("文件未上傳");
       return "error";
    } else {
       System.out.println("文件名: " + file.getOriginalFilename());
       System.out.println("文件類型: " + file.getContentType());
       System.out.println("文件大小: " + file.getSize());
       System.out.println("========================================");
       String fileName = photo.getOriginalFilename();
       String ext = fileName.substring(fileName.lastIndexOf("."),  
          fileName.length());// 獲得上傳文件的擴展名
       String newFileName = new SimpleDateFormat("yyyyMMddhhmmssSSS")
          .format(new Date())+ (10000 + new Random().nextInt(90000)) + ext;
       File destFile = new File(this.application
          .getRealPath("upload"), newFileName); // 創(chuàng)建目標(biāo)文件
       photo.transferTo(destFile);// 復(fù)制文件
       return "success";
    }
}

spring-mvc.xml文件上傳配置

<!--文件上傳處理器 -->  
<bean id="multipartResolver"  
      class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
    <property name="defaultEncoding" value="UTF-8"/>  
    <!-- 指定所上傳文件的總大小不能超過512K。
         注意maxUploadSize屬性的限制不是針對單個文件,而是所有文件的容量之和 
    -->  
    <property name="maxUploadSize" value="512000"/>  
</bean>  
      
<!--文件上傳異常處理器 -->  
<bean id="exceptionResolver" 
      class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
    <property name="exceptionMappings">  
        <props>  
            <!-- 拋出異常時,自動跳轉(zhuǎn)到指定頁面 -->  
            <prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">
               error
            </prop>  
        </props>  
    </property>  
</bean> 

MultipartFile API說明

返回值 方法名 說明
byte[] getBytes() 以字節(jié)數(shù)組類型返回文件內(nèi)容
String getContentType() 獲取文件類型
InputStream getInputStream() 獲取穩(wěn)健的輸入流
String getName() 返回參數(shù)名稱多部分的形式
String getOriginalFilename 返回文件名
long getSize() 返回文件大?。ㄗ止?jié))
boolean isEmpty() 判斷是否為空
void transferTo() 復(fù)制文件到指定文件

文件下載

@RequestMapping("/FileController_download.do")
public void downLoad(String id) throws Exception {
    String path = this.application.getRealPath("upload") + "\\2017090102581803133040.jpg";
    File file = new File(path);
    this.response.setContentType("application/x-msdownload;charset=utf-8");
    this.response.setHeader("Content-disposition","attachment; filename=" 
        + new String(file.getName().getBytes("UTF-8"), "iso-8859-1"));
    this.response.setHeader("Content-Length", String.valueOf(file.length()));
    InputStream input = new FileInputStream(file);
    byte data[] = new byte[(int) file.length()];
    input.read(data);
    input.close();
    OutputStream out = this.response.getOutputStream();
    out.write(data);
    out.close();
}

springmvc異常統(tǒng)一處理

在J2EE項目的開發(fā)中,不管是對底層的數(shù)據(jù)庫操作過程,還是業(yè)務(wù)層的處理過程,還是控制層的處理過程,都不可避免會遇到各種異常需要處理。如果每個過程都單獨手動用try-catch處理,則系統(tǒng)的代碼耦合度高,工作量大且不好統(tǒng)一,維護的工作量也很大。 Spring MVC提供了統(tǒng)一處理異常的解決方案。

Spring MVC處理異常有3種方式:

  • 使用Spring MVC提供的異常處理器SimpleMappingExceptionResolver;
  • 實現(xiàn)Spring的異常處理接口HandlerExceptionResolver 自定義異常處理器;
  • 使用@ExceptionHandler注解實現(xiàn)異常處理;

修改spring-mvc.mxl

<!-- 異常處理器 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <!-- 定義默認的異常處理頁面 -->
    <property name="defaultErrorView" value="error"></property>
    <!-- 定義異常處理頁面用來獲取異常信息的變量名,默認名為exception -->
    <property name="exceptionAttribute" value="ex"></property>
    <!-- 定義需要特殊處理的異常,用類名或完全路徑名作為key,異常處理頁名作為值 -->
    <property name="exceptionMappings">
        <props>
            <prop key="com.exception.MyException">error_myexception</prop>
            <!-- 這里還可以繼續(xù)擴展對不同異常類型的處理 -->
        </props>
    </property>
</bean>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容