码迷,mamicode.com
首页 > 编程语言 > 详细

springMVC学习之一

时间:2015-06-05 17:43:52      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:springmvc

环境

MavenWeb工程,核心jar包:

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>4.0.0.RELEASE</version>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.0.0.RELEASE</version>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.0.0.RELEASE</version>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-expression</artifactId>
        <version>4.0.0.RELEASE</version>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>4.0.0.RELEASE</version>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.0.0.RELEASE</version>
        <type>jar</type>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>4.0.0.RELEASE</version>
        <type>jar</type>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version>
        <type>jar</type>
    </dependency>

其中javax.servlet提供servlet-api支持。如有tomcat,可以直接关联tomcat的相应jar包。

配置文件

总体感觉spring的配置文件还是比较精炼的(相比于webx。。),主要有两大块:web.xml和applicationContext.xml(可用dispatcherServlet-servlet.xml替换,后面再说。)

web.xml

所有的web工程都会用到。对于使用springMVC来说要实现请求的分发处理,需要配置以下基本组件:

  • dispatcherServlet
  • contextConfigLocation(非必须)
dispatcherServlet
<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 配置 DispatcherServlet 的一个初始化参数: 配置 SpringMVC 配置文件的位置和名称 -->
    <!-- 
        实际上也可以不通过 contextConfigLocation 来配置 SpringMVC 的配置文件, 而使用默认的.
        默认的配置文件为: /WEB-INF/<servlet-name>-servlet.xml
        (比如本例中可替换为dispatcherServlet-servlet.xml)
    -->
    <!--  
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    -->
    <!--  
        load-on-startup参数如果非零,则表示在容器初始化的时候就会对该servlet进行初始化,通常用于监听类等服务于spring框架的类。
    -->
    <load-on-startup>1</load-on-startup>
</servlet>

    <!--  
        servlet映射规则(对所有请求进行映射)
    --> 
<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

applicationContext.xml(亦或是dispatcherServlet-servlet.xml)

  • scan扫描注解组件,用于扫描对应base-package下的所有类的注解。

  • InternalResourceViewResolver(内部资源映射组件)

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
    

    配置了controller处理后返回的页面对应的资源地址匹配。

基于注解

4.0.0版的springframework中注解相当普遍和强大了。
在本次学习到的有以下几个:

@Controller
@RequestMapping
@PathVariable
@RequestParam
@RequestHeader
@CookieValue
@ModelAttribute
  • @Controller

在作为controller的类上标记该注解。dispatcherServlet可将对应url-pattern转发给这些Controller。如何确定给哪个Controller呢?
@RequestMapping

  • @RequestMapping

该注解用于控制url分发方向,可标注类或者方法,用法为:
@RequestMapping(“/xxx”)
标注方法的时候,需要加上所在类的RequestMapping路径(若没有则不用)。
则符合该url的会找到该方法执行。

  • PathVariable

springMVC支持REST风格的urlpath类型。
如:@requestMapping(xxx/{id}/yyy)
则方法的参数可以使用@PathVariable("id") Integer id进行获取。如下为例:

@RequestMapping(value="sayhello/{id}")//, method=RequestMethod.GET, params={"id=1","age!=1"}
public String hello(@PathVariable("id") Integer i){
    System.out.println("hello world "+i);
    return SUCCESS;
}
  • RequestParam,RequestHeader,CookieValue

这三个注解都是用于修饰方法的入参的。
@RequestParam(value="id", required=false) Integer id
表示入参接受id,但是id不一定有。在默认情况下,不写required属性意味着id必须有,如果没有,则报错。

@RequestHeader(value="Accept-Language") String actLang
道理相同,将请求头中的字段绑定到方法入参中。

@CookieValue() String xxx
同理,将请求中的CookieValue的字段绑定到方法入参中。

  • ModelAttribute

在说ModelAttribute注解之前,需要说一下表单的提交,因为ModelAttribute是针对表单-对象映射这种类型的提交项进行优化的步骤。

表单的提交支持级联,即组合关系。
直接看例子:

User.java

public class User {
    private String username;
    private String password;
    private int age;
    private Address address;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
    @Override
    public String toString() {
        return "User [username=" + username + ", password=" + password
                + ", age=" + age + ", address=" + address + "]";
    }


}

Address.java (作为User的一个级联属性)


public class Address {
    private String province;
    private String city;
    public String getProvince() {
        return province;
    }
    public void setProvince(String province) {
        this.province = province;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
}

表单对应到实体类已经就绪,下面看表单:


    <form action="HelloWorld/testPojo" method="post">
        username: <input type="text" name="username" /> <br> 
        password: <input type="password" name="password"/> <br> 
        age: <input type="text" name="age" /> 
        <br> 
        province: <input type="text" name="address.province" /> 
        <br>
        city: <input type="text" name="address.city" /> <br> 
        <input type="submit" value="Submit" />
    </form>

对于级联的属性name可以用address.province来表示。

对应的controller应该这么写:

    @RequestMapping("/testPojo")
    public String testPojo(User user){
        System.out.println(user);
        return SUCCESS;
    }

上述表单直接映射为了User类。

那么@ModelAttribute有什么用呢?它跟表单的提交有什么关系?

先看由其标注的方法:

    @ModelAttribute
    public void prehand(Map<String, Object> map){
        User user = new User();//模拟数据库提取(业务逻辑,可自行调整)
        user.setUsername("shanjie");
        user.setAge(23);
        user.setPassword("123");
        map.put("user", user);
    }

我们看下图:

技术分享

当User这个form映射成实体作为入参的时候,这个User实际上是一个新建的对象,这就有个问题:如果对已经填写过的表单进行个别项的修改,而其余各项的值不允许修改,那我在修改表单的时候该怎么办?单纯的新建对象会使得固定字段为空,因为不能填写该项,那么在更新到db中的时候会导致固定项为空。如果先得到固定相的值传给页面,作为hidden域似乎可行,但是不安全性和参数复杂性都会增加。那么怎么办?

@ModelAttribute提供了完美的解决办法,如下图:

技术分享

标注了@ModelAttribute的方法会先于form的映射方法执行。
即一个表单从前端映射到后台存入数据库的流程是这样的:

  1. 执行@ModelAttribute修饰的方法,将目标对象从数据库中取出来,放到Map中(本例中为User对象,key为“user”)
  2. SpringMVC从Map中得到User对象,并把表单赋给“user”对象。
  3. SpringMVC把上述经过覆盖的“user”对象传入目标方法的参数。

因此,在没有@ModelAttribute修饰的方法时,我们使用的目标函数其实就是第三步中的过程。有了ModelAttribute修饰的方法,则第一步也就有了意义。

注:@ModelAttribute方法是如何识别目标对象的呢?
我们知道第一步和第三步都是我们人为定制的,而第二步是由spring为我们做的,它根据什么去从map中取得第三步需要传入的对象呢?
答案就是,它默认将对象类的首字母小写作为key值。本例中,User类对应着user这个key。如果key变了,那么spring也就找不到对应的User 了。
这是springMVC中的重要约定之一。

springMVC学习之一

标签:springmvc

原文地址:http://blog.csdn.net/langduhualangdu/article/details/46377439

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!