• SpringMVC之基于注解的Controller


    参考博客:https://www.cnblogs.com/qq78292959/p/3760560.html

    Controller注解:

    传统风格的Controller需要实现Controller接口,而现在我们只需要用注解就行了。

    基于注解的控制器有几个优点,1.一个控制器可以处理多个action(动作),而一个实现 Controller接口的控制器只能处理一个动作。    2.基于注解的控制器请求映射不需要存储在配置文件中,使用RequesetMapping注解类型就可以对一个方法进行请求处理。

    要写一个Controller,你只需要用  org.springframework.stereotype.Controller注解类型去注解

    @Controller
    public class CustomerController {
        //请求方法
    }

    Spring用扫描机制来找到应用程序中所有基于注解的控制器类。为了Spring能找到你的控制器,你需要做两件事:

      1.在spring的配置文件中声明Spring-context,如下:

      

    <beans
        ...
        xmlns:context:="http:www.springframework.org/schema/context"
        ...    
    >

      2.然后还需要饮用<component-scan/>元素

      <context:component-scan base-package="basePackage"/>

      请在<component-scan/>元素中指定控制器类的基本包。请确保所有控制器类都在基本包下,并且不要指定一个太广泛的基本包,因为这样会使得SpringMVC扫描了太多无关的包。

    RequestMaping注解类型:

       现在我们要在控制类的内部为每一个动作开发相应的处理方法。要让Spring知道用哪一种方法来处理它的动作,需要使用org.springframework.web.bind.annotation.RequestMapping注解类型映射的URL和方法。         可以用  @RequestMapping注解一种方法或类。

      一个采用@RequestMapping注解的方法将成为一个请求的处理方法。

    @Controller
    public class CustomerController {
        @RequestMapping(value="/customer_input") 
      public String inputCustomer()
      {
    //do somethimg return"CustomerFrom"; } }

      value属性将把URL映射到方法。当你用如下的URL就会访问到inputCustomer方法。

      http://domin/context/customer_input

      value属性是RequestMapping注解的唯一默认属性,因此如果只有这个属性,value可以省略不写:@RequestMapping("/customer_input")

      RequestMapping除了value属性外还有其他属性,method属性来指示该方法仅处理那些HTTP方法。下面这行注释代表着只有用HTTP POST方法或PUT方法的时候才调用这个请求方法。

      @RequestMapping(value="/order_process",method={RequestMethod.POST,RequestMethod.PUT})

      若method属性只有一个HTTP方法值,则无需花括号:

      @RequestMapping(value="/order_process",method=RequestMethod.POST)

      @RequestMapping也能注解一个类,这时所有的方法都将映射为相当于类级别的请求,看个例子:

      

    @Controller
    @RequestMapping(value="/customer")
    public class CustomerController {
        @RequestMapping(value="/delete",method={RequestMethod.POST,RequestMethod.PUT})
        public String deleteCustomer() {
            //...
            return ...;
        }
    }

      输入下面的URL会映射到deleteCustomer方法:    http://domin/context/customer/delete

      还有其他属性:

      2、 consumes,produces;

      consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;

      produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;

      3、 params,headers;

      params: 指定request中必须包含某些参数值是,才让该方法处理。

      headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。

       其他属性可以参考博客:https://www.cnblogs.com/qq78292959/p/3760560.html

    请求方法接收的参数和返回值:

      每个请求处理方法可以有多个不同类型的参数,以及一个多种类型的返回结果。例如如果请求处理方法中需要访问HttpSession对象,则可以添加HttpSession作为参数。Spring会将对象正确地传递给方法。  可以处理方法可以有这些参数:

    org.springframework.web.context.request.WebRequest
    org.springframework.web.context.request.NativeWebRequest
    java.util.Locale 当前请求的语言环境
    java.util.TimeZone 时区
    java.io.InputStream或java.io.Reader
    java.io.OutputStream或java.io.Writer
    org.springframework.http.HttpMethod
    java.security.Principal
    HttpEntity <?>参数用于访问Servlet的HTTP请求的标题和内容
    java.util.Map / org.springframework.ui.Model / org.springframework.ui.ModelMap 视图隐含模型
    org.springframework.web.servlet.mvc.support.RedirectAttributes 重定向
    命令或表单对象
    基本数据类型,如int,String,double...
    复杂数据类型,如自定义的POJO对象
    HandlerAdapter
    org.springframework.validation.Errors / org.springframework.validation.BindingResult 验证结果
    org.springframework.web.bind.support.SessionStatus 会话状态
    org.springframework.web.util.UriComponentsBuilder
    @PathVariable 注解参数访问URI模板变量。
    @MatrixVariable 注释参数用于访问位于URI路径段键值对对,矩阵变量。
    @RequestParam 注解参数访问特定的Servlet请求参数,请求参数绑定。
    @RequestHeader 注解参数访问特定的se​​rvlet请求HTTP标头,映射请求头。
    @RequestBody 注解参数访问HTTP请求主体,注解映射请求体
    @RequestPart 注解参数访问“的multipart / form-data的”请求部分的内容。处理客户端上传文件,多部分文件上传的支持
    @SessionAttribute 注解参数会话属性
    @RequestAttribute 注解参数访问请求属性

      注意这个org.springframework.ui.Model,这不是个servlet API的类型,而是一个包含Map的StringMVC类型,每次调用请求处理方法的时候,SpringMVC都会创建Model对象并将各种对象注入到Map中。要使用这个model的话,你只要在请求方法中加入这个参数就行了。

      请求方法中可以有这些返回值:

     

      ModelAndView
       Model
       ModelMap
       Map(包含模型的属性)
       View
       String(代表逻辑视图名)
       Void
      提供对servlet的访问以及相应HTTP头部和内容HttpEntity或ResponseEntity对象
      Callable
      DeferredResult
      其他任意类型,Spring将视其作输出给View的对象模型

    @Autowired和@service注解的依赖注入:

      将依赖注入到SpringMVC最简单的方法就是通过注解@AutoWired到字段或者方法。这个注解属于类型org.springframeword.beans.factory.annotation包。

      此外,为了能依赖注入,类必须注明为@Service,该类型是org.springframeword.stereotype包的成员,Service注解类型指示类是一个服务,此外在spring的配置文件中还要添加一个<component-scan/>元素来扫描依赖基本包。

    <context:component-scan base-package="dependencyPackage"/>

      用的时候就: 

    //ProductService接口
    
    public interface ProductService {
        Product add(Product product);
        Product get(long id);
    }
    
    
    
    //ProductServiceImpl类
    
    @Service 
    public class ProductServiceImpl implements ProductService {
        ...
        Product add(Product product) {
            ..
            return ..;
        }    
        Product get(long id) {
            ..
            return ..;
            
        }
    }
    
    
    
    Controller里面
    @Controller
    public class ProductController {
        
        @Autowired
        private ProductService productService;//注入实例,我们的的Service是个ProductService的实现类,所以这里也有多态的味道
        ....
        ....
    }

    重定向和Flash属性:

      比重定向快,因为重定向要经过客户端。 有时候,为了避免用户在重新加载界面的时候,因为如果是同一个url,容易再次调用同一个动作,例如成功提交表单后重新加载后又提交了一次。                为了避免这种现象,我们可以在提交表单后将用户重定向到一个不同的页面。

      在Controller的方法中返回:

      return:"redirect:/product_view/"+saveProduct.getId();

      这里的id是另外生成的,那么就可以防止saveProduct这个action被重复调用。但这个时候也有个不方便的地方,就是我们无法方便地传值给目标页面,因为这是两个不同的request和response,不能像转发一样简单地把属性添加到Model中,幸运的是Spring3.1版本以后提供了Flash属性——一种供重定向传值的方法。

      要使用Flash属性,必须在SpringMVC配置文件中有一个<annotation-driver/>元素。然后还要在方法中添加一个新的参数:RedirectAttributes redirectAttributes ,这个类来自org.springframework.web.servket.mvd.support.RedirectAttributes

      看个例子:

    @RequestMapping(value="product_save")
    public String saveProduct(ProductForm productForm,RedirectAttributes redirectAttributes) {
        ....
        redirectAttributes.addFlashAttribute("message","the product was successfully added");
        return "redirect:/product_view/"+saveProduct.getId();
    }

      

    请求参数和路径变量:

      请求参数就是url中的请求参数,想这个url有一个名额为productId的请求参数,其值为3:

      http://localhost:8080/app18b/product_retrieve?productId=3

      在传统的servlet编程中,我们用HttpServletRequest.getParameter("")来获取,现在我们可以通过org.springframework.web.bind.annotation.RequestParam注解类型来获取请求参数,只要用这个注解在方法参数中注解就行:

      public void sendProduct(@RequestParam int productId)

      可以理解成调用了

      int productId = Integer.parse(request.getParameter("productId")) ;   

      可见这个注解的参数不一定是字符串

      路径变量就是url中的变量,像url         /product_view/productId

      其中的productId是表示铲平标识符的整数,它是url中的一部分,叫做路径变量。下面这个例子看看路径变量的使用:

      

    @RequestMapping("/product_view/{id}")
    public String viewProduct(@PathVariable long id, Model model) {
        Product product = productService.get(id);
        model.addAttribute("product",product);
        return "ProductView";
    }

      为了使用路径变量,首先要在RequestMapping注解的值属性中加一个变量,这个变量必须放在花括号里。像上面的{id}     然后在方法签名中添加一个同名变量,并加上@PathVariable注解,然后当该方法被调用的时候,url中的这个id就会被复制到方法参数中,然后就可以使用了。   路径变量可以不是字符串,SpringMVC会尽力转换费字符串类型。

    @ModuleAttribute:

      前面谈到,SpringMVC每次调用请求处理方法的时候,都会创造一个Model类型的一个实例,若打算用这个实例,则可以在方法中添加一个Model类型的参数。事实上可以在方法参数中添加ModelAttribute注解类型来访问Model实例。  这个注解类型也是org.springframework.web.bind.annotation包的成员。

      可以用这个注解来注解方法参数或者方法。  带@ModelAttribute注解的方法参数,方法会将其输入或创建的参数对象添加到Model对象中。(若方法中没有闲式地添加)

      如       @RequestMapping("xxx")public String submitOrder(@ModelAttribute("newOrder")  Order order  , Model model ) {   .....  }

      输入或创建的Order实例将用newOrder为键名添加到Model对象中。如果没有定义键的名字,则将使用该对象的名称     @ModelAttribute Order order    那么键值就是order

      该注解也可以用来标注一个非请求的处理方法。  被@ModelAttribute注解的方法会在每次调用该控制器类的请求方法时被调用(在请求方法之前被调用),这个方法可以返回一个对象或一个void类型。如果返回一个对象,则返回对象会自动添加到Model中;如果返回void,则还需要添加一个Model类型的参数,并自行将实例添加到Model中。

  • 相关阅读:
    SWFUpload说明文档
    Ubuntu中root用户和user用户的相互切换
    不用IF比较两数大小
    Linux服务器下验证码图片不显示问题
    常用CSS语法
    常用CSS语法
    漫谈DataList的用法
    Session丢失浅析
    浅谈C#托管程序中的资源释放问题
    C#2.0 泛型详解
  • 原文地址:https://www.cnblogs.com/wangshen31/p/8471111.html
Copyright © 2020-2023  润新知