Spring MVC 配置檔案dispatcher-servlet.xml 檔案詳解
阿新 • • 發佈:2018-11-08
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd"> <!-- 使用spring提供的PropertyPlaceholderConfigurer讀取資料庫配置資訊.properties 1、這裡的classpath可以認為是專案中的src- 2、屬性名是 locations,使用子標籤<list></list>可以指定多個數據庫的配置檔案,這裡指定了一個 其中order屬性代表其載入順序,而ignoreUnresolvablePlaceholders為是否忽略不可解析的 Placeholder, 如配置了多個PropertyPlaceholderConfigurer,則需設定為true <bean id="propertyConfigurerForProject2" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="order" value="2" /> <property name="ignoreUnresolvablePlaceholders" value="true" /> <property name="locations"> <list> <value>classpath:/spring/include/jdbc-parms.properties</value> <value>classpath:/spring/include/base-config.properties</value> </list> </property> </bean>--> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="ignoreUnresolvablePlaceholders" value="true"/> <property name="location" value="classpath:/application.properties"/> </bean> <!--註解探測器,在xml配置了這個標籤後,spring可以自動去掃描base-pack下面或者子包下面的java檔案, 如果掃描到有@Component @[email protected]等這些註解的類,則把這些類註冊為bean 注意:如果配置了<context:component-scan>那麼<context:annotation-config/>標籤就可以不用再xml中配置了,因為前者包含了後者。 另外<context:annotation-config/>還提供了兩個子標籤 1. <context:include-filter> 2.<context:exclude-filter> <context:component-scan>有一個use-default-filters屬性,改屬性預設為true,這就意味著會掃描指定包下的全部的標有@Component的類, 並註冊成bean.也就是@Component的子註解@Service,@Reposity等。所以如果僅僅是在配置檔案中這麼寫 <context:component-scan base-package="com.test.myapp.web"/> Use-default-filter此時為true,那麼會對base-package包或者子包下的jun所有的進行java類進行掃描,並把匹配的java類註冊成bean。 可以發現這種掃描的粒度有點太大,如果你只想掃描指定包下面的Controller,該怎麼辦?此時子標籤<context:incluce-filter>就起到了勇武之地。如下所示 <context:component-scan base-package="com.test.myapp.web.Controller"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> 這樣就會只掃描base-package指定下的有@Controller下的java類,並註冊成bean. 但是因為use-dafault-filter在上面並沒有指定,預設就為true,所以當把上面的配置改成如下所示的時候,就會產生與你期望相悖的結果(注意base-package包值得變化) <context:component-scan base-package="com.test.myapp.web "> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> 此時,spring不僅掃描了@Controller,還掃描了指定包所在的子包service包下註解@Service的java類 此時指定的include-filter沒有起到作用,只要把use-default-filter設定成false就可以了。這樣就可以避免在base-packeage配置多個包名這種不是很優雅的方法來解決這個問題了。 另外在我參與的專案中可以發現在base-package指定的包中有的子包是不含有註解了,所以不用掃描,此時可以指定<context:exclude-filter>來進行過濾,說明此包不需要被掃描。綜合以上說明 Use-dafault-filters=”false”的情況下:<context:exclude-filter>指定的不掃描,<context:include-filter>指定的掃描--> <context:component-scan base-package="com.test.myapp"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!-- 檢視解析器,根據檢視的名稱new ModelAndView(name),在配置檔案查詢對應的bean配置 這個檢視解析器跟XmlViewResolver有點類似,也是通過把返回的邏輯檢視名稱去匹配定義好的檢視bean物件。 不同點有二,一是BeanNameViewResolver要求檢視bean物件都定義在Spring的application context中, 而XmlViewResolver是在指定的配置檔案中尋找檢視bean物件,二是BeanNameViewResolver不會進行檢視快取。 如果沒有設定viewResolver,spring使用InternalResourceViewResolver進行解析。 Spring實現ViewResolver的非抽象類且我們經常使用的viewResolver有以下四種: 1、InternalResourceViewResolver 將邏輯檢視名字解析為一個路徑 2、BeanNameViewResolver 將邏輯檢視名字解析為bean的Name屬性,從而根據name屬性,找定義View的bean 3、ResourceBundleResolver 和BeanNameViewResolver一樣,只不過定義的view-bean都在一個properties檔案中,用這個類進行載入這個properties檔案 4、XmlViewResolver 和ResourceBundleResolver一樣,只不過定義的view-bean在一個xml檔案中,用這個類來載入xml檔案 DispatcherServlet會載入所有的viewResolver到一個list中,並按照優先順序進行解析。 我們不想只使用一種檢視解析器的話,可以在[spring-dispatcher-name]-servlet.xml定義多個viewResolver: 注意order中的值越小,優先順序越高。而id為viewResolver 的viewResolver的優先順序是最低的。 --> <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"> <property name="order" value="1"/> </bean> <!--<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">--> <!--<property name="prefix" value="/WEB-INF/"/>--> <!--<property name="suffix" value=".html"/>--> <!--</bean>--> <!--基於json格式的mvc互動--> <bean name="jsonView" class="com.test.myapp.MappingFastJsonJsonView"> <property name="contentType" value="application/json;charset=UTF-8"/> </bean> <!-- spring mvc +servlet3.0上傳檔案配置,檔案上傳外掛uploadify的應用 1) 在Web.xml的配置 需要在web.xml新增multipart-config,如下所示 <servlet> <servlet-name>AcrWeb</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> <multipart-config> <max-file-size>52428800</max-file-size> <max-request-size>52428800</max-request-size> <file-size-threshold>0</file-size-threshold> </multipart-config> </servlet> 2) 在spring的application.xml(名字不一定是application)的配置,需要在該配置檔案下新增一個如下的bean spring mvc +servlet3.0上傳檔案配置 <bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"> </bean> 3) 在jsp頁面中需要引入一些相關的該外掛的包 <script src="<c:url value="/asset/admin/js/uploadify/jquery.uploadify.min.js"/>"></script> 4) 定義一個選擇檔案的input框 <div class="box-body"> <span class="label input g1">上傳apk</span> <input id="apk_upload" name="apk_upload" type="file"/> <input id="apkUrl" type="hidden" name="apkUrl"/> </div> 5) Input file與外掛進行繫結 $("#apk_upload").uploadify({ swf: "<c:url value='/asset/admin/js/uploadify/uploadify.swf'/>", //cancelImg : "<c:url value='/asset/admin/js/uploadify/uploadify-cancel.png'/>", uploader: "/acr/admin/app/apkupload", fileObjName: "file",//對應著檔案輸入框 width:300, buttonText: '<img src="/acr/asset/admin/js/uploadify/upload.png" />', // onInit: function () { $(".uploadify-queue").hide(); }, //removeCompleted : false, onUploadSuccess : function(file, data, response) { $("#apkUrl").val(data); }, onUploadError : function(file, errorCode, errorMsg, errorString) { alert('檔案 ' + file.name + ' 上傳失敗: ' + errorString); } }); 注意:該外掛的uploadify.swf檔案時放入到專案的某一個檔案下面 Uploader的值對應的是url,該值對映到了springmvc的一個方法,該方法是檔案上傳的核心, 負責把檔案寫到指定位置的地方去。 6) Spring 後臺程式碼的實現 @RequestMapping(value = "/apkupload", method=RequestMethod.POST) public @ResponseBody String apkUpload( @RequestParam MultipartFile file, Model model, HttpServletRequest request) throws IOException { InputStream input = null; OutputStream output = null; String root = "H:/file"; //生成了檔名字 String filename = file.getOriginalFilename(); //檔案要上傳的位置 String fileFullName = buildUpPath(root, filename); try { File dir = new File(root); if(!dir.exists()){ dir.mkdirs(); } input = file.getInputStream(); output = new FileOutputStream(new File(fileFullName)); //儲存檔案 IOUtils.copy(input, output); } catch (Throwable e) { throw e; }finally{ IOUtils.closeQuietly(input); IOUtils.closeQuietly(output); } return root+"/"+filename; } 其中filename對應著步驟5的onUploadSuccess中的data --> <bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"> </bean> </beans>