Spring中RESTful请求与响应

RESTful请求

REST全称是Representational State Transfer,如果一个架构符合REST的约束条件和原则,我们就称它为RESTful架构。可以唯一标识和定位资源,对于该URL标识的资源做何种操作是由Http方法决定的。请求方法有4种,get、post、put、delete分别对应获取资源,添加资源,更新资源及删除资源。

每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表格名对应。一般来说,数据库中的表都是同种记录的"集合"(collection),所以API中的名词也应该使用复数。
例如有一个博客系统,包含了博客、评论等信息,它的路径如下所示:

    https://api.myblog.com/blogs		有关博客的url
    https://api.myblog.com/blogs/ID/comments		有关评论的url

根据不同的HTTP动作对博客进行不同的操作:

    GET /blogs/ID:获取指定某篇博客的内容
    PUT /blogs/ID:更新某篇指定博客
    DELETE /blogs/ID:删除某篇博客
    GET /blogs/ID/comments:获取某篇博客的评论
    DELETE /blogs/ID/comments/ID:删除某篇博客的某个评论

可以在地址后面通过?附加参数来对获取的内容进行过滤

	GET /blogs/ID/comments?limit=10:指定返回10条评论
	GET /blogs/ID/comments?page=2&per_page=10:指定返回第2页的评论,每页10条记录

在Spring MVC中,可以用一个Controller类来对应一个资源集合,然后在其中定义对不同类型请求的响应方法。

例如首先定义BlogController类,通过注解@RequestMapping("/blogs")代表响应/blogs相关的资源请求
之后分别用注解@GetMapping@PostMapping@DeleteMapping来定义对不同类型请求的响应方法

@Controller
@RequestMapping("/blogs")
public class BlogController {
	//阅读博客
    @GetMapping("{id}")
    public String getBlogById(@PathVariable("id") Long id, Model model) {
    ...
    }

	//保存博客
	@PostMapping("{id}")
    public ResponseEntity<Response> saveBlog(@PathVariable("id") Long blogId, @RequestBody Blog blog) {
    ...
    }

	//删除博客
	@DeleteMapping("{id}")
    public ResponseEntity<Response> deleteBlog(@PathVariable("id") Long blogId) {
    ...
    }
}

在前端进行发起请求时,浏览器默认使用GET请求页面,使用POST提交表单,除此之外,还可以在发起Ajax请求时指定请求方法

	// 删除博客
    $(".blog-content-container").on("click", ".blog-delete-blog", function () {
        $.ajax({
            url: blogUrl,
            type: 'DELETE',				//指定请求的方法          
            success: function (data) {
            
            }
        });
    });

返回响应

ModelAndView

对于GET请求,我们可以使用ModelAndView的方式返回数据,即用model来保存数据,用view表示返回的页面。
其中Model对象可以从方法参数中传入,然后返回页面字符串
也可以自定义ModelAndView 对象,然后向其中添加数据和指定页面

	@GetMapping("/blogs/{id}")
    public String getBlogById(@PathVariable("id") Long id, Model model) {
        model.addAttribute("blogModel",blogService.getBlogById(id));	//保存数据
        return "/userspace/blog";	//返回页面视图
    }
	
	@GetMapping("/blogs/edit")
    public ModelAndView createBlog() {
    	ModelAndView mav = new ModelAndView();
        mav.addObject("blog", new Blog(null, null, null));		//添加数据
        mav.setViewName("/userspace/blogedit");		//指定页面
        return mav;
    }

ResponseEntity

ResponseEntity标识整个http相应:状态码、头部信息以及相应体内容。因此我们可以使用其对http响应实现完整配置。

如下所示返回一个简单的ResponseEntity响应,其包括String类型的内容"Hello World!",自定义的头部headers,和状态码HttpStatus.OK

@GetMapping("/hello")
ResponseEntity<String> hello() {
	HttpHeaders headers = new HttpHeaders();
    headers.add("Custom-Header", "foo");
    return new ResponseEntity<>("Hello World!", headers, HttpStatus.OK);
}

ResponseEntity提供了两个内嵌的构建器接口: HeadersBuilder 和其子接口 BodyBuilder。因此我们能通过ResponseEntity的静态方法直接访问。如下所示为一些常见的状态

BodyBuilder accepted();
BodyBuilder badRequest();
BodyBuilder created(java.net.URI location);
HeadersBuilder<?> noContent();
HeadersBuilder<?> notFound();
BodyBuilder ok();

我们可以直接将内容放到状态码对应的构造器内返回

@GetMapping("/hello")
ResponseEntity<String> hello() {
    return ResponseEntity.ok("Hello World!");
}

也可以使用方法链的形式设置状态码并返回内容

@GetMapping("/customHeader")
ResponseEntity<String> customHeader() {
    return ResponseEntity.ok()
        .header("Custom-Header", "foo")
        .body("Custom header set");
}

以上返回的ResponseEntity内容都是String类型ResponseEntity<String>,还可以自定义返回内容的类型,例如定义返回类Response用于统一返回数据的格式 ,其中success用于标识操作是否成功,message表示返回信息,body存放返回数据

public class Response {
    private boolean success;    //操作是否成功
    private String message;     //操作返回的信息
    private Object body;        //处理的返回内容
	
    public Response(boolean success, String message, Object body) {
        this.success = success;
        this.message = message;
        this.body = body;
    }
	
	...//getter & setter
}

public ResponseEntity<Response> deleteBlog(@PathVariable("username") String username,@PathVariable("id") Long id) {
        blogService.removeBlog(id);

        String redirectUrl = "/blog/u/" + username + "/blogs";
        Response res = new Response(true, "删除成功", redirectUrl);		//返回自定义的Response类
        return ResponseEntity.ok().body(res);
    }
}

请求Response返回给前端后,在ajax中通过回调函数的data获取返回数据,此时可以通过data.success判断操作是否成功,data.message获取操作信息,data.body获取返回的数据

$(".blog-content-container").on("click", ".blog-delete-blog", function () {
    $.ajax({
        url: blogUrl,
        type: 'DELETE',				    
        success: function (data) {
            if (data.success) {					//判断操作是否成功           
                window.location = data.body;	//处理返回的数据
            } else {
                toastr.error(data.message);		//弹出返回的信息
            }
        }
    });
});
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值