Bootstrap

框架学习07 - SpringMVC 地址映射

一. URL 地址映射配置

Controller层通过注解 @RequestMapping 将请求地址与⽅法进⾏绑定,可以在类级别和⽅法级别声明。类级别的注解负责将⼀个特定的请求路径映射到⼀个控制器上,将 url 和类绑定;通过⽅法级别的注解可以细化映射,能够将⼀个特定的请求路径映射到某个具体的⽅法上,将 url 和类的⽅法绑定。

  1. 映射单个 URLz在方法上

     /**
     * @RequestMapping("") 或 @RequestMapping(value="")
     * @RequestMapping 声明在⽅法上⾯,映射单个 URL访问地址:(如果有类路径需要写在⽅法路径前⾯)
     * http://losthost:8080/springmvc01/test01
     * @return
     */
     @RequestMapping("/test01")// @RequestMapping(value = "/test01")
     public ModelAndView test01(){
     ModelAndView modelAndView = new ModelAndView();
     modelAndView.addObject("hello","test01");
     modelAndView.setViewName("hello");
     return modelAndView;
     }
     /**
     * 路径开头是否加 斜杠"/" 均可 ,建议加上,如:@RequestMapping("/test02")
     * 访问地址:(如果有类路径需要写在⽅法路径前⾯)
     * @RequestMapping("/请求路径") 与 @RequestMapping("请求路径")均 可
     * http://ip:port/springmvc01/test02
     * @return
     */
     @RequestMapping("test02")
     public ModelAndView test02(){
     ModelAndView modelAndView = new ModelAndView();
     modelAndView.addObject("hello","test02");
     modelAndView.setViewName("hello");
     return modelAndView;
     }
    
  2. 映射多个 URL在方法上

    
     /**
     * @RequestMapping 声明在⽅法上⾯,映射多个 URL
     * @RequestMapping({"",""}) 或 @RequestMapping(value={"",""}) 
     * ⽀持⼀个⽅法绑定多个 url 的操作     
     * 访问地址:(如果有类路径需要写在⽅法路径前⾯)
     * http://ip:port/springmvc01/test03_01, http://ip:port/springmvc01/test03_02
     * @return
     */
     @RequestMapping({"/test03_01","/test03_02"})
     // @RequestMapping(value = {"/test03_01","/test03_02"})
     public ModelAndView test03(){
     ModelAndView modelAndView = new ModelAndView();
     modelAndView.addObject("hello","test03");
     modelAndView.setViewName("hello");
     return modelAndView;
    }
    
  3. 映射 URL 在控制器上

    @Controller
     @RequestMapping("/url") //⽤于类上,表示类中的所有响应请求的⽅法都是以该地址作为⽗路径。
     public class UrlController {
     /**
     * @RequestMapping 声明在类上⾯,类中的的⽅法都是以该地址作为⽗路径
     * 声明级别:类级别 + ⽅法级别 (/类路径/⽅法路径)访问地址http://ip:port/springmvc01/url/test04
     * @return
     */
     @RequestMapping("/test04")
     public ModelAndView test04(){
     ModelAndView modelAndView = new ModelAndView();
     modelAndView.addObject("hello","test04");
     modelAndView.setViewName("hello");
     return modelAndView;
        }
    
  4. 设置 URL 映射的请求⽅式

    默认没有设置请求⽅式,在HTTP 请求中最常⽤的请求⽅法是 GET、POST,还有其他的⼀些⽅法, 如:DELET、PUT、HEAD 等。
    可以通过 method 属性设置⽀持的请求⽅式,如 method=RequestMethod.POST;如设置多种请求⽅
    式,以⼤括号包围,逗号隔开即可。

    /**
     * 设置请求⽅式
     *  通过 method 属性设置⽅法⽀持的请求⽅式,默认 GET请求和 POST等请求都⽀持。
     * 设置了请求⽅式,则只能按照指定的请求⽅式请求。
     * 访问地址:(只能使⽤POST请求访问)
     * http://ip:port/springmvc01/url/test05
     * @return
     */
     @RequestMapping(value = "/test05",method = RequestMethod.POST)
     public ModelAndView test05(){
     ModelAndView modelAndView = new ModelAndView();
     modelAndView.addObject("hello","test05");
     modelAndView.setViewName("hello");
     return modelAndView;
     }
    
  5. 通过参数名称映射 URL

    /**
     * 通过参数名称访问
     * 通过参数的形式访问
     * 访问地址:
     * http://ip:port/springmvc01/url?test06
     * @return
     */
     @RequestMapping(params = "test06")
     public ModelAndView test06(){
     ModelAndView modelAndView = new ModelAndView();
     modelAndView.addObject("hello","test06");
     modelAndView.setViewName("hello");
     return modelAndView;
     }
    

二. 参数绑定

客户端请求的参数到控制器功能处理⽅法上的参数的绑定,对于参数绑定⾮常灵活。
类型:

  • 基本数据类型

    /**
     * 基本类型数据绑定     
     * 参数值必须存在。如果没有指定参数值,也没有设置参数默认值,则会报500异常。
     * @param age
     * @param money
     */
     @RequestMapping("data01")
     public void data01(int age, double money){
     System.out.println("age:" + age + ", money:" + money);
     }
     /**
     * 基本类型数据绑定         
     * 通过注解 @RequestParam 标记⼀个形参为请求参数。(注解声明在形参的前⾯)设置参数的默认值 defaultValue 或起一个别名
     * @param age
     * @param money
     */
     @RequestMapping("data02")
     public void data02(@RequestParam(defaultValue = "18",name= "username") int age, @RequestParam(defaultValue = "10.0",name = "userMoney") double money){
     System.out.println("age:" + age + ", money:" + money);
     }
    
  • 包装类型

    /**
     * 包装类型数据绑定 (如果数据是基本类型,建议使⽤包装类型)    
     * 客户端请求参数名与⽅法形参名保持⼀致,默认参数值为null
     * 可以通过 @RequestParam 的name属性设置参数的别名,defaultValue属性设置参数默认值
     * @param age
     * @param money
     */
     @RequestMapping("data05")
     public void data05(Integer age, Double money){
     System.out.println("age:" + age + ", money:" + money);
     }
    
  • 字符串

  • 数组

    /**
     * 数组类型数据绑定
     * 客户端传参形式:ids=1&ids=2&ids=3
     * @param ids
     */
     @RequestMapping("/data06")
     public void data06(String[] ids){
     for(String id : ids){
     System.out.println(id + "---");
        }
     }
    
  • javaBean对象

    /**
     * JavaBean 数据绑定     
    * 客户端请求的参数名与JavaBean对象的属性字段名保持⼀致
    * @param user对象
     */
     @RequestMapping("/data07")
     public void data07(User user) {
     System.out.println(user);
     }
    
  • set 类型
    Set 和 List 类似,也需要绑定在对象上,⽽不能直接写在 Controller ⽅法的参数中。但是,绑定Set数据时,必须先在Set对象中add相应的数量的模型对象。

    public class User {
     private int id;
     private String userName;
     private String userPwd;
     private Set<Phone> phones = new HashSet<Phone>();
     public User() {
     phones.add(new Phone());
     phones.add(new Phone());
     phones.add(new Phone());
        }
    
    @RequestMapping("/data09")
     public void data09(User user){
     System.out.println(user);
     }
    
    <form action="data09" method="post">
     <input name="phones[0].num" value="123456" />
     <input name="phones[1].num" value="4576" />
     <input name="phones[2].num" value="4576" />
     <button type="submit"> 提交</button>
     </form>
    
  • List 类型
    此时 User 实体需要定义对应 list 属性。(对于集合的参数绑定,⼀般需要使⽤ JavaBean 对象进⾏包 ,创建一个jsp data08 和方法名一致 页面

    @RequestMapping("/data08")
     public void data08(User user){
     System.out.println(user);
     }
    
    <form action="data08" method="post">
     <input name="phones[0].num" value="123456" />
     <input name="phones[1].num" value="4576" />
     <button type="submit"> 提交</button>
     </form>
    
  • Map 类型
    Map最为灵活,它也需要绑定在对象上,⽽不能直接写在Controller⽅法的参数中。

    public class User {
     private int id;
     private String userName;
     private String userPwd;
     private Set<Phone> phones=new HashSet<Phone>();
     private Map<String, Phone> map=new HashMap<String, Phone>();
     // private List<Phone> phones=new ArrayList<Phone>();
     public User() {
     phones.add(new Phone());
     phones.add(new Phone());
     phones.add(new Phone());
        }
    
    @RequestMapping("/data10")
     public void data10(User user){
     Set<Entry<String, Phone>>  set = user.getMap().entrySet();
     for(Entry<String, Phone> entry:set){
     System.out.println(entry.getKey()+"--"+entry.getValue().getNum());
        }   
    }
    
    <form action="data10" method="post">
     <input name="map['1'].num" value="123456" />
     <input name="map['2'].num" value="4576" />
     <input name="map['3'].num" value="4576" />
     <button type="submit"> 提交</button>
     </form>入代码片
    

三. 请求转发与重定向

重定向是发⼀个302的状态码给浏览器,浏览器⾃⼰去请求跳转的⽹⻚。地址栏会发⽣改变。

  1. 重定向 redirect: 重新定向的路径

     /**
     * 重定向到JSP⻚⾯?传递参
     * @return
     */
     @RequestMapping(value="/view02")
     public String view02(){
     return "redirect:view.jsp?uname=zhangsan&upwd=123456";
     }
    
     /**      
     * 重定向到JSP⻚⾯传递参数 (通过 RedirectAttributes 对象设置重定向参数,避免中⽂乱码问题)
     * @param redirectAttributes
     * @return
     */
     @RequestMapping(value="/view04")
     public String view04(RedirectAttributes redirectAttributes){
     redirectAttributes.addAttribute("uname","张三");
     redirectAttributes.addAttribute("upwd","123456");
     return "redirect:view.jsp";
     }
    
     /**
     * 重定向到Controller,返回 ModelAndView 对象
     * @param modelAndView
     * @return
     */
     @RequestMapping(value="/view07")
     public ModelAndView view07(ModelAndView modelAndView){
     modelAndView.addObject("uname","admin");//设置传递到页面上的参数名和值
     modelAndView.setViewName("redirect:test01");//设置重定向到达的视图名称
     return modelAndView;
     }
    ``
    
    
    ```html
    <body>
    	${${param.参数名}} //uname
    </body>
    
  2. 请求转发
    ·直接调⽤跳转的⻚⾯,让它返回。对于浏览器来说,它⽆法感觉服务器有没有forward。地址栏不发⽣改变。可以获取请求域中的数据。 forward: 重新定向的路径

    ·用法和重定向一样
    

四. JSON 数据开发

  1. 基本概念
    Json 在企业开发中已经作为通⽤的接⼝参数类型,在⻚⾯(客户端)解析很⽅便。SpringMVC 对于json 提供了良好的⽀持,这⾥需要修改相关配置,添加 json 数据⽀持功能。

  2. @ResponseBody :将页面读取到Controller层传来的数据解析为某种格式的数据(如 json、xml 等)。

  3. @RequestBody:将页面传来的数据解析为java格式的数据传回Controller层

  4. 添加 json相关坐标 pom.xml

     <!-- 添加json 依赖jar包 -->
     <dependency>
     <groupId>com.fasterxml.jackson.core</groupId>
     <artifactId>jackson-core</artifactId>
     <version>2.10.0</version>
     </dependency>
     <dependency>
     <groupId>com.fasterxml.jackson.core</groupId>
     <artifactId>jackson-databind</artifactId>
     <version>2.10.0</version>
     </dependency>   
    <dependency>
     <groupId>com.fasterxml.jackson.core</groupId>
     <artifactId>jackson-annotations</artifactId>
     <version>2.10.0</version>
     </dependency>
    
  5. 修改配置⽂件 servlet-context.xml

    <!-- mvc 请求映射 处理器与适配器配置 -->
     <mvc:annotation-driven>
     <mvc:message-converters>
     <bean class="org.springframework.http.converter.StringHttpMessageConverter" />
     <bean 
    class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
     </mvc:message-converters>
     </mvc:annotation-driven>
    
  6. 注解使⽤

    @Controller
     @RequestMapping("/user")
     public class UserController {
     /**
     * @ResponseBody 返回的是JOSN格式的数据,返回JavaBean对象     
     * 注解设置在⽅法体上 或 注解设置在⽅法返回对象前,修饰符之后
     * @return
     */
     @RequestMapping("queryUser01")
    // @ResponseBody
     public  @ResponseBody User queryUser01(){
     User user = new User();
     user.setId(1);
     user.setUserName("zhangsan");
     user.setUserPwd("123456");
     // 返回的是user对象
    return  user;
        }
    
    
    /**
     *  @RequestBody 规定请求的参数是JOSN格式的字符串     
     * 注解设置在形参前⾯
     * @param user
     * @return
     */
     @RequestMapping("/getUser")
     @ResponseBody
     public User getUser(@RequestBody User user){
     System.out.println(user);
     return user;
     }
    
;