参考博客: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 注解参数访问特定的servlet请求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中。