spring注解:@RestController、@Controller、@ResponseBody

@responseBody

@responseBody注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据。需要注意的呢,在使用此注解之后不会再走试图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。

 @ResponseBody这个注解通常使用在控制层(controller)的方法上,其作用是将方法的返回值以特定的格式写入到response的body区域,进而将数据返回给客户端。当方法上面没有写ResponseBody,底层会将方法的返回值封装为ModelAndView对象。

假如是字符串则直接将字符串写到客户端;假如是一个对象,此时会将对象转化为json串然后写到客户端。这里需要注意的是,如果返回对象,按utf-8编码。如果返回String,默认按iso8859-1编码,页面可能出现乱码。因此在注解中我们可以手动修改编码格式,例如@RequestMapping(value="/cat/query",produces="text/html;charset=utf-8"),前面是请求的路径,后面是编码格式。

 那么,控制层方法的返回值是如何转化为json格式的字符串的呢?其实是通过HttpMessageConverter中的方法实现的,因为它是一个接口,因此由其实现类完成转换。如果是bean对象,会调用对象的getXXX()方法获取属性值并且以键值对的形式进行封装,进而转化为json串。如果是map集合,采用get(key)方式获取value值,然后进行封装。


@Controller

 以前在编写Controller方法的时候,需要开发者自定义一个Controller类实现Controller接口,实现handleRequest方法返回ModelAndView。并且需要在Spring配置文件中配置Handle,将某个接口与自定义Controller类做映射。

这么做有个复杂的地方在于,一个自定义的Controller类智能处理一个单一请求。而在采用@Contoller注解的方式,可以使接口的定义更加简单,将@Controller标记在某个类上,配合@RequestMapping注解,可以在一个类中定义多个接口,这样使用起来更加灵活。

被@Controller标记的类实际上就是个SpringMVC Controller对象,它是一个控制器类,而@Contoller注解在org.springframework.stereotype包下。其中被@RequestMapping标记的方法会被分发处理器扫描识别,将不同的请求分发到对应的接口上。

Spring如何通过注解注入?
不过大家仔细想一下,为什么打上注解了就能实现接口功能了呢?换句话说,Spring怎么样找到开发者自定义的Controller把对应的请求分发到对应的方法上呢?

首先,要在Spring配置文件的头文件中引入spring-context。

其次,使用<context:component-scan>元素启动“包扫描”功能。

例如<context:component-scan base-package="com.myz.controller"/>

base-package是值是包的路径。意思就是,启动了报扫描功能,将com.myz.controller这个包下以及子包下的所有类扫描一遍,将标记有@Controller、@Service、@repository、@Component等注解的类注入到IOC容器中,作为Spring的Bean来管理。

这样,Spring就能找到Controller类,通过@RequestMapping注解处理对应的请求。
 


@RestController与@Controller

Spring的基于注释的MVC框架简化了创建RESTful Web服务的过程。传统的Spring MVC控制器和RESTful Web服务控制器之间的关键区别在于: 创建HTTP响应主体的方式。

虽然传统的MVC控制器依赖于View技术,但RESTful Web服务控制器只返回对象,对象数据作为JSON / XML直接写入HTTP响应。

以下步骤描述了典型的Spring MVC REST工作流:

  1. 客户端以URI形式向Web服务发送请求。

  2. 该请求被DispatcherServlet拦截,该服务器查找Handler Mappings及其类型:A、 应用程序上下文文件中定义的Handler Mappings部分告诉DispatcherServlet使用哪种策略根据传入请求查找控制器。B、 Spring MVC支持三种不同类型的映射请求URI到控制器:注释,名称约定和显式映射。

  • 请求由Controller处理,响应返回到DispatcherServlet,然后DispatcherServlet将调度到视图。 

    使用@Controller时需要用@ResponseBody注释

    Spring 3.x 或使用@Controller情况下,在方法上使用@ResponseBody注释时,Spring会转换返回值并自动将其写入HTTP响应。Controller类中的每个方法都必须使用@ResponseBody进行注释。

    Spring有一个在后台注册的HttpMessageConverters列表。HTTPMessageConverter的职责是将请求主体转换为特定类并再次返回响应主体,具体取决于预定义的mime类型。每次发出请求命中@ResponseBody时,Spring都会遍历所有已注册的HTTPMessageConverters,寻找符合给定mime类型和类的第一个,然后将其用于实际转换。

@Controller
@RequestMapping("employees")
public class EmployeeController {
    Employee employee = new Employee();
    @RequestMapping(value = "/{name}", method = RequestMethod.GET, produces = "application/json")
    public @ResponseBody Employee getEmployeeInJSON(@PathVariable String name) {
       employee.setName(name);
       employee.setEmail("employee1@genuitec.com");
    return employee; 
    }

    @RequestMapping(value = "/{name}.xml", method = RequestMethod.GET, produces = "application/xml")
    public @ResponseBody Employee getEmployeeInXML(@PathVariable String name) {
       employee.setName(name);
     employee.setEmail("employee1@genuitec.com");
       return employee; 
    }
}

@RestController

Spring 4.0引入了@RestController,这是一个控制器的专用版本,它是一个方便的注释,除了自动添加@Controller和@ResponseBody注释之外没有其他新魔法。

通过使用@RestController批注对控制器类进行注释,您不再需要将@ResponseBody添加到所有请求映射方法中。@ResponseBody注释默认处于活动状态。

要在我们的示例中使用@RestController,我们需要做的就是将@Controller修改为@RestController并从每个方法中删除@ResponseBody。结果类应如下所示:

@RestController
public class EmployeeController {

    Employee employee = new Employee();

    @GetMapping("/employees/{name}")
    public Employee getEmployeeInJSON(@PathVariable("name") String name) {
       employee.setName(name);
       employee.setEmail("employee1@genuitec.com");
       return employee;
    }
 
}

我们不再需要将@ResponseBody添加到请求映射方法中。进行更改后,再次在服务器上运行应用程序会产生与以前相同的输出。使用@RestController非常简单,这是从Spring v4.0开始创建MVC RESTful Web服务或基于SpringBoot 2的首选方法。


总结

@RestController = @ResponseBody + @Controller  合在一起的作用。

1) 如果只是使用@RestController注解Controller,则Controller中的方法无法返回jsp页面,或者html,配置的视图解析器 InternalResourceViewResolver不起作用,返回的内容就是Return 里的内容。

2) 如果需要返回到指定页面,则需要用 @Controller配合视图解析器InternalResourceViewResolver才行。
    如果需要返回JSON,XML或自定义mediaType内容到页面,则需要在对应的方法上加上@ResponseBody注解。

例如:

1.使用@Controller 注解,在对应的方法上,视图解析器可以解析return 的jsp,html页面,并且跳转到相应页面;若返回json等内容到页面,则需要加@ResponseBody注解。

	@CrossOrigin
	@Controller
	public class FileUploadController {

		// 跳转到上传文件的页面
		@RequestMapping(value = "/gouploadimg", method = RequestMethod.GET)
		public String goUploadImg() {
			// 跳转到 templates 目录下的 uploadimg.html
			return "uploadimg";
		}

		// 处理文件上传
		@RequestMapping(value = "/testuploadimg", method = RequestMethod.POST)
		public @ResponseBody String uploadImg(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
			System.out.println("调用文件上传方法");
			String contentType = file.getContentType();
			String fileName = file.getOriginalFilename();
		}
	}

2.@RestController注解,相当于@Controller+@ResponseBody两个注解的结合,返回json数据不需要在方法前面加@ResponseBody注解了,但使用@RestController这个注解,就不能返回jsp,html页面,视图解析器无法解析jsp,html页面。

@CrossOrigin
@RestController /* @Controller + @ResponseBody*/
public class HospitalController {

    //注入Service服务对象
    @Autowired
    private HospitalService hospitalService;

    /**
     * 查询所有医院信息(未分页)
     */

    @RequestMapping(value = "findAllHospital",method = RequestMethod.GET)
    public  List<Hospital> findAllHospital(){
        List<Hospital> hospitalList= hospitalService.findAllHospital();
        return hospitalList;
    }

 


其他

@Configuration把一个类作为一个IoC容器,它的某个方法头上如果注册了@Bean,就会作为这个Spring容器中的Bean。
@Scope注解 作用域
@Lazy(true) 表示延迟初始化
@Service用于标注业务层组件、 
@Controller用于标注控制层组件(如struts中的action)
@Repository用于标注数据访问组件,即DAO组件。
@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
@Scope用于指定scope作用域的(用在类上)
@PostConstruct用于指定初始化方法(用在方法上)
@PreDestory用于指定销毁方法(用在方法上)
@DependsOn:定义Bean初始化及销毁时的顺序
@Primary:自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常
@Autowired 默认按类型装配,如果我们想使用按名称装配,可以结合@Qualifier注解一起使用。如下:
@Autowired @Qualifier("personDaoBean") 存在多个实例配合使用
@Resource默认按名称装配,当找不到与名称匹配的bean才会按类型装配。
@PostConstruct 初始化注解
@PreDestroy 摧毁注解 默认 单例  启动就加载
@Async异步方法调用

  • 10
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值