AjaxSpring Boot实战:Restful API的构建

  上平等篇稿子讲解了经Spring
boot与JdbcTemplate、JPA与MyBatis的并,实现对数据库的拜访。今天重中之重给大家分享一下如何通过Spring
boot向前者返回数据。

  以如今的支出流程中,为了最充分程度实现内外端的诀别,通常后端接口就提供数据接口,由前端通过Ajax请求从后端获取数据并开展渲染再显让用户。我们为此底极其多之艺术就是是后端会回去给前端一个JSON字符串,前端解析JSON字符串生成JavaScript的目标,然后重新做处理。本文就来演示一下Spring
boot如何实现这种模式,本文重点会教如何筹划一个Restful的API,并经Spring
boot来贯彻相关的API。不过,为了大家再次好的垂询Restful风格的API,我们事先筹一个风俗的数据返回接口,这样大家可以对比着来理解。

一致、非Restful接口的支持

  我们这边坐文章列表为条例,实现一个归文章列表的接口,代码如下:

@Controller
@RequestMapping("/article")
public class ArticleController {

    @Autowired
    private ArticleService articleService;

    @RequestMapping("/list.json")
    @ResponseBody
    public List<Article> listArticles(String title, Integer pageSize, Integer pageNum) {
        if (pageSize == null) {
            pageSize = 10;
        }
        if (pageNum == null) {
            pageNum = 1;
        }
        int offset = (pageNum - 1) * pageSize;
        return articleService.getArticles(title, 1L, offset, pageSize);
    }
}

  这个ArticleService的实现充分粗略,就是简单的包裹了ArticleMapper的操作,ArticleMapper的情大家好参照达同一首之稿子,ArticleService的落实类似如下:

@Service
public class ArticleServiceImpl implements ArticleService {

    @Autowired
    private ArticleMapper articleMapper;

    @Override
    public Long saveArticle(@RequestBody Article article) {
        return articleMapper.insertArticle(article);
    }

    @Override
    public List<Article> getArticles(String title,Long userId,int offset,int pageSize) {
        Article article = new Article();
        article.setTitle(title);
        article.setUserId(userId);
        return articleMapper.queryArticlesByPage(article,offset,pageSize);
    }

    @Override
    public Article getById(Long id) {
        return articleMapper.queryById(id);
    }

    @Override
    public void updateArticle(Article article) {
        article.setUpdateTime(new Date());
        articleMapper.updateArticleById(article);
    }
}

  运行Application.java这个近乎,然后访问:http://locahost:8080/article/list.json,就可以看到如下的结果:

Ajax 1

  ArticleServiceImpl这个看似是一个颇寻常的类,只出一个Spring的诠释@Service,标识为一个bean以便于通过Spring
IoC容器来保管。我们更来看望ArticleController这个看似,其实用过Spring
MVC的口应该都熟识这几只注解,这里大概解释一下:

  @Controller 标识一个像样为控制器。

  @RequestMapping URL的映射。

  @ResponseBody 返回结果转换为JSON字符串。

  @RequestBody 表示收到JSON格式字符串参数。

  通过这个三独注解,我们虽可知自在的落实通过URL给前端返回JSON格式数据的功力。不过大家肯定有些疑惑,这不还是Spring
MVC的东西呢?跟Spring boot有啊关系?其实Spring
boot的打算就是是啊咱省了配备的历程,其他力量实在还是Spring与Spring
MVC来啊咱提供的,大家该记得Spring
boot通过各种starter来为我们提供自动配置的劳务,我们的工程中之前引入了是仗:

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
</dependency>

  这个是享有Spring
boot的web工程还得引入的jar包,也就是说要是Spring
boot的web的工程,都默认支持上述的效能。这里我们更是发现,通过Spring
boot来出web工程,确实为我们看了广大配置的办事。

 

二、Restful API设计

  好了,我们今天复来看看如何兑现Restful
API。实际上Restful本身不是均等码什么奥秘的技巧,而光是相同栽编程风格,或者说是一种植设计风格。在风俗的http接口设计受到,我们一般才下了get和post两独办法,然后用我们好定义之乐章汇来代表不同的操作,比如上面查询文章的接口,我们定义了article/list.json来表示查询文章列表,可以经过get或者post方法来聘。而Restful
API的统筹虽通过HTTP的点子来代表CRUD相关的操作。因此,除了get和post方法外,还会为此到其它的HTTP方法,如PUT、DELETE、HEAD等,通过不同的HTTP方法来代表不同含义的操作。下面是自己计划的同样组针对文章的增删改查的Restful
API:

接口URL HTTP方法 接口说明
 /article  POST  保存文章
 /article/{id}  GET  查询文章列表
 /article/{id}  DELETE  删除文章
 /article/{id}  PUT  更新文章信息

   这里可以看来,URL仅仅是标识资源的路劲,而现实的一言一行由HTTP方法来指定。

 

三、Restful API实现

  现在咱们再度来看望哪兑现者的接口,其他就是无多说,直接看代码:

@RestController
@RequestMapping("/rest")
public class ArticleRestController {

    @Autowired
    private ArticleService articleService;

    @RequestMapping(value = "/article", method = POST, produces = "application/json")
    public WebResponse<Map<String, Object>> saveArticle(@RequestBody Article article) {
        article.setUserId(1L);
        articleService.saveArticle(article);
        Map<String, Object> ret = new HashMap<>();
        ret.put("id", article.getId());
        WebResponse<Map<String, Object>> response = WebResponse.getSuccessResponse(ret);
        return response;
    }

    @RequestMapping(value = "/article/{id}", method = DELETE, produces = "application/json")
    public WebResponse<?> deleteArticle(@PathVariable Long id) {
        Article article = articleService.getById(id);
        article.setStatus(-1);
        articleService.updateArticle(article);
        WebResponse<Object> response = WebResponse.getSuccessResponse(null);
        return response;
    }

    @RequestMapping(value = "/article/{id}", method = PUT, produces = "application/json")
    public WebResponse<Object> updateArticle(@PathVariable Long id, @RequestBody Article article) {
        article.setId(id);
        articleService.updateArticle(article);
        WebResponse<Object> response = WebResponse.getSuccessResponse(null);
        return response;
    }

    @RequestMapping(value = "/article/{id}", method = GET, produces = "application/json")
    public WebResponse<Article> getArticle(@PathVariable Long id) {
        Article article = articleService.getById(id);
        WebResponse<Article> response = WebResponse.getSuccessResponse(article);
        return response;
    }
}

  我们再来分析一下眼看段代码,这段代码和之前代码的区别在:

  (1)我们以的凡@RestController这个注解,而不是@Controller,不过这注解同样未是Spring
boot提供的,而是Spring MVC4蒙的供的诠释,表示一个支撑Restful的控制器。

  (2)这个仿佛中起三只URL映射是如出一辙的,即都是/article/{id},这当@Controller标识的类中是免允许出现的。这里的得经过method来进展分,produces的图是象征回去结果的品类是JSON。

  (3)@PathVariable这个注解,也是Spring
MVC提供的,其用意是表示该变量的价值是从访问路径中得。

  所以看来看去,这个代码还是同Spring boot没尽多的关系,Spring
boot也无非是供自动配置的功效,这为是Spring
boot用起来挺畅快的一个格外重要之故,因为它的侵入性非常深小,你基本感觉不顶其的有。

 

四、测试

  代码写了了,怎么测试?除了GET的艺术外,都未克一直通过浏览器来拜访,当然,我们可直接通过postman来发送各种http请求。不过我或比较支持通过单元测试类来测试各个艺术。这里我们尽管由此Junit来测试各个艺术:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
public class ArticleControllerTest {

    @Autowired
    private ArticleRestController restController;

    private MockMvc mvc;

    @Before
    public void setUp() throws Exception {
        mvc = MockMvcBuilders.standaloneSetup(restController).build();
    }

    @Test
    public void testAddArticle() throws Exception {
        Article article = new Article();
        article.setTitle("测试文章000000");
        article.setType(1);
        article.setStatus(2);
        article.setSummary("这是一篇测试文章");
        Gson gosn = new Gson();
        RequestBuilder builder = MockMvcRequestBuilders
                .post("/rest/article")
                .accept(MediaType.APPLICATION_JSON)
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .content(gosn.toJson(article));

        MvcResult result = mvc.perform(builder).andReturn();
        System.out.println(result.getResponse().getContentAsString());
    }

    @Test
    public void testUpdateArticle() throws Exception {
        Article article = new Article();
        article.setTitle("更新测试文章");
        article.setType(1);
        article.setStatus(2);
        article.setSummary("这是一篇更新测试文章");
        Gson gosn = new Gson();
        RequestBuilder builder = MockMvcRequestBuilders
                .put("/rest/article/1")
                .accept(MediaType.APPLICATION_JSON)
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .content(gosn.toJson(article));
        MvcResult result = mvc.perform(builder).andReturn();
    }

    @Test
    public void testQueryArticle() throws Exception {
        RequestBuilder builder = MockMvcRequestBuilders
                .get("/rest/article/1")
                .accept(MediaType.APPLICATION_JSON)
                .contentType(MediaType.APPLICATION_JSON_UTF8);
        MvcResult result = mvc.perform(builder).andReturn();
        System.out.println(result.getResponse().getContentAsString());
    }

    @Test
    public void testDeleteArticle() throws Exception {
        RequestBuilder builder = MockMvcRequestBuilders
                .delete("/rest/article/1")
                .accept(MediaType.APPLICATION_JSON)
                .contentType(MediaType.APPLICATION_JSON_UTF8);
        MvcResult result = mvc.perform(builder).andReturn();
    }
}

  执行结果这里就是无让大家贴了,大家产生趣味之说话可友善尝试一下。整个类要说明的接触还是格外少,主要这些事物还与Spring
boot没提到,支持这些操作的来头或者上同首稿子中关系的引入对应的starter:

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
</dependency>

  因为只要实践HTTP请求,所以这里运用了MockMvc,ArticleRestController通过注入的法实例化,不可知直接new,否则ArticleRestController就非能够经过Spring
IoC容器来管理,因而其负之其它类为无能为力正常注入。通过MockMvc我们就好轻松的贯彻HTTP的DELETE/PUT/POST等方式了。

五、总结

  本文讲解了而通过Spring
boot来兑现Restful的API,其实多数物还是Spring和Spring
MVC提供的,Spring
boot只是供自动配置的功效。但是,正是这种自动配置,为咱减了成千上万之付出与护卫工作,使我们能够益简约、高效之落实一个web工程,从而被咱能更进一步在意于事情自的开销,而不欲去关心框架的物。这篇稿子中我们关系了好经postman和junit的点子来访问Restful
接口,下篇文章我们见面介绍另外一种艺术来聘,有趣味之可以连续关心一下。

 

相关文章