Spring MVC代码实例系列-08:Spring MVC通过@RestController和@PathVariable构建RESTFul风格的Web服务

超级通道 :Spring MVC代码实例系列-绪论

本章主要记录如何通过@RestController@PathVariable构建RESTFul风格的Web服务。涉及到的知识点有:
- RESTRepresentational State Transfer 表现层状态转化,一种软件架构风格、设计风格。
- @RestController:一种控制器,@Controller@ResponseBody的结合,此控制器内的方法返回的不是View,而是对象。
- @PathVariable通过获取URL上以模板{}标记的参数。
- @ModelAttribute 设置Model里的属性,本例中用来模拟数据库。

1.说明

1.1.REST简介

REST,全称为Representational State Transfer,翻译为表现层状态转化。以我的理解就是:

REST:通过URL名词定位资源,通过HTTP请求方式(GET/POST/PUT/PATCH/DELETE)描述操作。

示例:

序号 URL 请求方式 实际URL 解释
1 localhost:8080/student/{id} GET [GET] localhost:8080/student/1 获得id=1的student信息
2 localhost:8080/student/{id} DELETE [DELETE] localhost:8080/student/1 删除id=1的student信息
3 localhost:8080/student/ GET [GET] localhost:8080/student/ 获取所有的student信息
4 localhost:8080/student/ DELETE [DELETE] localhost:8080/student/ 删除所有的student信息
5 localhost:8080/student/ POST [POST] localhost:8080/student/ 添加一个新的student信息
6 localhost:8080/student/ PUT [PUT] localhost:8080/student/ 替换一个student信息
7 localhost:8080/student/ PATCH [PATCH] localhost:8080/student/ 修改一个student信息

说明:
1. PUT倾向于修改一个对象的全部信息,我理解为所有的属性不论是否为空,全部修改。
2. PATCH倾向于修改一个对象的部分属性,我理解为所有的属性值只修改不为空的字段。
3. REST是一种风格,一种规范,而不是协议。可以只用PUT,不用PATCH。

1.2.@RestController

@RestController = @Controller + @ResponseBody,表示此控制器的每一个方法返回域对象代替一个视图。
@Controller + @ResponseBody的写法

@Controller
public class DemoController{
    @RequestMapping
    @ResponseBody
    public User getUser(){}
}

@RestController的写法

@RestController
public class DemoController{
    @RequestMapping
    public User getUser(){}
}

1.3.@PathVariable

@PathVariable用于获取URL上的模板参数

@RestController
public class DemoController{
    @GetMapping("/student/{id}")
    public User getUser(@PathVariable String id){}
}

2.实例

2.1.目录结构

src
\---main
    \---java
    |   \---pers
    |       \---hanchao
    |           \---hespringmvc
    |               \---restful
    |                   \---Question.java
    |                   \---MyJsonResult.java
    |                   \---QuestionController.java
    \---webapp
        \---restful
        |   \---question.jsp.jsp
        \---WEB-INF
        |   \---spring-mvc-servlet.xml
        |   \---web.xml
        \---index.jsp

2.2.Question.java

package pers.hanchao.hespringmvc.restful;

/**
 * 

题目对象

* @author hanchao 2018/1/21 11:30 **/
public class Question { /** 试题id */ private Integer id; /** 题目 */ private String title; /** 分数 */ private Integer score; /** 答案 */ private String answer; public Question(){} public Question(Integer id, String title, Integer score, String answer) { this.id = id; this.title = title; this.score = score; this.answer = answer; } //toString //setter and getter }

2.3.MyJsonResult.java

package pers.hanchao.hespringmvc.restful;

import java.util.Arrays;
import java.util.List;

/**
 * 

用来封装返回值

* @author hanchao 2018/1/21 11:29 **/
public class MyJsonResult { /** 状态码 */ private String code = "1"; /** 状态消息 */ private String message = "success!"; /** 返回消息 */ private Question[] questions; public MyJsonResult(){ } public MyJsonResult(Question[] data){ this.questions = data; } public void setCodeAndMessage(String code,String message){ this.code = code; this.message = message; } //toString //setter and getter }

2.4.QuestionController.java

package pers.hanchao.hespringmvc.restful;

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

/**
 * 

Restful风格URL的简单实例

* @author hanchao 2018/1/21 11:30 **/
@RestController @RequestMapping("restful") public class QuestionController { /** *

定义一个Question的列表,用来模拟数据集

* @author hanchao 2018/1/20 23:15 **/
@ModelAttribute public Question[] init(Model model){ Question[] questions = new Question[10]; String title = "题目"; int score = 90; String answer = "答案"; for(int i = 0 ; i < 10 ; i ++){ questions[i] = new Question(i,title + i,score + i,answer + i); } model.addAttribute("questions",questions); return questions; } /** *

[GET]获取一个题目

* @author hanchao 2018/1/20 22:08 **/
@GetMapping("/question/{id}") public MyJsonResult getQuestion(@PathVariable Integer id, @ModelAttribute("questions") Question[] questions) { MyJsonResult myJsonResult = new MyJsonResult(); //查找题目,找到则返回 for (Question question : questions){ if (id.equals(question.getId())){ myJsonResult.setQuestions(new Question[]{question}); break; } } return myJsonResult; } /** *

[GET]获取全部的题目

* @author hanchao 2018/1/20 23:50 **/
@GetMapping("/question/") public MyJsonResult getAll(@ModelAttribute("questions") Question[] questions) { MyJsonResult myJsonResult = new MyJsonResult(questions); return myJsonResult; } /** *

[POST]新增一个题目

* @author hanchao 2018/1/21 10:10 **/
@PostMapping("/question/") public MyJsonResult postQuestion(@RequestBody Question question,@ModelAttribute("questions") Question[] questions) { MyJsonResult myJsonResult = new MyJsonResult(); boolean isExist = false; //查找题目,如果找到,则表明已经存在,不能再添加 for (int i = 0 ; i < questions.length; i ++){ Question qi = questions[i]; if (question.getId().equals(qi.getId())){ myJsonResult.setCodeAndMessage("0","改题目已经存在,不能再添加!"); isExist = true; break; } } //如果题目不存在,则新增题目 if (!isExist){ Question[] newQuestions = new Question[questions.length + 1]; newQuestions[0] = question; System.arraycopy(questions,0,newQuestions,1,questions.length); myJsonResult.setQuestions(newQuestions); } return myJsonResult; } /** *

[PUT]替换一个题目(全部修改)

* @author hanchao 2018/1/21 10:44 **/
@PutMapping("/question/") public MyJsonResult putQuestion(@RequestBody Question question,@ModelAttribute("questions") Question[] questions) { MyJsonResult myJsonResult = new MyJsonResult(); boolean isExist = false; //查找题目,如果找到,直接替换全部属性 for (int i = 0 ; i < questions.length; i ++){ Question qi = questions[i]; if (question.getId().equals(qi.getId())){ questions[i] = question; myJsonResult.setQuestions(questions); break; } } //如果找不到,则提示不存在此题目 if (!isExist){ myJsonResult.setCodeAndMessage("0","不存在此题目,无法替换!"); } return myJsonResult; } /** *

[PATCH]修改一个题目,修改不为空的属性值

* @author hanchao 2018/1/21 11:15 **/
@PatchMapping("/question/") public MyJsonResult patchQuestion(@RequestBody Question question,@ModelAttribute("questions") Question[] questions) { MyJsonResult myJsonResult = new MyJsonResult(); boolean isExist = false; //查找题目,如果找到,替换不为空的属性 for (int i = 0 ; i < questions.length; i ++){ Question qi = questions[i]; if (question.getId().equals(qi.getId())){ if (null != question.getTitle() && !"".equals(question.getTitle())){ questions[i].setTitle(question.getTitle()); } if (null != question.getAnswer() && !"".equals(question.getAnswer())){ questions[i].setAnswer(question.getAnswer()); } if (null != question.getScore() && !"".equals(question.getScore())){ questions[i].setScore(question.getScore()); } myJsonResult.setQuestions(questions); break; } } //如果找不到,则提示不存在此题目 if (!isExist){ myJsonResult.setCodeAndMessage("0","不存在此题目,无法替换!"); } return myJsonResult; } /** *

[DELETE]删除一个题目

* @author hanchao 2018/1/21 11:21 **/
@DeleteMapping("/question/{id}") public MyJsonResult deleteQuestion(@PathVariable Integer id,@ModelAttribute("questions") Question[] questions ) { MyJsonResult myJsonResult = new MyJsonResult(); boolean isExist = false; //查找题目,如果找到,直接删除 for (int i = 0 ; i < questions.length; i ++){ Question qi = questions[i]; if (id.equals(qi.getId())){ questions[i] = null; myJsonResult.setQuestions(questions); break; } } //如果找不到,则提示不存在此题目 if (!isExist){ myJsonResult.setCodeAndMessage("0","不存在此题目,无法删除!"); } return myJsonResult; } /** *

[DELETE]删除所有题目

* @author hanchao 2018/1/21 11:24 **/
@DeleteMapping("/question/") public MyJsonResult deleteAllQuestion() { MyJsonResult myJsonResult = new MyJsonResult(); return myJsonResult; } }

2.5.question.jsp.jsp

<%--
  Created by IntelliJ IDEA.
  User: hanchao
  Date: 2018/1/20
  Time: 22:40
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>题目信息管理title>
    <style type="text/css">
        div{margin: 5px 5px; }
        .div-left {float: left;margin: 5px 5px;}
        .div-text-center {text-align:center; border:1px solid #96c2f1; background:#eff7ff;}
        textarea{border:1px solid #9bdf70;background:#f0fbeb}
        .in-text{width: 30px;}
    style>
head>
<body>
<div class="div-left">
    <textarea id="message" cols="50" rows="50">textarea>
div>
<div class="div-left">
    <div class="div-text-center">
        <label>题目id:label><input class="in-text" type="text" id="id" value="1"/><input type="button" value="查询一个(GET)" onclick="question('GET')"/>
    div>
    <div class="div-text-center">
        <label>题目列表label><input type="button" value="查询所有(GET)" onclick="questions('GET')"/>
    div>
    <div class="div-text-center">
        <table style="text-align: right">
            <tr>
                <td><label>idlabel>td>
                <td><input id="new_id" type="text" value="1"/> td>
            tr>
            <tr>
                <td><label>titlelabel>td>
                <td><input id="new_title" type="text" value="新题目"/> td>
            tr>
            <tr>
                <td><label>scorelabel>td>
                <td><input id="new_score" type="text" value="100"/> td>
            tr>
            <tr>
                <td><label>answerlabel>td>
                <td><input id="new_answer" type="text" value="新答案"/> td>
            tr>
            <tr>
                <td colspan="2"><input type="button" value="新增(POST)" onclick="question1('POST')"> td>
            tr>
            <tr>
                <td><input type="button" value="替换(PUT)" onclick="question1('PUT')"> td>
                <td><input type="button" value="修改(PATCH)" onclick="question1('PATCH')"> td>
            tr>
        table>
    div>
    <div class="div-text-center">
        <label>题目id:label><input class="in-text" type="text" id="del_id" value="1"/>
        <input type="button" value="删除一个(DELETE)" onclick="question('DELETE')">
    div>
    <div class="div-text-center">
        <label>删除所有label><td><input type="button" value="删除所有(DELETE)" onclick="questions('DELETE')">
    div>
div>
body>
<script type="text/javascript" src="../static/jquery-3.2.1.min.js">script>
<script type="text/javascript">
    /**
     * 获取一个题目:[GET]/restful/question/{id}
     */
    /**
     * 删除一个题目:[DELETE]/restful/question/{id}
     */
    function question(type) {
        $.ajax({
            type:type,
            url:"/restful/question/" + $("#id").val(),
            contentType:"application/json;charset=utf-8",
            success:function (data) {
                console.log(data);
                var html = "url[" + type + "]:/restful/question/" + $("#id").val() + "\n\nresult:\n" + JSON.stringify(data, null, 4);
                $("#message").html(html);
            }
        });
    }

    /**
     * 获取全部题目:[GET]/restful/question/
     */
    /**
     * 删除全部题目:[DELETE]/restful/question/
     */
    function questions(type) {
        $.ajax({
            type:type,
            url:"/restful/question/",
            contentType:"application/json;charset=utf-8",
            success:function (data) {
                console.log(data);
                var html = "url[" + type + "]:/restful/question/\n\nresult:\n" + JSON.stringify(data, null, 4);
                $("#message").html(html);
            }
        });
    }

    /**
     * 新增一个题目:[POST]/restful/question/
     */
    /**
     * 替换一个题目:[PUT]/restful/question/
     */
    /**
     * 修改一个题目:[PATCH]/restful/question/
     */
    function question1(type) {
        $.ajax({
            type:type,
            url:"/restful/question/",
            data:JSON.stringify({
                id:$("#new_id").val(),
                title:$("#new_title").val(),
                score:$("#new_score").val(),
                answer:$("#new_answer").val()
            }),
            contentType:"application/json;charset:utf-8",
            success:function (data) {
                console.log(data);
                var html = "url[" + type + "]:/restful/question/\n\nresult:\n" + JSON.stringify(data,null,4);
                $("#message").html(html);
            }
        });
    }
script>
html>

2.6.result

2.6.1.查询一个

Spring MVC代码实例系列-08:Spring MVC通过@RestController和@PathVariable构建RESTFul风格的Web服务_第1张图片

2.6.2.查询全部

Spring MVC代码实例系列-08:Spring MVC通过@RestController和@PathVariable构建RESTFul风格的Web服务_第2张图片

2.6.3.新增

Spring MVC代码实例系列-08:Spring MVC通过@RestController和@PathVariable构建RESTFul风格的Web服务_第3张图片

2.6.4.替换

Spring MVC代码实例系列-08:Spring MVC通过@RestController和@PathVariable构建RESTFul风格的Web服务_第4张图片

2.6.5.修改

Spring MVC代码实例系列-08:Spring MVC通过@RestController和@PathVariable构建RESTFul风格的Web服务_第5张图片

2.6.6.删除一个

Spring MVC代码实例系列-08:Spring MVC通过@RestController和@PathVariable构建RESTFul风格的Web服务_第6张图片

2.6.7.删除全部

Spring MVC代码实例系列-08:Spring MVC通过@RestController和@PathVariable构建RESTFul风格的Web服务_第7张图片

你可能感兴趣的:(Spring-MVC合集,REST,Spring,MVC学习实例)