SpringMVC实例及注解(二)

@RequestMapping()
除了修饰方法,还可以修饰类
1、类定义处:提供初步的请求映射信息。相对于WEB应用的根目录
2、方法处:提供进一步的细分映射信息。相对于类定义处的URL。若类定义处未标注@RequestMapping,则方法处标记的URL相对于WEB应用的根目录

value:请求的URL
method:请求方式(get/post)
params:请求参数
也可用params和headers类更加准确的映射请求,params和headers支持简单的表达式

@PacthVariable映射URL绑定的占位符
1、带占位符的URL是spring3.0新增的功能,该功能在springMVC想REST目标挺进发展过程中具有里程碑的意义
2、通过@PathVariable可以将URL中占位符参数绑定到控制器处理方法的入参中:URL的{xxx}占位符可以通过@PathVariable{"xxx"}绑定到操作方法的入参中。

@RequesttMapping("/delete/{id}")
public String delete(@PathVariable("id") Integer id){
    Dao.delete(id);
    return "delSuccess";
}

REST:Representational State Transfer。资源表现层转化,是目前最流行的一种互联网软件结构。
即:HTTP协议里面的四个标识操作方式的动词:GET\POST\PUT\DELETE。他们分别对应四种基本操作:
GET:用来获取资源
POST:用来新建资源
PUT:用来更新资源
DELETE:用来删除资源

在web.xml中配置HiddenHttpMethodFilter,可以把POST请求转为DELETE或PUT请求

<filter>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mappping>
    <filter-name>HiddenHttpMethodFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

REST风格的URL
以CRUD为例:
新增:/order POST
修改:/order/1 PUT
获取:/order/1 GET
删除:/order/1 DELETE

请求处理方法需标识处理请求的类型。
如:

@Cotroller
public class test{
    @RequestMapping(value="/order/{id}",method=RequestMethod.DELETE)
    public String delete(@PathVariable Integer id){
        System.out,println("删除成功="+id);
        return "success";
    }
}

注:发送PUT请求和DELETE请求时
1、需要配置HiddenHttpMethodFilter
2、需要发送POST请求
3、需要在发送POST请求时携带一个name="_method"的隐藏域,值为DELETE或PUT
使用@PathVariable注解得到目标方法的id

@RequestParam绑定请求参数值
使用@RequestParam可以把请求参数传递给请求方法
value:参数名
required:是否必须。默认为true,表示请求参数中必须包含对应的参数,若不存在,将抛出异常
defaultValue:请求参数的默认值
如:

@RequestMapping("/handler1")
public String handler(@RequestParam(value="userName",required=false) String userName,
    @RequestParam(value="age",required=false,defaultValue="0") int age){
    System.out.println("参数值username="userName+"age="+age);
    return "success";
}

@RequestHeader绑定请求报头的属性值
请求头包含有若干个属性,服务器可据此获知客户端的信息,通过@RequestHeader即可将请求头中属性值绑定到处理方法的入参中

@RequestMapping("/handler2")
public String handle2(@RequestHeader("Acept-Encoding") String encoding){
    System.out.println("请求头="+encoding);
    return "success";
}

使用方法与@RequestParam类似

@CookieValue:映射一个cookie值,属性同@RequestParam相同

使用POJO对绑定请求参数值
springmvc会按请求参数名和POJO属性进行自动匹配,自动为该对象填充属性值。支持级联属性。
如:dept.deptid、dept.address.tel等

@RequestMapping("/handler3")
public String handler(User user){
    System.out.println("测试==="+user);
    return "succee";
}

使用Servlet API作为入参:
MVC的Handler方法可以接受ServletAPI的类型:
HttpServletRequest
HttpServletResponse
HttpSession
java.security.Principal
Locale
InputStream
OutputStream
Reader
Writer

@RequestMapping("/servletAPI")
public void servletAPI(HttpServletRequest request,HttpServletResponse response,Writer out)throws IOException{
    System.out.println("request="+request+":response="+response);
    out.write("hello");
} 

模型数据处理:
ModelAndView:处理方法返回值类型为ModelAndView时,方法即可通过该对象添加模型数据
Map及Model:入参为org.springframework.ui.Model、org.springframework.ui.ModelMap或java.util.Map时,处理方法返回时,Map中的数据自动添加到模型中。
@SessionAttributes:将模型中的某个属性暂存到HttpSession中,以便多个请求之间可以共享这个属性。
@ModelAndView:方法作为入参标注该注解后,入参的对象就会放到数据模型中。


1、ModelAndView:
控制器处理方法的返回值如果为ModelAndView,则其既包含视图信息,也包含莫行数据信息。
添加莫行数据:

ModelAndView addObject(String attributeName,Object attributeValue)
ModelAndView addAllObject(Map<String,?> modelMap)

设置视图:
xxx setView(View view)
xxx setViewName(String viewName)

//springMVC会把ModelAndView的model中数据放到request域对象中
//requestScope     ${requestScope.hello}
@RequestMapping("/testModelAndView")
public ModelAndView test(){
    String view="success";
    ModelAndView modelAndView=new ModelAndView(view);

    //添加模型数据到ModelAndView
    modelAndView.addObject("hello","你好");

    return modelAndView;
}

2、Map/Model
    1)SpringMVC在内部使用了一个org.springframework.ui.Model接口存储模型
    2)SpringMVC在调用方法前会创建一个隐含的模型对象作为模型数据的额存储容器。
      如果方法的入参为Map/Model类型,SpringMVC会将隐含模型的引用传递给这些入参。
      在方法体内,开发者可以通过这个入参对象访问到模型中的所有数据,也可以想模型中添加新的属性数据。

//目标方法可以添加Map类型的参数,也可以是Model/ModelMap类型

@RequestMapping("testMap")
public String testMap(Map<String,Object> map){
    map.put("name",Arrays.asList("Tom","Jerry","Mike"));
    return "success";
}

@SessionAttributes:若希望在多个请求之间共用某个模型属性数据,则可以在控制器类上标注,springmvc将在模型中对应的属性暂存到HttpSession中。
@SessionAttributes除了可以通过属性名指定需要存放到会话中的属性外(使用value属性),
还可以通过模型属性的对象指定哪些模型属性需要存放到会话中(使用types属性)。
    @SessionAttributes(type=User.class)会将隐含模型中所有的类型为User.class的属性添加到会话中。
    @SessionAttributes(value={"user1","user2"})
    @SessionAttributes(types={User.class,Dept.class})
    @SessionAttributes(value={"user1","user2"},types={"Dept.class"})

/**
*存放在session域中可以通过${sessionScope.user}得到属性值
*@SessionAttributes只能放在类的上面。
*/
@Controller
@RequestMapping("/springmvc")
@SessionAttributes(value={"user"},types={String.class})//将数据存放在session域中
public class Test{
    @RequestMapping("/testSessionAttributes")
    public String testSessionAttributes(Map<String,Object> map){
    
        User user=new User("zhangsan",12);
        map.put("user",user);
        map.put("test","测试");
        return "success";
    }
}


ModelAndView:

@ModelAndView
public void getUser(@RequestParam(value="id",required=false) Integer id,Map<String,Object> map){
    System.out.println("modelAttributes method");
    if(id!=null){
        User user=new User(1,"ROM","123456",12);
        System.out.println("数据库中的相对应的数值="+user);
        map.put("user",user);
    }

}
/**
*如果只是这样写,前端传递的参数只有:id,name,age,并未传递password,这样修改将会造成数据库中保存的密码为null,此操作是不允许出现的,
*所以我们在修改时需要先获取数据库中的值,使其保证在修改操作时,密码保持不变。
*
*运行流程:
*1、执行@ModelAndView注解修饰的方法:从数据库取出对象,把对象放入到MAP中。健为user
*2、SpringMVC从map中取出的User对象,并从表单的请求参数赋给该User对象对应的属性
*3、springmvc把上述对象传入目标方法的参数
*
*注意:在@ModelAndView修饰的方法中,放入到map时的键需要和目标方法入参类型的第一个字母小写的字符串一致
*
*源码分析流程
*1、调用@ModelAttribute注解修饰对的方法,实际上把@ModleAttribute方法中Map中的数据放在了implecitModel中。
*2、解析请求处理器的目标参数,实际该目标参数来自于WebDataBinder对象的target属性
*1).创建WebDataBinder对象:
*①.确定objectName属性:若传入的attrName属性值为"",则objectName为类名第一个字母小写。
*注意:attrName 若目标方法的POJO属性使用了@ModelAttribute来修饰,则attrName值即为@ModelAttribute的value的属性值
*
*②。确定target属性:
*>在implicitModel中查找attrName对应的属性值。
*>若不存在:则验证当前Handler是否使用了@SessionAttributes进行修饰,若使用了,则尝试从Session中获取attrName所对应的属性值。
*若session中没有的对应的属性值,则抛出异常
*>若Handler没有使用@SessionAttributes进行修饰,或@SessionAttributes中没有使用value值指定的key和attrName相匹配,则通过反射创建了POJO对象
*2).springmvc 把表单的请求参数赋给了WebDataBinder的target对应的属性
*3).springmvc会把WebDataBinder的attrName和target给到implicitModel,进而传到request域的对象中。
*4).把WebDataBinder的target作为参数传递给目标方法的入参。
*/
@RequestMapping("/testModel")
public String testModelAndView(User user){
    System.out.println("修改:"+user);
    return "success";
}

 

posted @ 2017-06-22 16:37  Mr.栋  阅读(332)  评论(0编辑  收藏  举报