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解释
1localhost:8080/student/{id}GET[GET] localhost:8080/student/1获得id=1的student信息
2localhost:8080/student/{id}DELETE[DELETE] localhost:8080/student/1删除id=1的student信息
3localhost:8080/student/GET[GET] localhost:8080/student/获取所有的student信息
4localhost:8080/student/DELETE[DELETE] localhost:8080/student/删除所有的student信息
5localhost:8080/student/POST[POST] localhost:8080/student/添加一个新的student信息
6localhost:8080/student/PUT[PUT] localhost:8080/student/替换一个student信息
7localhost: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;

/**
 * <p>题目对象</p>
 * @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;

/**
 * <p>用来封装返回值</p>
 * @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.*;

/**
 * <p>Restful风格URL的简单实例</p>
 * @author hanchao 2018/1/21 11:30
 **/
@RestController
@RequestMapping("restful")
public class QuestionController {

    /**
     * <p>定义一个Question的列表,用来模拟数据集</p>
     * @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;
    }

    /**
     * <p>[GET]获取一个题目</p>
     * @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;
    }

    /**
     * <p>[GET]获取全部的题目</p>
     * @author hanchao 2018/1/20 23:50
     **/
    @GetMapping("/question/")
    public MyJsonResult getAll(@ModelAttribute("questions") Question[] questions) {
        MyJsonResult myJsonResult = new MyJsonResult(questions);
        return myJsonResult;
    }

    /**
     * <p>[POST]新增一个题目</p>
     * @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;
    }

    /**
     * <p>[PUT]替换一个题目(全部修改)</p>
     * @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;
    }

    /**
     * <p>[PATCH]修改一个题目,修改不为空的属性值</p>
     * @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;
    }

    /**
     * <p>[DELETE]删除一个题目</p>
     * @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;

    }

    /**
     * <p>[DELETE]删除所有题目</p>
     * @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>id</label></td>
                <td><input id="new_id" type="text" value="1"/> </td>
            </tr>
            <tr>
                <td><label>title</label></td>
                <td><input id="new_title" type="text" value="新题目"/> </td>
            </tr>
            <tr>
                <td><label>score</label></td>
                <td><input id="new_score" type="text" value="100"/> </td>
            </tr>
            <tr>
                <td><label>answer</label></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.查询一个

这里写图片描述

2.6.2.查询全部

这里写图片描述

2.6.3.新增

这里写图片描述

2.6.4.替换

这里写图片描述

2.6.5.修改

这里写图片描述

2.6.6.删除一个

这里写图片描述

2.6.7.删除全部

这里写图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值