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中。

原文地址:https://www.cnblogs.com/wangshen31/p/8471111.html