jjzjj

SpringBoot ResponseEntity标识Http响应

fengyehongWorld 2023-04-22 原文

参考资料

  1. 使用spring ResponseEntity处理http响应
  2. 使用ResponseEntity处理API返回

目录


一. 说明

ResponseEntity用来标识整个Http响应,可以标识状态码,Head头部信息,以及响应体。

  • ResponseEntity的优先级高于@ResponseBody。
    在返回值不是ResponseEntity的情况下才去检查有没有@ResponseBody注解。
    如果响应类型是ResponseEntity可以不写@ResponseBody注解,便可返回JSON数据或其他类型的数据,如果同时使用ResponseEntity和@ResponseBody注解也不会报错。

  • ResponseEntity是在 org.springframework.http.HttpEntity 的基础上添加了http status code(http状态码)。作用是和@ResponseStatus@ResponseBody结合起来的功能一样的。

  • @ResponseBody可以直接返回JSON结果, @ResponseEntity不仅可以返回JSON结果,还可以返回自定义的HttpHeaders和HttpStatus。


二. ResponseEntity.ok().headers(响应头).body(响应体)

  • 可用于文件下载
  • 与直接向HttpServletResponse中写入OutputStream和header的效果相同
  • HttpServletResponse是servlet式的写法,而ResponseEntity是Springt式的写法
  • new ResponseEntity<>(响应体, 响应头, 状态码) 是非简写方式
  • ResponseEntity.ok().headers(响应头).body(响应体) 是简写方式
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;

import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

@GetMapping("/testResponseEntity1")
public ResponseEntity<byte[]> testResponseEntity1() throws Exception {

    // 读取本地的文件
    String filePath = "/temp/A110120119/测试文件.text";
    ClassPathResource readFile = new ClassPathResource(filePath);

    // 设置响应头,把文件名称放入响应头中,确保文件可下载
    HttpHeaders headers = new HttpHeaders();
    headers.set("Content-Disposition", "attachment;filename=" + URLEncoder.encode(readFile.getFilename(), "UTF-8"));
    // 设置内容类型为「application/octet-stream」二进制流
    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

    // 获取File对象
    File file = readFile.getFile();
    Path path = Paths.get(file.toURI());
    // 获取File对象的字节码文件
    byte[] bytes = Files.readAllBytes(path);

    /*
     * 表示返回一个字节码类型的响应
     * 同时设置了响应头和状态码
     * */
    if (ObjectUtils.isEmpty(readFile.getFilename())) {
        // 👉👉👉简写形式
        return ResponseEntity.ok().headers(headers).body(bytes);
    }

    // 👉👉👉非简写形式
    return new ResponseEntity<>(bytes, headers, HttpStatus.OK);
}

三. ResponseEntity.ok(响应内容)

  • 请求成功,直接把后台的数据响应给前台
@GetMapping("/testResponseEntity2")
public ResponseEntity<List<String>> testResponseEntity2() {

    List<String> list = Arrays.asList("1", "2");
    return ResponseEntity.ok(list);
}
  • 与下面这种写法功能相同
@GetMapping("/testResponseEntity2")
@ResponseBody
public List<String> testResponseEntity2() {

    List<String> list = Arrays.asList("1", "2");
    return list;
}

四. ResponseEntity<Void>

  • HttpStatus.NO_CONTENT状态码为204,表示服务器成功的处理了请求,但是没有返回任何内容
  • 多用于 更新删除 的时候,响应给前台一个状态码,表示操作成功。
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

@GetMapping("/testResponseEntity3")
public ResponseEntity<Void> testResponseEntity3(String param) {

    // ⏹http状态码 204 (无内容) 服务器成功处理了请求,但没有返回任何内容。
    if (ObjectUtils.isEmpty(param)) {
    	// ⏹简写方式
        return ResponseEntity.noContent().build();
    }
	
	// ⏹非简写方式
    return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}

五. ResponseEntity.status(状态码)

  • 用于向前台返回指定的状态码,还可以返回Header和响应内容
  • HttpStatus.CREATED201状态码表示请求成功并且服务器创建了新的资源。
@GetMapping("/testResponseEntity4")
public ResponseEntity<Void> testResponseEntity4() {
	
	// 向数据库中插入数据
	// ......
	
    // ⏹http状态码 201 (已创建) 请求成功并且服务器创建了新的资源。
    return ResponseEntity.status(HttpStatus.CREATED).build();
}

@GetMapping("/testResponseEntity5")
public ResponseEntity<String> testResponseEntity5(String param) {
	
	// 如果参数不存在就返回默认的图片url,并返回状态码201
    if (!ObjectUtils.isEmpty(param)) {
        return new ResponseEntity<>("默认的图片URL", HttpStatus.CREATED);
    }
	
	// 向数据库中插入图片,并返回能访问图片地址的url
	// ......
	// ⏹用于插入数据成功之后返回数据给前台

    // ⏹201 状态码,并返回图片的url
    return ResponseEntity.status(HttpStatus.CREATED).body("图片的url");
}

六. ResponseEntity.status(状态码).body(响应体)

  • HttpStatus.BAD_REQUEST表示状态码400,异常的请求。
@GetMapping("/testResponseEntity6")
public ResponseEntity<Map<String, Object>> testResponseEntity6(String param) {
	
	// 用来存放校验信息的Map
    Map<String, Object> map = new HashMap<>();
	
	// 进行参数校验
    if (param == null) {
    	// 参数为null,直接返回错误码400
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
    } else if ("".equals(param.trim())){
    	// 参数为空字符串,返回错误码400的同时,还返回错误信息
        map.put("errorMsg","参数为空");
        return ResponseEntity.badRequest().body(map);
    }

    // 200 状态码,并指定请求成功的响应体
    map.put("successMsg", "参数通过校验");
	
    return ResponseEntity.status(HttpStatus.OK).body(map);
    
    // 这种写法更加简单,本质上和上面是一种写法
    // return ResponseEntity.ok(map);
}

七. 前台ajax

$.ajax({
    url: `请求URL`,
    type: '请求方式',
    // data: JSON.stringify(param),
    // 向服务器发送的数据类型
    // contentType: 'application/json;charset=utf-8',
    // dataType: 'json',
    success: function (data, status, xhr) {

        // 请求成功的响应体
        console.log(data);

        // 请求成功的状态文字描述(success,nocontent等)
        console.log(status);

        // 请求成功的状态码(200,201,204等)
        const {
            status: stateCode
        } = xhr;
        console.log(stateCode);
    },
    error(xhr, status, error) {

        const {
            // 请求异常时的json格式响应体
            responseJSON,
            // 请求异常时的文本响应内容
            responseText,
            // 请求异常时的状态码
            status: stateCode
        } = xhr;
        console.log(responseJSON);
        console.log(responseText);
        console.log(stateCode);

        // 请求成功的状态文字描述(error等)
        console.log(status);
    }
});

有关SpringBoot ResponseEntity标识Http响应的更多相关文章

  1. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  2. ruby-on-rails - 每次我尝试部署时,我都会得到 - (gcloud.preview.app.deploy) 错误响应 : [4] DEADLINE_EXCEEDED - 2

    我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie

  3. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  4. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  5. ruby-on-rails - 如何从过时的 TZInfo 标识符中获取 Rails TimeZone 名称? - 2

    已经有一个问题回答了如何将“America/Los_Angeles”转换为“PacificTime(US&Canada)”。但是我想将“美国/太平洋”和其他过时的时区转换为RailsTimeZone。我无法在图书馆中找到任何可以帮助我完成此任务的东西。 最佳答案 来自RailsActiveSupport::TimeZonedocs:TheversionofTZInfobundledwithActiveSupportonlyincludesthedefinitionsnecessarytosupportthezonesdefinedb

  6. ruby-on-rails - Rails - 从命名路由中提取 HTTP 动词 - 2

    Rails中有没有一种方法可以提取与路由关联的HTTP动词?例如,给定这样的路线:将“users”匹配到:“users#show”,通过:[:get,:post]我能实现这样的目标吗?users_path.respond_to?(:get)(显然#respond_to不是正确的方法)我最接近的是通过执行以下操作,但它似乎并不令人满意。Rails.application.routes.routes.named_routes["users"].constraints[:request_method]#=>/^GET$/对于上下文,我有一个设置cookie然后执行redirect_to:ba

  7. ruby-on-rails - 在 Ruby on Rails 中发送响应之前如何等待多个异步操作完成? - 2

    在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.

  8. ruby-on-rails - Heroku 吃掉了我的自定义 HTTP header - 2

    我正在使用Heroku(heroku.com)来部署我的Rails应用程序,并且正在构建一个iPhone客户端来与之交互。我的目的是将手机的唯一设备标识符作为HTTPheader传递给应用程序以进行身份​​验证。当我在本地测试时,我的header通过得很好,但在Heroku上它似乎去掉了我的自定义header。我用ruby​​脚本验证:url=URI.parse('http://#{myapp}.heroku.com/')#url=URI.parse('http://localhost:3000/')req=Net::HTTP::Post.new(url.path)#boguspara

  9. ruby-on-rails - 使用 HTTP.get_response 检索 Facebook 访问 token 时出现 Rails EOF 错误 - 2

    我试图在我的网站上实现使用Facebook登录功能,但在尝试从Facebook取回访问token时遇到障碍。这是我的代码:ifparams[:error_reason]=="user_denied"thenflash[:error]="TologinwithFacebook,youmustclick'Allow'toletthesiteaccessyourinformation"redirect_to:loginelsifparams[:code]thentoken_uri=URI.parse("https://graph.facebook.com/oauth/access_token

  10. ruby - HTTP 请求中的用户代理,Ruby - 2

    我是Ruby的新手。我试过查看在线文档,但没有找到任何有效的方法。我想在以下HTTP请求botget_response()和get()中包含一个用户代理。有人可以指出我正确的方向吗?#PreliminarycheckthatProggitisupcheck=Net::HTTP.get_response(URI.parse(proggit_url))ifcheck.code!="200"puts"ErrorcontactingProggit"returnend#Attempttogetthejsonresponse=Net::HTTP.get(URI.parse(proggit_url)

随机推荐