2017年12月22日 星期五

自定義 View、加載靜態資源 (Spring3.x MVC 四)

※自定義 View


※DefinedSelfView.java

@Component
public class DefinedSelfView implements View{
    @Override
    public String getContentType() {
        return "text/html";
    }
    
    @Override
    public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        response.setContentType("text/html; charset=UTF-8");
        response.getWriter().println("耶!自定義的 View 耶");
    }
}

※繼承 View 後,實作兩個方法


※設定檔

<context:component-scan base-package="controller,view"></context:component-scan>
    
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/" />
    <property name="suffix" value=".jsp" />
</bean>
    
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" p:order="50" />

※尤於有多個 ViewResolver,所以要加上 order,這個數字是較小的優先,InternalResourceViewResolver 的父類 UrlBasedViewResolver 已經有定義 order = Integer.MAX_VALUE;,所以基本上,隨便打個數字都比它優先


※測試

@Controller
@RequestMapping("/ooo/xxx/")
public class XxxAction {
    @RequestMapping("definedSelfView")
    public String getView() {
        return "definedSelfView"; // bean id
    }
}
------------------------------
<a href="ooo/xxx/definedSelfView.mvc">definedSelfView</a>





※加載靜態資源 

官網
在首頁加載 jquery,如果 web.xml 是全部給 spring 處理時,在伺服器起動時,會發現「No mapping found for HTTP request with URI [/SpringMVC/jquery-3.2.1.js] in DispatcherServlet with name 'testServlet'」,當然可用副檔名的方式來避免這個問題,但如果不想用這招,還可以用以下的方式

※web.xml

<servlet-mapping>
    <servlet-name>testServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

※全部的資源都給 spring 處理,不管是給container處理、還是給 spring 管理,都必需這麼做才能體現他的功能


※給 container 處理

※XML 設定

<mvc:default-servlet-handler default-servlet-name="default" />
<mvc:annotation-driven />

※使用 default-servlet-handler 可將靜態資源交給 container 處理,預設名稱是 default,如此例的 default-servlet-name 可不用寫,大部分的 container 都會取名為 default,如果不是就加這個屬性

※本來不加 default-servlet-handler 是可以處理 @RequestMapping 的,但加了 default-servlet-handler,annotation-driven 不加的話,那就無法處理  @RequestMapping,所以一加就兩個都要加才行,看官網


※annotation 設定

@Component
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}

※如果預設名稱不是 default,可以寫在 enable() 裡面


※tomcat 裡的 web.xml

<servlet>
    <servlet-name>default</servlet-name>
    <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
    <init-param>
        <param-name>debug</param-name>
        <param-value>0</param-value>
    </init-param>
    <init-param>
        <param-name>listings</param-name>
        <param-value>false</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

※這只是從 tomcat 裡的 web.xml 貼出來參考,並不用改



※給 spring 管理


※紅框由上而下,分別是 靜態資源、spring設定檔、測試頁

※XML 設定

<mvc:resources mapping="/xxx/**" location="/WEB-INF/static/" />

※location 裡寫的是真實路徑,可用 classpath

※mapping 如有多個,可用逗號隔開

※這個意思表示 /WEB-INF/static 底下的目錄可用 xxx 取代


※測試

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    
<script src='<c:url value="/xxx/js/jquery-3.2.1.js" />'></script>
    
<!-- <script src="xxx/js/jquery-3.2.1.js"></script> -->
    
$( _ => {
    alert("xxx");
});

※註解那一行也行,就看你要不要用 JSTL 了,前面有「/」的差別


※annotation 設定

@Component
@EnableWebMvc
public class Xxx extends WebMvcConfigurerAdapter {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/xxx/**").addResourceLocations("/WEB-INF/static/");
    }
}

※addResourceLocations 是 ... 參數,所以可以寫多個

※和 container 的 annotation 設定很像,差在覆寫不同的方法

沒有留言:

張貼留言