spring构建web应用以及ModelAndView中的 model value 在JSP中的EL表达式显示null解决办法

来源:互联网 发布:小米5抢购软件下载 编辑:程序博客网 时间:2024/06/12 22:35

创建一个Hello world的例子,使用Java配置。 通过对应的Java替换XML配置。

以 Spring Java为基础的配置取决于Servlet 3.0 的API, 因此,我们需要包含的依赖在 pom.xml 中。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  <modelVersion>4.0.0</modelVersion>  <groupId>com.dhb.demo</groupId>  <artifactId>spring4MVCHelloWorldNoXMLDemo</artifactId>  <packaging>war</packaging>  <version>0.1.0-SNAPSHOT</version>  <name>spring4MVCHelloWorldNoXMLDemo Maven Webapp</name>  <url>http://maven.apache.org</url>  <properties>    <jetty.context>/</jetty.context>    <jetty.http.port>9089</jetty.http.port>    <jetty.https.port>9444</jetty.https.port>    <jetty.stopPort>10081</jetty.stopPort>    <spring.version>4.1.4.RELEASE</spring.version>  </properties>  <dependencies>    <!-- spring -->    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-web</artifactId>      <version>${spring.version}</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-webmvc</artifactId>      <version>${spring.version}</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-expression</artifactId>      <version>${spring.version}</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-context-support</artifactId>      <version>${spring.version}</version>    </dependency>    <dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>      <version>3.8.1</version>      <scope>test</scope>    </dependency>    <dependency>      <groupId>javax.servlet</groupId>      <artifactId>javax.servlet-api</artifactId>      <version>3.1.0</version>    </dependency>    <dependency>      <groupId>javax.servlet.jsp</groupId>      <artifactId>javax.servlet.jsp-api</artifactId>      <version>2.3.1</version>    </dependency>    <dependency>      <groupId>javax.servlet</groupId>      <artifactId>jstl</artifactId>      <version>1.2</version>    </dependency>  </dependencies>  <build>    <plugins>      <plugin>        <groupId>org.apache.maven.plugins</groupId>        <artifactId>maven-compiler-plugin</artifactId>        <version>3.1</version>        <configuration>          <source>1.7</source>          <target>1.7</target>          <showWarnings>true</showWarnings>        </configuration>      </plugin>      <!--maven jetty 插件配置-->      <plugin>        <groupId>org.eclipse.jetty</groupId>        <artifactId>jetty-maven-plugin</artifactId>        <version>9.2.17.v20160517</version>        <configuration>          <webApp>            <contextPath>${jetty.context}</contextPath>          </webApp>          <httpConnector>            <port>${jetty.http.port}</port>          </httpConnector>          <stopKey>jetty</stopKey>          <stopPort>${jetty.stopPort}</stopPort>          <!--<scanIntervalSeconds>2</scanIntervalSeconds>-->        </configuration>      </plugin>    </plugins>    <finalName>Spring4MVCHelloWorldNoXMLDemo</finalName>  </build></project>



添加控制器
在src/main/java下添加一个控制器类,如下所示:
package com.dhb.springmvc.controller.HelloWorldController

package com.dhb.springmvc.controller;import org.springframework.stereotype.Controller;import org.springframework.ui.ModelMap;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * Created by ${denghb} on 2016/7/31. */@Controller@RequestMapping("/springmvc")public class HelloWorldController {    @RequestMapping(method = RequestMethod.GET)    public String sayHello(ModelMap model) {        model.addAttribute("greeting", "Hello World from Spring 4 MVC");        return "welcome";    }    @RequestMapping(value = "/helloagain", method = RequestMethod.GET)    public String sayHelloAgain(ModelMap model) {        model.addAttribute("greeting", "Hello World Again, from Spring 4 MVC");        model.put("star","haha");        return "welcome";    }    @RequestMapping(value = "/helloThird", method = RequestMethod.GET)    public ModelAndView show(HttpServletRequest request,                              HttpServletResponse response) throws Exception {        ModelAndView mav = new ModelAndView("welcome");        mav.addObject("account", "100w");        return mav;    }}

类名@Controller注解声明这个类的Spring bean 以及 @RequestMapping注解声明了这个类是默认处理程序键入“/”的所有请求。第一种方法没有声明因此任何映射,它将继承映射的映射声明是在类级别上,默认处理GET请求。方法二(由于额外的映射声明使用value属性)形式 /hello 将再次请求。属性方法说哪种类型的HTTP请求这种方法可以服务。

方法说哪种类型的HTTP请求这种方法可以服务。 ModelMap是一个Map实现,在这里作为替代[request.getAttribute()/request.setAttribute()] 设定值作为请求属性。请注意,我们从这个方法返回“welcome”字符串。此字符串将后缀和前缀后缀,在视图解析器定义的前缀(见上面的 spring-servlet.xml),形成真正的视图文件名。

添加视图
创建一个新的文件夹命名为views在WEB-INF目录下,并添加一个简单的JSP页面welcome.jsp (WEB-INF/views/welcome.jsp)从控制器到简单的访问模式值。

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"        "http://www.w3.org/TR/html4/loose.dtd"><html><head>    <title>HelloWorld page</title></head><body>Greeting : ${greeting}<br>Greeting : ${requestScope.greeting}<p><%=request.getAttribute("greeting") %></p><%=request.getAttribute("star") %></body></html>

添加配置类
在src/main/java下添加下面提到的类指定的包,如下图所示。这种构造类可以被看作是一个替代 spring-servlet.xml,因为它包含了所有必需的组件的扫描和视图解析器的信息。

package com.dhb.springmvc.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.ViewResolver;import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;import org.springframework.web.servlet.config.annotation.EnableWebMvc;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;import org.springframework.web.servlet.view.InternalResourceViewResolver;import org.springframework.web.servlet.view.JstlView;/** * Created by ${denghb} on 2016/7/31. */@Configuration@EnableWebMvc@ComponentScan(basePackages = "com.dhb.springmvc")public class WebConfig extends WebMvcConfigurerAdapter {    @Bean    public ViewResolver viewResolver() { //配置JSP视图解析器        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();        viewResolver.setViewClass(JstlView.class);        viewResolver.setPrefix("/WEB-INF/views/");        viewResolver.setSuffix(".jsp");        // 可以在JSP页面中通过${}访问beans        viewResolver.setExposeContextBeansAsAttributes(true);        return  viewResolver;    }    @Override    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {        //super.configureDefaultServletHandling(configurer);        configurer.enable(); //配置静态文件处理    }}

@Configuration指明该类包含注解为@Bean 生产 bean管理是由Spring容器的一个或多个bean方法。 
@EnableWebMvc 等同于 mvc:annotation-driven 在XML中. 它能够为使用@RequestMapping向特定的方法传入的请求映射@Controller-annotated 类。
@ComponentScan 等同于 context:component-scan base-package="..." 提供 spring 在哪里寻找 管理 beans/classes.



RootConfig的配置就非常简单了,唯一需要注意的是,它在设置扫描机制的时候,将之前WebConfig设置过的那个包排除了;也就是说,这两个扫描机制作用的范围正交。RootConfig的代码如下:

package com.dhb.springmvc.config;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.FilterType;import org.springframework.web.servlet.config.annotation.EnableWebMvc;/** * Created by ${denghb} on 2016/8/1. */@Configuration@ComponentScan(basePackages = {"org.test.spittr"},        excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class)})public class RootConfig {}

当DispatcherServlet启动时,会创建一个Spring MVC应用容器并开始加载配置文件中定义好的beans。通过getServletConfigClasses()方法,可以获取由DispatcherServlet加载的定义在WebConfig.class中的beans。

在Spring Web应用中,还有另一个Spring应用容器,这个容器由ContextLoaderListener创建。

我们希望DispatcherServlet仅加载web组件之类的beans,例如controllers(控制器)、view resolvers(视图解析器)和处理器映射(handler mappings);而希望ContextLoaderListener加载应用中的其他类型的beans——例如业务逻辑组件、数据库操作组件等等。

实际上,AbstractAnnotationConfigDispatcherServletInitializer创建了DispatcherServlet和ContextLoaderListener:getServletConfigClasses()返回的配置类定义了Spring MVC应用容器中的beans;getRootConfigClasses()返回的配置类定义了Spring应用根容器中的beans。【书中没有说的】:Spring MVC容器是根容器的子容器,子容器可以看到根容器中定义的beans,反之不行。


添加初始化类

package com.dhb.springmvc.config;import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;/** * Created by ${denghb} on 2016/7/31. */public class DhbWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {    @Override    protected Class<?>[] getRootConfigClasses() {        return new Class<?>[] { RootConfig.class };    }    @Override    protected Class<?>[] getServletConfigClasses() {        // return new Class<?>[0];        return new Class [] { WebConfig.class };    }    @Override    protected String[] getServletMappings() {        return new String[] { "/" };    }}


类似 web.xml 在之前的教程中的内容,因为我们使用的是前端控制器 DispatcherServlet,分配映射(URL模式的XML)和而不是提供给 Spring 配置文件(spring-servlet.xml)的路径,在这里,我们正在注册的配置类。总体而言,我们都在做同样的事情,只是方式有所不同。

显示结果:



解决办法有两种:

一、我们使用的是 JSP 1.2 descriptor, defined by DTD ,例如:

web.xml

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app>//...</web-app>

EL表达式是不起作用的,被默认忽略了。所以我们要加一句代码:

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"        "http://www.w3.org/TR/html4/loose.dtd"><html><head>    <title>HelloWorld page</title>    <%@ page isELIgnored="false" %></head><body>Greeting : ${greeting}<br>Greeting : ${requestScope.greeting}<p><%=request.getAttribute("greeting") %></p><%=request.getAttribute("star") %></body></html>


二、我们使用这个标准standard JSP 2.0 descriptor, defined by w3c schema 例如:

web.xml

<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">//...</web-app>

这里EL表达式会被默认起作用的。

结果显示:



0 0
原创粉丝点击