SpringMVC(二):基于注解的SpringMVC入门

一、使用注解时须要注意xml的配置

    <mvc:annotation-driven />java

  • 对包进行扫描,实现注释驱动Bean定义,同时将bean自动注入容器中使用。即解决了@Controller标识的类的bean的注入和使用。web

  • 会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 两个bean。spring

  • 若是没有<mvc:annotation-driven/>,那么全部的Controller可能就没有解析,没有相应的Controller就会被default servlet处理。mvc


    <context:component-scan base-package="用于扫描的包" />app

  • 启用自动检测webapp


二、@Controller

    标识一个控制器,@Controller注解定义在org.springframework.steretype包中。使用方式: @Controller 或者 @Controller("")。 jsp

    org.springframework.steretype包中还包含@Component @Service @Respository三个注解。@Component是通用标注,@Controller标注web控制器,@Service标注Servicec层的服务,@Respository标注DAO层的数据访问。函数


三、@RequestMapping

  • 在类级别上则表示相对路径网站

  • 在方法级别上则表示访问路径ui

请求:(网站域名+web应用名)web应用根目录+类定义处@RequestMapping+方法定义处@RequestMapping

映射到

物理视图:webapp根目录+springmvc.xml配置的prefix+ 控制器方法的返回值 +springmvc.xml配置的sufix


这里的话是

请求:http://localhost:8080/MySpringMVC/roger/test

映射到

物理视图webapp/test.jsp就经过控制器上的

注:当方法返回值类型为void时,controller方法仍是返回一个String类型的值做为视图名(默认为请求名)

例如:http://localhost:8080/MySpringMVC/roger/test  访问showTest()

@Controller
@RequestMapping("/roger")
public class TestController {
    @RequestMapping("/")
    public String showIndex() {
        return "index";
    }

    @RequestMapping(value="/test")
    public String showTest() {
        return "test";
    }
    
    @RequestMapping(value="/get")
    public void showTest() {
        //do something..
    }(默认返回一个String类型的值做为视图名(默认为请求名))


3.一、value属性

    @RequestMapping的value值先后是否有“/”对请求的路径没有影响,即value="test" 、"/test"、"/test/"其效果是同样的。

3.1.一、value通配符

在一些场景中,请求的url多是符合必定模式的多个值,这时候须要使用Ant 风格通配符来进行限定。

Ant 风格资源地址支持 3 种匹配符:

  •  ?:匹配文件名中的一个字符

  • *:匹配文件名中的任意字符

  • **: ** 匹配多层路径

@RequestMapping 支持 Ant 风格的 URL:

– /user/*/createUser: 匹配

/user/aaa/createUser、 /user/bbb/createUser 等 URL

– /user/**/createUser: 匹配

/user/createUser、 /user/aaa/bbb/createUser 等 URL

– /user/createUser??: 匹配

/user/createUseraa、 /user/createUserbb 等 URL

3.1.二、映射优先级
  • 选择范围更小,更加具体的进行映射

  • ?>*>**

  • 仅仅是位置关系有差异,映射是随机的

3.二、params属性

    @RequestMapping(params="action=del"),请求参数包含“action=del",如http://localhost:8080/MySpringMVC/roger/test?action=del

复杂点,例如:

所传参数中必须包含username, age=20, 以及不能包含名为pwd的参数

 @RequestMapping(value="testParam2",params={"username","age=20","!pwd"})
    public String testParam2() {
        return "test";
    }


四、@RequestParam

    使用@RequestParam("xx")注解获取GET请求或POST请求提交的参数,替代request.getParameter("xx")

例如:

    访问连接:http://localhost:8080/MySpringMVC/roger/testParam?username=roger

@RequestMapping(value = "/testParam", method = RequestMethod.GET)
  public String testParam(HttpServletRequest request, @RequestParam("username") String username) {
    System.out.println("HttpServletRequest, username:" + request.getParameter("username"));
    System.out.println("@RequestParam(), username:" + username);
    return "test";
}


@RequestParam() 来映射请求参数

  • value值 即请求参数名

  • required 该参数是否必需。默认为true

  • defaultValue请求参数的默认值

  • 处理函数的参数类型必须是对象类型,不然基本数据类型如int等没法设为空。


4.一、required属性

    required属性标注这个参数是不是必需的,默认是true,若是想让它能够不存在,那么就设置为false。可是请注意,required设置成false的参数对应的处理函数的参数类型必须是对象类型,不然回报错500!

package com.happyBKs.springmvc.handlers;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
 
@RequestMapping("class")
@Controller
public class RPTestHandler {
     
    String page="successrm";
     
    @RequestMapping("student")
    public String handle(@RequestParam(value="username") String un, @RequestParam(value="age",required=false) int age)
    {
        System.out.println("a student's request has come. username: "+un+", age: "+age);
        return page;
    }
}

    结果会报错,由于age虽然设置了required为false,请求参数能够不包含age,可是在处理函数中对应的参数类型是int,int是基本数据类型,没法为空,因此报错。解决办法是将int改成Integer。

4.二、defaultValue属性

    若是咱们仍然想用基本类型做为参数类型,那么能够用到@RequestParam注解的defaultValue属性来指定默认值。

@Controller
public class RPTestHandler {
     
    String page="successrm";
     
    @RequestMapping("student")
    public String handle(@RequestParam(value="username") String un, @RequestParam(value="age",required=false, defaultValue="0") int age)
    {
        System.out.println("a student's request has come. username: "+un+", age: "+age);
        return page;
    }
}


五、@PathVariable

    使用@PathVariable注解提取路径中的变量值,映射请求URL中的占位符到控制器方法参数。

例如:

@RequestMapping(value = "/testPathVariable/{username}", method = RequestMethod.GET)
public String testPathVariable(@PathVariable String username) {
    System.out.println("username:" + username);
    return "test";
}

访问路径能够是:http://localhost:8080/MySpringMVC/roger/testPathVariable/roger_fang

可是/testPathVariable/{username},路径中username部分不能有'/'。


六、@Autowired和@Service进行依赖注入

    @Autowired,注释类型属于org.springframework.beans.factory.annotation包,注解到字段或方法。

    @Service,注释类型属于org.springframework.stereotype包,注解到类上,用于指示类是一个服务,在配置文件中还须要添加一个<mvc:component-scan base-package="xxx" />元素来扫描依赖基本包。

例如:

Controller类

public class ProductController {
    @Autowired
    privte ProductService productService;
    
    //handle method
}

ProductService接口

public interface ProductService {
    //Product处理方法
}

ProductServiceImpl类

@Service
public class ProductServiceImpl implements ProductService{
    //Product处理方法
}

    本例中,@Autowired注解会使一个ProductService实例被注入到ProductController实例中,同时,为了使ProductServiceImpl类能被spring扫描到,必须为其标注@Service。


七、@ModelAttribute

a、注释方法的参数

    用于将输入或建立的对象添加到Model对象中(若方法中没有显示添加)。

@RequestMapping("/saveProduct")
public String saveProduct(@ModelAttribute Product product, Model model) {
    ...
}

    @ModelAttribute若是未定义键值名则自动将类的首字母改成小写如"product"做为键值名添加到Model对象中。也能够自定义@ModelAttribute("xxx")。

    从Form表单或URL参数中获取(实际上,不作此注释也能拿到product对象)。

b、标注一个非请求的处理方法

    被@ModelAttribute注解的方法会在每次调用该控制器类的请求处理方法时被调用。带@ModelAttribute注解的方法能够返回一个对象或一个void类型,若是返回一个对象免则返回的对象会自动添加到Model中。

如下两种方式:

@ModelAtrribute
public void populateModel(Model model) {
    model.addAttribute(new Product())
}

@ModelAttribute
public Product addProduct() {
    return new Product();
}


八、@ResponseBody

使用@ResponseBody将会跳过视图处理部分,而是调用适合HttpMessageConverter,将返回值写入输出流

相关文章
相关标签/搜索