# 20Spring MVC web系列 - 提供一个接口Controller

20Spring MVC web系列 - 提供一个接口Controller

一、背景

使用Spring boot创建项目。

二、简介

我们在使用Spring boot开发web项目时,需要添加spring-boot-starter-web这个依赖。我们知道Spring boot帮助我们处理在使用Spring技术时起步依赖、自动配置的问题。所以我们先来看下添加的spring-boot-starter-web这个依赖里有什么。

<dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <version>2.0.6.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-json</artifactId>
      <version>2.0.6.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <version>2.0.6.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.hibernate.validator</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>6.0.13.Final</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.0.10.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.0.10.RELEASE</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>

我们在最下面看到了熟悉的spring-webmvc,对就是它。我们知道Spring MVC是一个web层框架,所以我们在Spring boot中添加了它之后就可以开发web项目。Spring、Spring MVC、Spring boot的区别

三、实现一个Controller控制器

在Spring MVC中,控制器(Controller层)负责处理DispatcherServlet分发的请求,它把用户请求的数据经过业务处理之后封装成一个ModelAndView返回给DispatcherServlet(Spring MVC的请求流程)。

在Spring MVC中定义一个控制器非常简便,只需使用@Controller这个注解标记这个类即可。然后使用@RequestMapping定义URL请求路径,这样的Controller就能被外界访问到了。

package com.lucky.spring.controller;


import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

/**
 * Created by zhangdd on 2020/8/23
 */
@Controller
@Slf4j
public class ControllerController {

    @RequestMapping("/controller/hello1")
    public ModelAndView hello1() {
        log.info("/controller/hello1");
        ModelAndView mv = new ModelAndView();
        mv.setViewName("controller");
        return mv;
    }
}

这里返回的ModelAndView,会被视图解析器进行解析。

  • @Controller注解作用在类上就标识该类是一个Handler控制器类,在Spring初始化Bean信息时就会被加载
  • @RequestMapping注解的作用是为控制器指定可以处理哪些URL请求,该注解可以放置在类上或者方法上。
    • 当放置在类上时,提供初步的URL请求映射信息,即一个请求路径
    • 当放置在方法上时,提供进一步的细分URL映射信息

四、Spring MVC实现JSON交互

上面的例子中视图解析器对返回的ModelAndView进行解析得到View后,将进行视图渲染,这里支持的类型有jsp、freemarker、excel、pdf等。在pc端web开发可以能够支持,那么移动端的数据呢?如果是前后端分离的场景呢?或者说如何返回JSON或者XML数据格式的内容?

Spring MVC主要利用类型转换器将前台信息转换成开发者需要的格式。

  • 在相应的Controller方法接收参数前添加@RequestBody注解,用来接收请求参数的数据转换;
  • 在方法的返回值类型处添加@ResponseBody注解,将返回信息转换成相关格式的数据写入Http response body中,而不是解析为跳转路径

image.png

package com.lucky.spring.controller;

import com.lucky.spring.entity.Person;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created by zhangdd on 2020/8/23
 */
@Controller
@ResponseBody
public class JsonController {

    @RequestMapping("/json/helloJson")
    private String helloJson() {
        return "helloJson";
    }


    @RequestMapping("/json/helloObject")
    private Person helloObject() {
        return new Person();
    }

}

image.png
更多情况下使用的是@RestController注解,该注解是@Controller和@ResponseBody两个的组合。

/*
 * Copyright 2002-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.web.bind.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Controller;

/**
 * A convenience annotation that is itself annotated with
 * {@link Controller @Controller} and {@link ResponseBody @ResponseBody}.
 * <p>
 * Types that carry this annotation are treated as controllers where
 * {@link RequestMapping @RequestMapping} methods assume
 * {@link ResponseBody @ResponseBody} semantics by default.
 *
 * <p><b>NOTE:</b> {@code @RestController} is processed if an appropriate
 * {@code HandlerMapping}-{@code HandlerAdapter} pair is configured such as the
 * {@code RequestMappingHandlerMapping}-{@code RequestMappingHandlerAdapter}
 * pair which are the default in the MVC Java config and the MVC namespace.
 *
 * @author Rossen Stoyanchev
 * @author Sam Brannen
 * @since 4.0
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {

	/**
	 * The value may indicate a suggestion for a logical component name,
	 * to be turned into a Spring bean in case of an autodetected component.
	 * @return the suggested component name, if any (or empty String otherwise)
	 * @since 4.0.1
	 */
	@AliasFor(annotation = Controller.class)
	String value() default "";

}

五、@RequestMapping的其他应用

5.1 注解指定请求方法

package com.lucky.spring.controller;

import org.springframework.web.bind.annotation.*;

/**
 * Created by zhangdd on 2020/8/24
 */
@RestController
public class MethodController {

    @RequestMapping(value = "/method/getMethod", method = RequestMethod.GET)
    public String getMethod() {
        return "getMethod";
    }

    @RequestMapping(value = "/method/postMethod", method = RequestMethod.POST)
    public String postMethod() {
        return "postMethod";
    }

    @GetMapping("/method/getMapping")
    public String getMapping() {
        return "getMapping";
    }

    @PostMapping("/method/postMapping")
    public String postMapping() {
        return "postMapping";
    }
}

  • @RequestMapping 提供method属性用来指定URL的请求方法类型
    • 当method = RequestMethod.GET时,@RequestMapping效果和@GetMapping一样
    • image.png
    • 当method = RequestMethod.POST时,@RequestMapping效果和@PostMapping一样
    • image.png
posted @ 2020-08-24 18:42  在线打工者  阅读(294)  评论(0)    收藏  举报