您的位置:首页 > 编程语言 > Java开发

4、Spring MVC 之 实现Controller

2016-07-13 23:38 706 查看
控制器提供的应用程序行为通常通过服务接口定义.Controller翻译用户的输入并将其转换为一个模型,用于提供给用户视图。Spring用一种非常抽象的方式实现控制器,它使您能够创建一个多样化的控制器。

在Spring2.5中为MVC Controller引入一种基于annotaion的编程模型。你可以使用像@RequestMapping,@RequestParam, @ModelAttribute等等这些注解。这些注解支持即可以从Servlet MVC又可以从Portlet MVC获取到。通过这种方式实现Controller你不需要继承特殊的base class与不需要实现特殊的接口。而且,他们通常不是直接依赖于Servlet或者Portlet的API,但是你能够很容易的通过Servlet或者Portlet工具来使用。

注意:可以在Github上的spring项目的组织(https://github.com/spring-projects/),许多web应用程序利用在这一节中描述的注释支持包括:MvcShowcase, MvcAjax, MvcBasic, PetClinic, PetCare以及其它.

@Controller
public class HelloWorldController {

@RequestMapping("/helloWorld")
public String helloWorld(Model model) {
model.addAttribute("message", "Hello World!");
return "helloWorld";
}
}


正如你所看到的,@Controller和@RequestMapping注释允许你使用灵活的方法名称和签名.在这个特殊的例子中方法接受一个Modle并且以为一个字符串返回一个视图.在后面会介绍各种各样的参数方法参数和返回值。@Controller,@RequestMapping和许多其他注释构成了Spring MVC实现的基础.这章节主要说明这些注释并且它们是如何在一个Servlet环境中的一般用法。

1、使用@Controller定义一个Controller

@Controller注释表明一个特定的类提供一个控制器的作用.Spring并不要求您扩展任何控制器基类或引用Servlet API。但是可以如果你需要你仍然可以引用Servlet一些特性。

@Controller注解注释的类作为模板,说明它的角色。dispatcher扫描这些被注解的类用来映射标记了@RequestMapping注解的方法.(看下面的部分)

你可以使用标准的Spring bean定义调度程序的上下文显式地定义注释控制器bean。但是@Controller也允许被自动检测,与Spring一般支持检测在类路径中组件的类一样和会自动注册并定义bean。

为了能够自动检测到这些被注解了的Controllers,你需要给你的配置添加组件扫描。使用spring-context这个schema如以下所示的XML代码片段。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<context:component-scan base-package="org.springframework.samples.petclinic.web"/>

<!-- ... -->

</beans>


2、使用@RequestMapping来映射请求

你使用@RequestMapping注释url映射/appointments到整个类或一个特定的处理程序方法。典型的使用方式是。@RequestMapping通过类级注释与这个类中方法级别的注解映射会映射这个特定的HTTP请求方法(“GET”、”POST”,等等。)或一个HTTP到一个Form表单。

下面的例子显示了在Spring MVC应用程序使用该注释作为一个控制器:

@Controller
@RequestMapping("/appointments")
public class AppointmentsController {

private final AppointmentBook appointmentBook;

@Autowired
public AppointmentsController(AppointmentBook appointmentBook) {
this.appointmentBook = appointmentBook;
}

@RequestMapping(method = RequestMethod.GET)
public Map<String, Appointment> get() {
return appointmentBook.getAppointmentsForToday();
}

@RequestMapping(path = "/{day}", method = RequestMethod.GET)
public Map<String, Appointment> getForDay(@PathVariable @DateTimeFormat(iso=ISO.DATE) Date day, Model model) {
return appointmentBook.getAppointmentsForDay(day);
}

@RequestMapping(path = "/new", method = RequestMethod.GET)
public AppointmentForm getNewForm() {
return new AppointmentForm();
}

@RequestMapping(method = RequestMethod.POST)
public String add(@Valid AppointmentForm appointment, BindingResult result) {
if (result.hasErrors()) {
return "appointments/new";
}
appointmentBook.addAppointment(appointment);
return "redirect:/appointments";
}
}


在这个例子中,@RequestMapping这个注解被使用到多个地方。第一种用法是使用到类级别,用来表明这个类的所有的处理方法都被关联到/appointments这个路径下。get()方法进一步@RequestMapping将细化:它只接收GET请求。代表一个/appointments的GET类开的HTTP请求调用这个方法。add()与getNewForm()也有类似的细化,把HTTP清晰的与Controller中方法绑定了起来。所以appointments/new这个GET请求会被getNewForm()方法处理。

getForDay()这个方法展现了@RequestMapping的另一种用法:URI模板,带参数的URI。

@RequestMapping注解不一定要使用到方法级别。没有它,所有路径是绝对的,而不是相对的。下面的例子就是在方法层级上使用@RequestMapping:

@Controller
public class ClinicController {

private final Clinic clinic;

@Autowired
public ClinicController(Clinic clinic) {
this.clinic = clinic;
}

@RequestMapping("/")
public void welcomeHandler() {
}

@RequestMapping("/vets")
public ModelMap vetsHandler() {
return new ModelMap(this.clinic.getVets());
}

}


在上面的例子中并没有指定GET,PUT或者POST等,因为@RequestMapping默认映射所有的HTTP请求。使用@RequestMapping(method=GET)会限制请求方式。

3、@Controller与AOP代理

在一些情况中,一个Controller需要在运行时使用AOP代理修饰。其中一个例子就是,如果你在controller中直接使用@Transactional标签。当遇到这种情况,对待这些特殊的controller,Spring推荐你使用基于类的代理。这一般是controller的默认选择。但是如果这个controller必须实现不是由Spring Context回调的接口(e.g. InitializingBean, *Aware等等),你可能需要明确的配置基于class的代理。例如在之前使用的是,需要把它修改成

4、Spring MVC支持@RequestMapping方法的新类

在Spring 3.1中引进了一些@RequestMapping方法的新类,分别是RequestMappingHandlerMapping和RequestMappingHandlerAdapter。他们建议使用甚至需要利用Spring MVC 3.1中的新特性。新的支持类默认启用的MVC名称空间和MVC Java配置,但如果使用都必须显式配置。本节描述一些旧的和新的支持类之间的重要的区别。

在Spring3.1之前,类型和方法级请求映射在两个独立的阶段检查 – 一个控制器首先通过DefaultAnnotationHandlerMapping被选定,第二步是通过AnnotationMethodHandlerAdapter来确定实际方法被调用的。

在Spring3.1新的支持类中,RequestMappingHandlerMapping是作为仅有一个类。用来决定哪个方法用来处理客户端的请求。可以认为控制器中的方法作为唯一端点的集合。通过类与方法级别的@RequestMappinginformation中的信息推断出这个方法。

这使得一些新的特性成为可能。

HandlerInterceptor或者HandlerExceptionResolver现在期待Object类型变成一个HandlerMethod。HandlerMethod可让他们检查的方法,其参数和相关的注释。这样处理一个URL不再需要跨越不同的控制器。

下面的几件事情不再发生:

1. 首先通过SimpleUrlHandlerMapping或者BeanNameUrlHandlerMapping查询controller,然后再通过使用了@RequestMapping注解的方法来定位方法。

2. 依赖方法名称作为两个@RequestMapping之间的援助机制来消除歧义的方法。在Spring MVC3.1中会用独特的方法来比较。(比较RequestMapping中的6个属性值)

3. 如果找到不匹配的controller的中方法来处理请求,会默认有一个方法(没有明确的路径来映射)来处理。在新的支持类中如果找不到方法来匹配,就报404错误。

上述特性仍然支持有现有的支持类。但是如果你想使用Spring MVC 3.1新的功能你需要使用新的支持类。

因为水平有限,翻译不足之处还望见谅。

原文地址:spring-framework-reference-4.2.6.RELEASE
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: