Spring MVC(下)

SpringMVC Controller控制器详解

Controller控制器作用
  • 收集、验证请求参数并绑定到命令对象;
  • 将命令对象交给业务对象,由业务对象处理并返回模型数据;
  • 返回ModelAndView(Model部分是业务对象返回的模型数据,视图部分为逻辑视图名)。
核心注解

@Controller : 用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller 对象。分发处理器将会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping 注解。

/** 
 * @Controller,类级别上的注解。我们定义的类可以只是一个 javabean,不需要实现任何接口。标注了 
 * @Controller,借助 <context:component-scan>,框架能自动识别到这就是一个 Controller 
 */  
@Controller  
public class MyController {  
  // ......  
}  

@RequestMapping : @RequestMapping 来映射URL 到控制器类,或者是到Controller 控制器的处理方法上。当@RequestMapping 标记在Controller 类上的时候,里面使用@RequestMapping 标记的方法的请求地址都是相对于类上的@RequestMapping 而言的;当Controller 类上没有标记@RequestMapping 注解时,方法上的@RequestMapping 都是绝对路径。这种绝对路径和相对路径所组合成的最终路径都是相对于根路径“/ ”而言的。

  • value: 路径地址
  • method:请求方法的规则,比如:如果设置了RequestMethod.POST,那么你的表单提交就必须使用POST提交,否则将报405错误
  • params: 提交中的数据中一定要有配置的参数(如id),否则将报400的错误
/** 
 * @RequestMapping 可以出现在类级别上,也可以出现在方法上。如果出现在类级别上,那请求的 url 为 类级别 
 * 上的 @RequestMapping + 方法级别上的 @RequestMapping,否则直接取方法级上的 @RequestMapping。 
 * 类级别的 @RequestMapping 不是必需的。 
 */  
 @Controller  
@RequestMapping("/my")  
public class MyController {
    /** 
       * 由于类级别上定义了 @RequestMapping,那么想匹配到这个方法来处理请求,url 必须为 /my/somelist。 
   * 如果没有定义类级别上的 @RequestMapping,url 为 /somelist 即可。同时,请求方法必须为 POST 
   */  
  @RequestMapping(value="/somelist", method=RequestMethod.POST);  
  public String getSomeList() {...}  
  /** 
     * 在方法级别使用 @RequestMapping 来限定请求处理的时候,可以指定两个属性。除了我们在上面刚使用过的 
     * method 属性,还有一个 params 属性。使用 params 属性,可以达到与使用 
     * ParameterMethodNameResolver 作为 MethodResolver的 MultiActionController 类似的功能。 
     * 
     * params 有两种表达形式,这里先说第一种:"parameterName=parameterValue" 
     * 
     * 请求方法为 GET 或 POST,且具有 hello 参数,且值为 world 的请求才能匹配到该方法,如: 
     *   /my?hello=world 
     */  
    @RequestMapping(params="hello=world", method={RequestMethod.GET, RequestMethod.POST})  
    public String helloworld() {...}  
    /** 
     * 请求方法为 GET 或 POST,且具有 hello 参数,且值为 java 的请求才能匹配到该方法,如: 
     *   /my?hello=java 
     */  
    @RequestMapping(params="hello=java", method={RequestMethod.GET, RequestMethod.POST})  
    public String hellojava() {...}  
    /** 
     * params 属性的另外一种表达形式为:"parameter" 
     * 
     * 请求方法为 GET,且具有请求参数 java 即匹配此方法,而不管 java 参数的值是什么,如: 
     *   /my?java=anything 
     */  
    @RequestMapping(params="java", method={RequestMethod.GET})  
    public String java() {...}  
     /** 
     * 请求方法为 GET,且具有请求参数 cplusplus 即匹配此方法,而不管 cplusplus 参数的值是什么,如: 
     *   /my?cplusplus=anything 
     */  
    @RequestMapping(params="cplusplus", method={RequestMethod.GET})  
    public String cplusplus() {...}  
    /** 
     * @RequestMapping 还有一个参数化 headers,它和 params 非常相似,也有两种表达式,只不过它是对 
     * 请求头做限制罢了。大家可以通过 telnet 或 http-client 来发类似的请求以检验。以 telnet 为例: 
     *  
     * telnet localhost 8080 
     * POST /contextPath/my HTTP/1.1 
     * Host: localhost 
     * hello: world # 这个就是自定义请求头,和标准的请求头的写法别无二致 
     */  
    @RequestMapping(headers="hello=world", method={RequestMethod.POST})  
    public String cplusplus() {...}  
}

@RequestBody : 将请求正文绑定到方法参数

@Controller  
@RequestMapping("/my")  
public class MyController {  
    /** 
   * 我们定义的 body 的数据类型是 String,请求体嘛,肯定是 String。实际上,@RequestBody 是用于将请 
   * 求体的内容绑定到方法参数上,数据类型不一定是 String。Spring MVC 是通过 HttpMessageConverter 
   * 来完成这种转换的。AnnotationMethodHandlerAdapter 默认注册了一些 HttpMessageConverters: 
   *   ByteArrayHttpMessageConverter - converts byte arrays 
   *   StringHttpMessageConverter - converts strings 
   *   FormHttpMessageConverter - converts form data to/from MultiValueMap< String,String> 
   *   SourceHttpMessageConverter - convert to/from a javax.xml.transform.Source 
   *   MappingJacksonHttpMessageConverter - converts json 
   *   MarshallingHttpMessageConverter - convert to/from an object using the  
   * 正如上所述,HttpMessageConverter 用于从请求正文绑定到对象和把对象序列化成 String 予客户端响应。 
   * 即 HttpMessageConverter is responsible for converting from the HTTP request message to 
   * an object and converting from an object to the HTTP response body 
   * 
   * 我们可以在 AnnotationMethodHandlerAdapter 定义任意多的 HttpMessageConverters。 
   * 
   * 既然 HttpMessageConverter 可以用于双向 convert,这里讨论的是 @RequestBody,那这部分我们只讲  
   * converting from the HTTP request message to an object。 
   * 
   * 假设我们只向 AnnotationMethodHandlerAdapter 注入了 MappingJacksonHttpMessageConverter 和 
   * MarshallingHttpMessageConverter。处理请求的方法有如下签名: 
   *     public String test(@RequestBody User user) { ... } 
   * 
   * 不管请求正文的内容是什么,对于客户端和服务器而言,它们只是用文本来互相通信。把字符串转为 User 对 
   * 象,该用哪个 HttpMessageConverter 来完成此项工作呢? 
   * 
   * 在定义 HttpMessageConverters 时,我们可以为其指定 supportedMediaTypes。对于将请求正文转为对象 
   * 这个方向的操作,HttpMessageConverters 会从请求头得到 Content-Type 头信息,看其是否隶属于其定义 
   * 的 supportedMediaTypes。若没有匹配上,则会使用下一个 HttpMessageConverter 做同样的判断。只要 
   * 某个 HttpMessageConverter 支持请求头中的 Content-Type,那么就会应用此 HttpMessageConverter 
   * 来将 String 转为 Object。当然,若请求正文并没有按照 Content-Type 所规定的格式来编写,必然要收到 
   * 500 的响应。同时请注意,请求头中还必须提供 Content-Length,否则拿不到请求正文。 
   * 
   * 如果所有的 HttpMessageConverters 中定义的 supportedMediaTypes 均不能匹配上 Content-Type 请 
   * 求头中的类型,那么就会收到 415 Unsupported Media Type 响应。 
   */  
  @RequestMapping("/user/body");  
  public String getBody(@RequestBody String body) {  
    // 这里的 body 的内容就是 hello  
    System.out.println(body);  
    return null;  
  }  
}  

@ResponseBody : 将返回的数据改为json格式。

@Controller  
@RequestMapping("/my")  
public class MyController {  
  /** 
   * 该方法的返回类型是 User,并不符合含有 @RequestMapping 的注解所需的签名方式。但它仍然是合法的,因 
   * 为在返回类型前有 @ResponseBody 注解,此注解将告知框架,将 User 对象作为影响正文返回?什么?对象 
   * 作为响应正文!所以,HttpMessageConverter 在这里就起到作用了。这里讨论的是 @ResponseBody,所以 
   * 这里我们只讲 converting from an object to the HTTP response body。 
   * 
   * User 对象要转成什么样的 String,或者说要转成什么格式的 String?这个时候需要从请求头中获得此信息 
   * 了,这里,就是请求头的 Accept 头。Accept 头可以使用逗号分隔定义多个类型,用以告知服务器我只接受 
   * 哪些类型的响应。AnnotationMethodHandlerAdapter 中同样注入了多个 HttpMessageConverter,每个  
   * HttpMessageConverter 都可以定义各自的 supportedMediaTypes。这个时候该用哪个  
   * HttpMessageConverter 来完成对象到文本的序列化操作呢? 
   * 
   * 遍历 Accept 头中的每种媒体类型,在定义的多个 HttpMessageConverters 中依次去匹配,若匹配上,就使 
   * 用该 HttpMessageConverter 来完成序列化操作,并且响应头的 Content-Type 并不是请求头 Accept 头 
   * 的诸多类型中第一个被匹配的类型,而是匹配到的 HttpMessageConverter 定义的 supportedMediaTypes 
   * 中的第一个类型。 
   * 
   * 如果所有的 HttpMessageConverters 中定义的 supportedMediaTypes 均不能匹配上 Accept 请求头中 
   * 的诸多的类型,那么就会收到 406 Not Acceptable 响应。 
   */  
  @RequestMapping("/user")  
  public @ResponseBody User getUser() {  
    return new User(18, "Jack", "计算机");  
  }  
}  

@RequestParam : 绑定 HttpServletRequest 请求参数到控制器方法参数。

@Controller  
@RequestMapping("/my")  
public class MyController {  
  /** 
   * 注意,这里的方法有一个参数。若请求 url 为 /my/test,会匹配此方法。这里的方法的参数名为 userId, 
   * 那么请求参数中一定有名为 userId 的参数,且值为整数。这也是默认的绑定行为,它是根据名称匹配原则进行 
   * 的数据绑定。当请求中的参数名与方法名一致的时候,相应的参数值将被绑定到相应的方法参数上。 
   *  
   * 如果没有传递 userId 参数,框架会传入 null。可是这里我们定义的是 primitive type,异常伺候!若 
   * 要解决此问题,需要将 primitive type 定义成相应的 wrapper type 即可,这里使用 Integer 就行了。 
   * 
   * 如果传递了 userId 参数,但值不是整数,你叫 test 怎么办呢?这种情况下,框架借助 PropertyEditor  
   * 数据类型转换失败,ExceptionResolver 会接手处理,请求是不会进入 test 方法的。 
   * 
   * 这种方式下,默认的绑定行为需要我们严格遵守命名一致性原则。如果我们对此不满,想自定义绑定关系,可以求 
   * 助于 @RequestParam。 
   */  
  @RequestMapping("/test")  
  public String test(int userId) { ... }  
  /** 
   * 当我们不想使用 userId 作为方法的参数名,即不想使用默认的数据绑定方式。如果我们要使用 id 作为方法 
   * 的参数,为了保证名称为 userId 的请求参数可以绑定到新的名称为 id 的方法参数上,我们就可以使用  
   * @RequestParam 对这一参数进行标注。@RequestParam 只可以标注于方法参数上。 
   * 如果请求参数中有 age,和方法的参数名称一致,故 age 参数不需要 @RequestParam 标注。如果没有传递 
   * age,我们又不想定义成 Integer,很显然框架会注入 null 值,报错是必然的。这是由于 @RequestParam  
   * 的 required 属性决定的,默认就是 true。如果我们定义成 false, 
   * 即 @RequestParam(required=false) int age 
   * 这个时候定义成 int 型的 age,即便请求参数没有 age 参数,也是没问题的。 
   * 同时,这里还能绑定 Date 类型,User 对象类型等等。如 date=2011-01-01&userName=Tom&userAge=18 
   * 这里,User 类的属性需要为 userName 和 userAge,以免和 age,name 混淆。所以,Spring MVC 对对象 
   * 的数据绑定就没有 Struts2 做的那么好了,Strtus2 可以这样:user.age=18&user.name=Tom 
   */  
  @RequestMapping("/test2")  
  public String test2(@RequestParam("userId") int id, int age, Date date, User user) { ... }  
}  

@PathVariable : 将 url template 里的参数绑定到方法参数

@Controller  
@RequestMapping("/my")  
public class MyController {  
  /** 
   * @PathVariable 是 url 模板,需要和 @RequestMapping 配合起来使用,这是 Spring 3.0 之后引入的。 
   * 
   * 在这个例子中,请求的 url 必须满足类似 /my/user/zhangsan/18 这样的格式才能匹配方法。url 模板里 
   * 的参数名和方法参数名的绑定规则和 @RequestParam 类似,这里就不再赘述了。 
   * 
   * @PathVariable @RequestParam 的区别在于: 
   *   @PathVariable 的 url:/my//user/zhangsan/18 
   *   @RequestParam 的 url:/my//user?nickname=zhangsan&age=18 
   */  
  @RequestMapping("/user/{nickname}/{age}");  
  public String getUserInfo(@PathVariable("nickname") String name, @PathVariable int age) {...}  
}  

ModelAttribute :

/** 
 * @ModelAttribute 可以为视图渲染提供更多的模型数据,而不需要在处理请求的方法里添加 ModelMap 或 
 * Model 类型的参数。 
 * 
 * @ModelAttribute 可以标注在方法(存数据)上,也可以标注在方法参数(取数据)上。 
 */  
@Controller  
@RequestMapping("/my")  
public class MyController {  
  /** 
   * 在处理该请求时,方法的返回类型是 User,貌似不符合返回类型的规范。由于这里使用了 @ModelAttribute 
   * 注解,表示将返回的对象以 "user" 为 key 放入模型数据里。这里的 key 值默认值是返回的数据类型首字母 
   * 小写的结果。如果想自定义 key,可以写成 @ModelAttribute("myAttribute"),那么模型数据将会将  
   * User 对象绑定到 key 为 "myAttribute" 上。 
   *  
   * jsp 里可以这样访问模型里的数据: 
   *   age: ${user.age} 
   *   name: ${user.name} 
   *   job: ${user.job} 
   * 
   * 当然,这里只是提到了 @ModelAttribute 存数据的操作。 
   */  
  @RequestMapping("/user")  
  @ModelAttribute  
  public User getUser() {  
    return new User(18, "Jack", "计算机");  
  }  
  /** 
   * 这里将 @ModelAttribute 标注在方法参数上,表示要从模型数据里取 key 为 "user" 的对象,绑定在方法 
   * 参数上。如果这样做的话,其实你是得不到上面的那个请求放入的 User 对象,得到的是另外一个对象。其实 
   * 也好理解,这是两个互相独立的请求,作用域不一样。要想达到我们的目的,即能够从模型数据里取数据,需要 
   * 求助于 @SessionAttributes 
   */  
  @RequestMapping("/user2")  
  public String showUser(@ModelAttribute User user) {  
    System.out.println(user);  
    return null;  
  }  
}  

@SessionAttributes

/** 
 * @SessionAttributes @ModelAttribute 类似,只不过 @SessionAttributes 是将数据存放于 session  
 * 中或从 session 中取数据。 
 * 
 * @SessionAttributes 只能应用在类型声明上。比如下面的类的声明中,只有属性名为 "the-attribute" 的数 
 * 据才会纳入到 session 的管理。 
 * 
 * @SessionAttributes 允许以属性名名称或者类型两种方法,来表明将哪些数据通过 session 进行管理。这里 
 * 我们使用的是指定属性名称的方式,但通过类型来指定也是可行的,如: 
 *   @SessionAttributes(types=User.class) 
 */  
@Controller  
@RequestMapping("/my")  
@SessionAttributes("the-attribute")  
public class MyController {  
  @RequestMapping("/getUser")  
  public String getUser(int userId, Model model) {  
    /** 
     * 注意,这里将 User 对象添加到属性名为 "the-attribute" 上,所以 User 对象将纳入到 session 的 
     * 管理。如果这里添加的对象的属性名不是 "the-attribute",那么它只会作用于当前请求,而不会纳入到  
     * session 的管理中。 
     */  
    User user = userService.getUserById(userId);  
    model.addAtrribute("the-attribute", user);  
    return "userinfo";  
  }   
  /** 
   * 将模型里的 "the-attribute" 为 key 的对象绑定到 User 类上。由于在类级别上声明了只有 "the- 
   * attribute" 的属性名才会纳入到 session 的管理,所以就解决了在 @ModelAttribute 注解中讲解中最 
   * 后提到的问题。 
   * 
   * 另外,这个方法还有两个参数,BindingResult 和 SessionStatus。由于这里有绑定数据的动作,我们可以 
   * 根据 BindingResult 对象获得数据绑定结果以决定后继流程该如何处理。SessionStatus 在这里用于处理 
   * 完请求后,清空 session 里的数据。 
   */  
  @RequestMapping("/updateUser")  
  public String updateUser(@ModelAttribute("the-attribute") User user,   
            BindingResult result, SessionStatus status) {  
    if (result.hasErrors) {  
      return "error";  
    }     
    userService.updateUser(user);  
    // 我们通过调用 status.setComplete() 方法,该 Controller 所有放在 session 级别的模型属性数据  
    // 将从 session 中清空  
    status.setComplete();  
    return "redirect:getUser?userId=" + user.getId();  
  }  
}  

@CookieValue : 绑定 cookie 的值到 Controller 方法参数。
@RequestHeader :注解绑定 HttpServletRequest 头信息到 Controller 方法参数。

使用示例

自动匹配参数
@RequestMapping("/person")
public String toPerson(String name,double age){
    System.out.println(name+" "+age);
    return "hello";
}
使用InitBinder来处理Date类型的参数
@RequestMapping("/date")
public String date(Date date){
    System.out.println(date);
    return "hello";
}
//At the time of initialization,convert the type "String" to type "date"
@InitBinder
public void initBinder(ServletRequestDataBinder binder){
    binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),
            true));
}
自动装箱
package test.SpringMVC.model;
public class Person {
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    private String name;
    private int age;  
}
@RequestMapping("/person1")
public String toPerson(Person p){
    System.out.println(p.getName()+" "+p.getAge());
    return "hello";
}
向前台传递参数
@RequestMapping("/show")
public String showPerson(Map<String,Object> map){
    Person p =new Person();
    map.put("p", p);
    p.setAge(20);
    p.setName("jayjay");
    return "show";
}
在Controller中使用redirect方式处理请求
@RequestMapping("/redirect")
public String redirect(){
    return "redirect:hello";
}
文件上传
@RequestMapping(value="/upload",method=RequestMethod.POST)
public String upload(HttpServletRequest req) throws Exception{
    MultipartHttpServletRequest mreq = (MultipartHttpServletRequest)req;
    MultipartFile file = mreq.getFile("file");
    String fileName = file.getOriginalFilename();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");        
    FileOutputStream fos = new FileOutputStream(req.getSession().getServletContext().getRealPath("/")+
            "upload/"+sdf.format(new Date())+fileName.substring(fileName.lastIndexOf('.')));
    fos.write(file.getBytes());
    fos.flush();
    fos.close();
    return "hello";
}
使用@RequestParam注解指定参数的name
@Controller
@RequestMapping("/test")
public class mvcController1 {
    @RequestMapping(value="/param")
    public String testRequestParam(@RequestParam(value="id") Integer id,
            @RequestParam(value="name")String name){
        System.out.println(id+" "+name);
        return "/hello";
    }    
}
RESTFul风格的SringMVC
@Controller
@RequestMapping("/rest")
public class RestController {
    @RequestMapping(value="/user/{id}",method=RequestMethod.GET)
    public String get(@PathVariable("id") Integer id){
        System.out.println("get"+id);
        return "/hello";
    }
    @RequestMapping(value="/user/{id}",method=RequestMethod.POST)
    public String post(@PathVariable("id") Integer id){
        System.out.println("post"+id);
        return "/hello";
    }
    @RequestMapping(value="/user/{id}",method=RequestMethod.PUT)
    public String put(@PathVariable("id") Integer id){
        System.out.println("put"+id);
        return "/hello";
    }
    @RequestMapping(value="/user/{id}",method=RequestMethod.DELETE)
    public String delete(@PathVariable("id") Integer id){
        System.out.println("delete"+id);
        return "/hello";
    }
}
返回json格式的字符串
@Controller
@RequestMapping("/json")
public class jsonController {
    @ResponseBody
    @RequestMapping("/user")
    public  User get(){
        User u = new User();
        u.setId(1);
        u.setName("jayjay");
        u.setBirth(new Date());
        return u;
    }
}
异常的处理
  • 处理局部异常(Controller内)

    @ExceptionHandler
    public ModelAndView exceptionHandler(Exception ex){
        ModelAndView mv = new ModelAndView("error");
        mv.addObject("exception", ex);
        System.out.println("in testExceptionHandler");
        return mv;
    }
    @RequestMapping("/error")
    public String error(){
        int i = 5/0;
        return "hello";
    }
  • 处理全局异常(所有Controller)

    @ControllerAdvice
    public class testControllerAdvice {
        @ExceptionHandler
        public ModelAndView exceptionHandler(Exception ex){
            ModelAndView mv = new ModelAndView("error");
            mv.addObject("exception", ex);
            System.out.println("in testControllerAdvice");
            return mv;
        }
    }
  • 在SpringMVC配置文件中配置全局异常

    <!-- configure SimpleMappingExceptionResolver -->
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="exceptionMappings">
            <props>
                <prop key="java.lang.ArithmeticException">error</prop>
            </props>
        </property>
    </bean>

整体示例

实体类

package com.heqing.ssm.entity;
public class Test {
    private int id;
    private String name;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override  
    public String toString() {  
        return "test = {id:"+id+",name:"+name+"}";  
    }
}

控制层

package com.heqing.ssm.controller;

@Controller
@RequestMapping("/springMVC")
public class TestController {

    @ModelAttribute   
    public void modelAttribute() {    
       System.out.println("===Controller.before===");
    }   

    @ExceptionHandler  
    public void exceptionHandler(Exception e) {    
       System.out.println("===Controller.@ExceptionHandler==="+e.getMessage());
    }   

    @InitBinder
    public void initBinder(ServletRequestDataBinder binder){
        binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));
    }

    @RequestMapping("/index")
    public String index(Map<String,Object> map) {
        System.out.println("===Controller.springMVC===");
        map.put("message", "Hello World!");
        return "springMVC.html";
    }   

    @RequestMapping("/view")
    public ModelAndView view(HttpServletRequest req, HttpServletResponse resp) throws Exception {  
       //1、收集参数、验证参数  
       //2、绑定参数到命令对象  
       //3、将命令对象传入业务对象进行业务处理  
       //4、选择下一个页面  
       ModelAndView mv = new ModelAndView();  
       //添加模型数据 可以是任意的POJO对象  
       mv.addObject("message", "Hello World!");  
       //设置逻辑视图名,视图解析器会根据该名字解析到具体的视图页面  
       mv.setViewName("springMVC");  
       return mv;  
    }   

    @RequestMapping("/jsonUtil")
    public void jsonUtil(HttpServletResponse response,HttpServletRequest request, int id, String name) {
        Test test = new Test();
        test.setId(id);
        test.setName(name);
        List<String> list = new ArrayList<>();
        list.add("test1"); list.add("test2");
        Map<String,Object> paramsMap=new LinkedHashMap<String,Object>();
        paramsMap.put("id", 1);
        paramsMap.put("message", "Hello World!");
        paramsMap.put("test", test);
        paramsMap.put("list", list);
        JsonUtil.outPutJsonMessage(log, "test", response, paramsMap);
    }   

    @RequestMapping(value = "/requestBody", method = {RequestMethod.POST })
    @ResponseBody
    public void requestBody(@RequestBody List<Test> tests) {
        System.out.println("===Controller.requestBody===");
        System.out.println("size="+tests.size()+"   name1="+tests.get(0).getName());
    }  

    @RequestMapping("/responseBody")  
    @ResponseBody
    public Map<String, Object> responseBody() throws IOException {  
        System.out.println("===Controller.responseBody===");
        Map<String,Object> paramsMap = new LinkedHashMap<String,Object>();
        paramsMap.put("id", 1);
        paramsMap.put("name", "name1");
        return paramsMap;
    }  

    /**
     * value: 路径地址
     * method:请求方法的规则,比如:如果设置了RequestMethod.POST,那么你的表单提交就必须使用POST提交,否则将报405错误 
     * params: 提交中的数据中一定要有配置的参数(如id),否则将报400的错误
     * */
    @RequestMapping(value = "/requestParam", method = {RequestMethod.POST }, params="id") 
    @ResponseBody
    public void requestParam(@RequestParam int id, @RequestParam String name) {  
        System.out.println("===Controller.requestParam===");  
        System.out.println("id="+id+", name="+name);  
    }

    @RequestMapping("/requestParamAuto")
    @ResponseBody
    public void toPerson(String id, String name){
        System.out.println("===Controller.requestParamAuto==="); 
        System.out.println("id="+id+", name="+name);  
    }

    @RequestMapping("/requestBeanAuto")
    @ResponseBody
    public void requestBeanAuto(Test test){
        System.out.println("===Controller.requestBeanAuto==="); 
        System.out.println("id="+test.getId()+", name="+test.getName());  
    }

    @RequestMapping("/pathVariable/{id}") 
    @ResponseBody
    public void pathVariable(@PathVariable("id") String id) {  
        System.out.println("===Controller.pathVariable===");  
        System.out.println("id="+id);  
    }

    @RequestMapping("/initBinder") 
    @ResponseBody
    public void initBinder(Date date) {  
        System.out.println("===Controller.initBinder===");  
        System.out.println("date="+date);  
    }

    @RequestMapping("/upload")  
    @ResponseBody
    public void upload(HttpServletRequest request) throws IllegalStateException, IOException {
        System.out.println("===upload===");
        //创建一个通用的多部分解析器 
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());  
        //判断 request 是否有文件上传,即多部分请求  
        if(multipartResolver.isMultipart(request)){  
            //转换成多部分request    
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest)request;  
            //取得request中的所有文件名  
            Iterator<String> iter = multiRequest.getFileNames();
            while(iter.hasNext()){  
                //记录上传过程起始时的时间,用来计算上传时间  
                int pre = (int) System.currentTimeMillis();  
                //取得上传文件  
                MultipartFile file = multiRequest.getFile(iter.next());  
                if(file != null){  
                    //取得当前上传文件的文件名称  
                    String myFileName = file.getOriginalFilename();  
                    //如果名称不为“”,说明该文件存在,否则说明该文件不存在  
                    if(myFileName.trim() !=""){  
                        //重命名上传后的文件名  
                        String fileName = file.getOriginalFilename();  
                        //定义上传路径  
                        String path = "D:/test/" + fileName;  
                        File localFile = new File(path);  
                        file.transferTo(localFile);  
                    }
                }
                //记录上传该文件后的时间  
                int finaltime = (int) System.currentTimeMillis();  
                System.out.println("上传用时:"+(finaltime - pre)+"秒");  
            }  
        }  
    }  
}

显示层

< !DOCTYPE html>
< html>
  < head>
    < base href="<%=basePath%>">
    < title>springMVC< /title>
    < meta http-equiv="pragma" content="no-cache">
    < meta http-equiv="cache-control" content="no-cache">
    < meta http-equiv="expires" content="0">    
    < meta http-equiv="keywords" content="springMVC">
    < meta http-equiv="description" content="This is my test page">
    < script src="../js/jquery-3.1.1.min.js"></script> 
    < script src="../js/ajaxfileupload.js"></script> 
  < /head>

  < body>
             后台传递过来的消息:${message}  <br/>
    < spring:message code="start"/><br/>
    < button id="RequestBody"     type="button">测试  @RequestBody< /button>
    < button id="ResponseBody"    type="button">测试  @ResponseBody< /button>
    < button id="RequestParam"    type="button">测试  @RequestParam< /button>
    < button id="RequestParamAuto" type="button">测试  自动匹配参数< /button>
    < button id="RequestBeanAuto"  type="button">测试  自动装箱< /button>
    < button id="PathVariable"    type="button">测试  @PathVariable< /button>
    < button id="InitBinder"      type="button">测试  @InitBinder< /button>
    < button id="JsonUtil"        type="button">测试 JsonUtil< /button>
    < input type="file" id="uFile" name="uFile" multiple="multiple"/>
        < button id="uploadAll" type="button">上传文件< /button>
  < /body>

  < script>
   $("#RequestBody").click(function(){
        var testAry=[];  
        var test1={"id":1,"name":"name1"};  
        var test2={"id":2,"name":"name2"};  
        testAry.push(test1);  
        testAry.push(test2);       
        $.ajax({
            type: "POST",
            url: "/Demo_SSM/springMVC/requestBody",
            data:JSON.stringify(testAry),
            dataType: "json", 
            contentType: "application/json;",
            success: function(data){
                console.info(data);
            }
       });
    });

    $("#JsonUtil").click(function(){
        $.ajax({
            type: "POST",
            url: "/Demo_SSM/springMVC/jsonUtil",
            data: { 
                "id" : 1,
                "name" : "name"
            },
            success: function(data){
                console.info(data);
            }
       });
    });

    $("#ResponseBody").click(function(){
        $.ajax({
            type: "POST",
            url: "/Demo_SSM/springMVC/responseBody",
            success: function(data){
                console.info(data);
            }
       });
    });

    $("#RequestParam").click(function(){
        $.ajax({
            type: "POST",
            url: "/Demo_SSM/springMVC/requestParam",
            data: { 
                "id" : 3,
                "name" : "name3"
            },
            success: function(data){
                console.info(data);
            }
       });
    });

    $("#RequestParamAuto").click(function(){
        $.ajax({
            type: "POST",
            url: "/Demo_SSM/springMVC/requestParamAuto",
            data: { 
                "id" : 3,
                "name" : "name3"
            },
            success: function(data){
                console.info(data);
            }
       });
    });

    $("#RequestBeanAuto").click(function(){
        $.ajax({
            type: "POST",
            url: "/Demo_SSM/springMVC/requestBeanAuto",
            data: { 
                "id" : 3,
                "name" : "name3"
            },
            success: function(data){
                console.info(data);
            }
       });
    });

    $("#PathVariable").click(function(){
        $.ajax({
            type: "POST",
            url: "/Demo_SSM/springMVC/pathVariable/4",
            success: function(data){
                console.info(data);
            }
       });
    });

    $("#InitBinder").click(function(){
        $.ajax({
            type: "POST",
            url: "/Demo_SSM/springMVC/initBinder",
            data: { 
                "date" : "2017-01-16"
            },
            success: function(data){
                console.info(data);
            }
       });
    });

    $("#uploadAll").click(function(){
        $.ajaxFileUpload({
           url:"/Demo_SSM/springMVC/upload",
           fileElementId:"uFile",
           success: function (data, status){
                alert("上传成功");
           },
        });
    });
  </script>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值