.Net之接口小知识

目的

通过一个简单的项目,在原来的文章基础上完善一下常用的几种WebApi编写方式以及请求方式,一方面是用于给我一个前端朋友用来学习调用接口,另一方面让我测试HttpClient的一些效果。

本文示例代码环境:vs2022、net6

准备

新创建了一个.Net WebAPI程序,安装组件

<ItemGroup><PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="11.0.0" /><PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.1" /><PackageReference Include="Swashbuckle.AspNetCore" Version="6.3.1" /><PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="6.3.1" />
</ItemGroup>

ConfigureServices配置NewtonsoftJson以及Automapper和操作数据库代码(为了省事,删除了一些不影响当前效果的代码)

public void ConfigureServices(IServiceCollection services)
{services.AddControllers().AddNewtonsoftJson();services.AddEndpointsApiExplorer();services.AddSwaggerGen(c =>{c.SwaggerDoc("v1", new OpenApiInfo { Title = "MyWebApi", Version = "v1" });});//注入AutoMapperservices.AddAutoMapper(Assembly.GetExecutingAssembly().DefinedTypes.Where(t => typeof(Profile).GetTypeInfo().IsAssignableFrom(t.AsType())).Select(t => t.AsType()).ToArray());
}

注意:在Net core3.0以后,微软移除了Newtonsoft.Json,而使用了System.Text.Json,所以依赖于Newtonsoft.Json的组件将不可用,需要安装 Microsoft.AspNetCore.Mvc.NewtonsoftJson 包

因为仅仅作为演示,所以我只是新增一个控制器,里面包含了get、post、put、patch、delete几种类型的接口。这里先不贴代码,一点一点看。通过一个用户的添加、修改、删除作为一个演示的流程。

记得配置允许跨域请求,要不js请求会因为跨域问题而报错。详情看此处

数据来源就是控制器里面的一个静态变量,格式如下

public class UserDto
{public long UserId { get; set; }public string Name { get; set; }public string Sex { get; set; }
}

静态变量如下

private static readonly List<UserDto> _userDtoList = Enumerable.Range(0, 100).Select(t => new UserDto{Name = "张三" + t,Sex = "男",UserId = 6974150586715897857 + t}).ToList();

后端请求的方法我使用的是HttpClient,并且做成了一个公共类,部分需要用到的如下

public class HttpClientHelper: IHttpHelper
{private readonly System.Net.Http.HttpClient _client;/// <summary>/// 构造函数/// </summary>/// <param name="httpClientFactory"></param>public HttpClientHelper(IHttpClientFactory httpClientFactory){_client = httpClientFactory.CreateClient();}private void VerifyParam(string url, string jwtToken, IDictionary<string, string> headers){_client.DefaultRequestHeaders.Clear();if (string.IsNullOrWhiteSpace(url)){throw new ArgumentNullException("url不能为null");}if (!string.IsNullOrWhiteSpace(jwtToken)){_client.DefaultRequestHeaders.Add("Authorization", $"Bearer {jwtToken}");}if (headers?.Count > 0){foreach (var (key, value) in headers){_client.DefaultRequestHeaders.Add(key, value);}}}private static async Task<T> ConvertResponseResult<T>(HttpResponseMessage httpResponse){//确保成功完成,不是成功就返回具体错误信息httpResponse.EnsureSuccessStatusCode();var resStr = await httpResponse.Content.ReadAsStringAsync();if (typeof(T) == typeof(string))return (T)Convert.ChangeType(resStr, typeof(string));return JsonConvert.DeserializeObject<T>(resStr);}
}

操作

请求头传递token只是为了演示请求头传递参数的写法,token为伪值

GET

从web服务检索数据。传递参数的本质是url字符串拼接,Request-Head头部传递,Request-Body中不能传递(严格点说不建议,因为我使用Apifox等工具可以在body中传值,swagger会提示 Request with GET/HEAD method cannot have body)

Query格式

编写用户id查询用户信息接口

[HttpGet("user/details")]
public UserDto GetUserDetails(long userId)
{if (!_userDtoList.Any(t => t.UserId == userId))throw new ParameterException("未找到用户标识");return _userDtoList.Find(t => t.UserId == userId);
}

前端请求

$(function () {$.ajax({type: "get",url: "http://localhost:5000/api/HttpSample/user/details?userId=6974150586715897857",headers: { "Authorization": "Bearer 123456" },contentType: "application/json",success: function (data, status) {if (status == "success") {console.log(JSON.stringify(data));}}});var postdata = { userId: "6974150586715897857" };$.ajax({type: "get",headers:{"Authorization":"Bearer 123456"},url: "http://localhost:5000/api/HttpSample/user/details",data: postdata,success: function (data, status) { if (status == "success") {console.log(JSON.stringify(data));}  }});
});

后端请求

var token = "123456";//此处token是伪值
var result = await _httpHelper.GetAsync<ResultModel<UserDto>>("http://localhost:5000/api/HttpSample/user/details?userId=6974150586715897857", token);

这里的_httpHelper是注入的IHttpHelper(下面其他的方法一样),对应的GetAsync为

public async Task<T> GetAsync<T>(string url, string jwtToken = "", IDictionary<string, string> headers = null)
{VerifyParam(url, jwtToken, headers);var response = await _client.GetAsync(url).ConfigureAwait(false);return await ConvertResponseResult<T>(response).ConfigureAwait(false);
}

接口工具请求

url:http://localhost:5000/api/HttpSample/user/details?userId=6974150586715897857

并且再请求头增加:Authorization,值为Bearer xxxx

返回结果如下

cdc838d3af1b12a4db12287956a6605b.png
img

POST

在web服务上创建新的数据项。约定用于向服务端提交数据操作,请求时候参数放在参数FromBody传递

Json格式

演示添加用户操作

请求类

public class UserDto
{public long UserId { get; set; }public string Name { get; set; }public string Sex { get; set; }
}

接口代码示例

[HttpPost("user/add")]
public bool Add([FromBody] UserDto request)
{if (_userDtoList.Any(t => t.UserId == request.UserId))throw new ParameterException("用户标识已经存在");Console.WriteLine(DateTime.Now + "   " + HttpContext.Request.Headers["Authorization"].FirstOrDefault());_userDtoList.Add(request);return true;
}

前端请求

$(function () {var param = { userId: "8974150586715897867", name: "老八", sex: "女" };$.ajax({type: "post",dataType: 'json',contentType: "application/json",headers: { "Authorization": "Bearer 123456" },url: "http://localhost:5000/api/HttpSample/user/add",data: JSON.stringify(param),success: function (data) {if (status == "success") {console.log(JSON.stringify(data));}}});
});

后端请求

var token = "123456";//此处token是伪值
var url = "http://localhost:5000/api/HttpSample/user/add";var usedto = new UserDto
{UserId = 123456,Name = "李四",Sex = "女"
};var result = await _httpHelper.PostAsync<ResultModel<bool>>(url, usedto, token);public async Task<T> PostAsync<T>(string url, object data, string jwtToken = "", IDictionary<string, string> headers = null)
{VerifyParam(url, jwtToken, headers);var jsonData = data is string ? data.ToString() : JsonConvert.SerializeObject(data);using var content = new StringContent(jsonData ?? string.Empty, Encoding.UTF8, "application/json");var response = await _client.PostAsync(url, content).ConfigureAwait(false);return await ConvertResponseResult<T>(response).ConfigureAwait(false);
}

接口工具请求

传递参数格式为json格式,请求头部默认添加:"Content-Type", "application/json"

12c4437fd6470eb5d6f5ab5c214d5b54.png
img

x-www-form-unlencoded格式

更新用户姓名

[HttpPost("user/updatename")]
public bool UpdateName([FromForm] long userId, [FromForm] string name)
{var entity = _userDtoList.Find(t => t.UserId == userId);if (entity is null)throw new ParameterException("用户标识不存在");entity.Name = name;return true;
}

前端请求

$(function () {var postdata = { userId: "6974150586715897857", name: "赵六" };$.ajax({type: "post",headers: { "Authorization": "Bearer 123456" },url: "http://localhost:5000/api/HttpSample/user/updatename",data: postdata,success: function (data, status) {if (status == "success") {console.log(JSON.stringify(data));}}});
});

后端请求

var token = "123456";//此处token是伪值
var url = "http://localhost:5000/api/HttpSample/user/updatename";
var dic = new Dictionary<string, string>
{{ "userId","6974150586715897857"},{ "name","王五"}
};
var result = await _httpHelper.PostFormDataAsync<ResultModel<bool>>(url, dic, token);public async Task<T> PostFormDataAsync<T>(string url, Dictionary<string, string> data, string jwtToken = "", IDictionary<string, string> headers = null)
{VerifyParam(url, jwtToken, headers);var httpContent = new FormUrlEncodedContent(data);var response = await _client.PostAsync(url, httpContent).ConfigureAwait(false);return await ConvertResponseResult<T>(response).ConfigureAwait(false);
}

接口工具请求

选择post请求,参数在Body,然后选择x-www-form-unlencoded格式。

41303d6d0113af3944c72d658f6ad98b.png
img

Form-data格式

模拟上传用户头像操作

[HttpPost("user/uploadImg")]
public string Upload([FromForm] IFormFile img, [FromForm] long userId)
{if (img is null)throw new ParameterException("用户头像不能为null");Console.WriteLine(HttpContext.Request.Headers["Authorization"].FirstOrDefault());var entity = _userDtoList.Find(t => t.UserId == userId);if (entity is null)throw new ParameterException("用户标识不存在");return img.FileName;
}

注意:当你上传大于30000000字节长度的文件时候,需要修改上传文件的默认限制

前端请求

$(function () {$("#tijiao").click(function () {//logoimg是<input type="file" id="logoimg"" />var files = $("#logoimg").prop('files'); //获取到文件列表var formData = new FormData();formData.append("userId", "6974150586715897857");formData.append("img", files[0], "1122.jpg");//图片文件流console.log(formData);$.ajax({type: 'post',url: "http://localhost:5000/api/HttpSample/user/uploadImg",headers: {"Authorization": "Bearer 123456"},mimeType: "multipart/form-data",processData: false,contentType: false,data: formData,success: function (data) {//后端Httpclient请求成功后返回过来的结果console.log(data);}});});
});

后端请求

var url = "http://localhost:5000/api/HttpSample/user/uploadImg";var formData = new MultipartFormDataContent();var bytes = System.IO.File.ReadAllBytes("D:\\Downloads\\11111.jpg");
var byteContent = new ByteArrayContent(bytes);
byteContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("form-data")
{Name = "img",FileName = "111.jpg"
};
formData.Add(byteContent);// 写法一
formData.Add(new StringContent("6974150586715897857"), "userId");// 写法二
var byteContent2 = new ByteArrayContent(Encoding.UTF8.GetBytes("天气"));
byteContent2.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("form-data")
{Name = "name",
};
formData.Add(byteContent2);var headerDic = new Dictionary<string, string>
{{ "Authorization","Bearer 123456"},
};var result = await _httpHelper.PostFormDataAsync<ResultModel<string>>(url, formData, headerDic);public async Task<T> PostFormDataAsync<T>(string url, MultipartFormDataContent data, IDictionary<string, string> headers = null)
{VerifyParam(url, "", headers);var result = await _client.PostAsync(url, data).ConfigureAwait(false);return await ConvertResponseResult<T>(result);
}

接口工具请求

选择Body=>form-data

442b97ef3e80051774a12b0114241b04.png
img

PUT

更新web服务上的数据项。

Json格式

更新用户信息

[HttpPut("user/update")]
public bool Update(UserDto userDto)
{if (userDto is null)throw new ParameterException("参数不能为空");Console.WriteLine(DateTime.Now + "    " + HttpContext.Request.Headers["Authorization"].FirstOrDefault());var currUser = _userDtoList.Find(t => t.UserId == userDto.UserId);if (currUser is null)throw new ParameterException("用户标识不存在");currUser.Name = userDto.Name;currUser.Sex = userDto.Sex;return true;
}

前端请求

$(function () {var param = { userId: "6974150586715897859", name: "老八", sex: "女" };$.ajax({type: "put",dataType: 'json',contentType: "application/json",headers: { "Authorization": "Bearer 123456" },url: "http://localhost:5000/api/HttpSample/user/update",data: JSON.stringify(param),success: function (data, status) {if (status == "success") {console.log(JSON.stringify(data));}}});
});

后端请求

var token = "123456";//此处token是伪值var usedto = new UserDto
{UserId = 6974150586715897859,Name = "老八",Sex = "女"
};var url = "http://localhost:5000/api/HttpSample/user/update";var result = await _httpHelper.PutAsync<ResultModel<bool>>(url, usedto, token);
return JsonConvert.SerializeObject(result);public async Task<T> PutAsync<T>(string url, object data, string jwtToken = "", IDictionary<string, string> headers = null)
{VerifyParam(url, jwtToken, headers);var jsonData = data is string ? data.ToString() : JsonConvert.SerializeObject(data);using var content = new StringContent(jsonData ?? string.Empty, Encoding.UTF8, "application/json");var response = await _client.PutAsync(url, content).ConfigureAwait(false);return await ConvertResponseResult<T>(response).ConfigureAwait(false);
}

接口工具请求

URL:http://localhost:5000/api/HttpSample/user/update

参数传递:Body=>json

262d545306d12cf61b9f270ebb88a94e.png
img

DELETE

删除web服务上的数据项。

Query格式

删除用户信息

[HttpDelete("user")]
public bool Delete(long userId)
{var entity = _userDtoList.Find(t => t.UserId == userId);if (entity is null)throw new ParameterException("用户标识不存在");Console.WriteLine(DateTime.Now + "    " + HttpContext.Request.Headers["Authorization"].FirstOrDefault());_userDtoList.Remove(entity);return true;
}

前端请求

$(function () {$.ajax({type: "DELETE",url: "http://localhost:5000/api/HttpSample/user?userId=6974150586715897861",headers: { "Authorization": "Bearer 123456" },success: function (data, status) {if (status == "success") {console.log(JSON.stringify(data));}}});
});

后端请求

var token = "123456";//此处token是伪值
var url = "http://localhost:5000/api/HttpSample/user?userId=6974150586715897862";var result = await _httpHelper.DeleteAsync<ResultModel<bool>>(url, token);public async Task<T> DeleteAsync<T>(string url, string jwtToken = "", IDictionary<string, string> headers = null)
{VerifyParam(url, jwtToken, headers);var response = await _client.DeleteAsync(url).ConfigureAwait(false);return await ConvertResponseResult<T>(response).ConfigureAwait(false);
}

接口工具请求

URL:http://localhost:5000/api/HttpSample/user?userId=6974150586715897859

fc4b77707795155246d583ce18e2df6c.png
img

Patch

通过描述有关如何修改项的一组说明,更新web服务上的数据项。

请求格式如下:

[{"op" : "replace", "path" : "/PassWord", "value" : "222222"}]

op属性指示操作的类型,path属性指示要更新的元素,value属性提供新值。

add:添加属性或数组元素。对于现有属性:设置值。

remove:删除属性或数组元素。

replace:替换操作

为了支持该请求方式,需要安装nuget包Microsoft.AspNetCore.Mvc.NewtonsoftJson。

参考文档:https://docs.microsoft.com/zh-cn/aspnet/core/web-api/jsonpatch?view=aspnetcore-6.0

Json格式

在此用于更新数据

[HttpPatch("user/update2/{userId}")]
public UserDto Update2([FromRoute] long userId, JsonPatchDocument<UserDto> jsonPatch, [FromServices] IMapper mapper)
{var entity = _userDtoList.Find(t => t.UserId == userId);if (entity is null)throw new ParameterException("用户标识无效");var dto = mapper.Map<UserDto>(entity);jsonPatch.ApplyTo(dto, ModelState);var user = _userDtoList.Find(t => t.UserId == userId);mapper.Map(dto, user);return user;
}

前端请求

演示根据用户id去更新用户的姓名

$(function () {var par = [{ "op": "replace", "path": "/name", "value": "老六" }];$.ajax({type: "Patch",url: "http://localhost:5000/api/HttpSample/user/update2/6974150586715897857",headers: { "Authorization": "Bearer 123456" },contentType: "application/json",data: JSON.stringify(par),success: function (result) {console.log(result);}});
});

后端请求

var token = "123456";//此处token是伪值
var url = "http://localhost:5000/api/HttpSample/user/update2/6974150586715897859";
var content = "[{\"op\":\"replace\",\"path\":\"/name\",\"value\":\"小七七\"}]";
var result = await _httpHelper.PatchAsync<ResultModel<UserDto>>(url, content, token);public async Task<T> PatchAsync<T>(string url, object data, string jwtToken = "", IDictionary<string, string> headers = null)
{VerifyParam(url, jwtToken, headers);var jsonData = data is string ? data.ToString() : JsonConvert.SerializeObject(data);using var content = new StringContent(jsonData ?? string.Empty, Encoding.UTF8, "application/json");var response = await _client.PatchAsync(url, content).ConfigureAwait(false);return await ConvertResponseResult<T>(response).ConfigureAwait(false);
}

接口工具请求

参数传递:Body=>json

60190503e0c042d112a6a214187bf3bf.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/282776.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

你所不知道的setTimeout

JavaScript提供定时执行代码的功能&#xff0c;叫做定时器&#xff08;timer&#xff09;&#xff0c;主要由setTimeout()和setInterval()这两个函数来完成。它们向任务队列添加定时任务。初始接触它的人都觉得好简单&#xff0c;实时上真的如此么&#xff1f;这里记载下&#…

android 特效绘图,Android绘图机制与处理技巧——Android图像处理之图形特效处理...

Android变形矩阵——Matrix对于图像的图形变换&#xff0c;Android系统是通过矩阵来进行处理的&#xff0c;每个像素点都表达了其坐标的X、Y信息。Android的图形变换矩阵是一个3x3的矩阵&#xff0c;如下图所示&#xff1a;72F0CAC1-14FB-40F8-A430-8F542B09DC4E.png当使用变换…

WPF 使用 DrawingContext 绘制刻度条

WPF 使用 DrawingContext 绘制刻度条控件名&#xff1a;Ruler作者&#xff1a;WPFDevelopersOrg原文链接&#xff1a; https://github.com/WPFDevelopersOrg/WPFDevelopers框架使用大于等于.NET40&#xff1b;Visual Studio 2022;项目使用 MIT 开源许可协议&#xff1b;定义I…

个人中心的html,个人中心.html

&#xfeff;个人中心$axure.utils.getTransparentGifPath function() { return resources/images/transparent.gif; };$axure.utils.getOtherPath function() { return resources/Other.html; };$axure.utils.getReloadPath function() { return resources/reload.html; };…

使用CMD命令修改Windows本地账户密码

2019独角兽企业重金招聘Python工程师标准>>> 一、以管理员身份运行cmd命令 二、在命令提示符窗口中输入命令符&#xff1a;net user Administrator 123&#xff0c;然后按回车键“Enter”。(Administrator是你的win8用户名&#xff0c;123是重新设置的密码。) ​ 三…

java线程安全问题原因及解决办法

1.为什么会出现线程安全问题 计算机系统资源分配的单位为进程&#xff0c;同一个进程中允许多个线程并发执行&#xff0c;并且多个线程会共享进程范围内的资源&#xff1a;例如内存地址。当多个线程并发访问同一个内存地址并且内存地址保存的值是可变的时候可能会发生线程安全问…

html语言怎么添加图片,我想问你一下,你是怎么在html中插入本地图片?非常感谢...

满意答案小蜜蜂手工2013.10.03采纳率&#xff1a;43% 等级&#xff1a;12已帮助&#xff1a;7929人img{float:right}在下面的段落中&#xff0c;我们添加了一个样式为 float:right 的图像。结果是这个图像会浮动到段落的右侧。This is some text. This is some text. This i…

EntityFrameworkCore上下文如何实现继承?

【导读】如果我们存在基础设施服务和其他服务&#xff0c;我们会定义属于基础设施服务的上下文以及其他服务的上下文&#xff0c; 而且会独立部署&#xff0c;此时其他服务需要使用基础服务&#xff0c;我们都会暴露基础服务接口给到其他服务调用&#xff0c;这也是常规操作若在…

美观又实用,10 款强大的开源 Javascript 图表库

2019独角兽企业重金招聘Python工程师标准>>> 随着发展&#xff0c;现代 Web 设计在改善体验和功能的同时&#xff0c;对于美观的追求也越来越高&#xff0c;可视化、交互式、动态等元素和效果似乎已成为标配。 以下是为开发者推荐的 10 款开源 Javascript 图表库&am…

EF CORE 7 RC1 发布

原文链接&#xff1a;https://devblogs.microsoft.com/dotnet/announcing-ef7-rc1/[1]原文作者&#xff1a;Jeremy Likness翻译&#xff1a;沙漠尽头的狼(谷歌翻译加持)Entity Framework Core 7 (EF7) Release Candidate 1 已发布&#xff01;该团队专注于解决缺陷、小幅改进以…

微服务太分散?使用Fundebug集中式bug监控

摘要&#xff1a; 微服务日志分散&#xff0c;可以使用Fundebug的异常监控将它们集中起来。 当一个项目复杂到一定程度&#xff0c;功能越来越多&#xff0c;随之对应的模块也越来越多。 如果都放在一个大的项目下面&#xff0c;共同开发&#xff0c;整合发布&#xff0c;那么会…

html404页面怎么添加,网站要如何设置自定义404页面?

之前我们讲述过网站设置404页面对于优化或是用户体验的重要意义&#xff0c;大家可移步到《网站为什么要设置404页面》查看&#xff0c;今天我们讲解的是网站要如何设置自己的404页面。现在大多数空间商都有了404设置的功能&#xff0c;我们可将404页面上传至空间里面&#xff…

ASP.NET Core在.NET 7 RC1中的更新

原文链接&#xff1a;https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-7-rc-1/[1]原文作者&#xff1a;Daniel Roth翻译&#xff1a;沙漠尽头的狼(谷歌翻译加持).NET 7 Release Candidate 1 (RC1) 现已推出[2]&#xff0c;其中包括对 ASP.NET Core 的许…

html5 tab菜单切换页面,11个常用的jQuery TAB切换菜单源码及制作教程

11个常用的jQuery TAB切换菜单源码及制作教程SponsorTAB切换式菜单可以方便为我们减少很多网页布局空间&#xff0c;而且用jQuery的话可以加入一些动画效果&#xff0c;比如渐变&#xff0c;向左右滑动等&#xff0c;提升一定的用户体验&#xff0c;所以TAB菜单目前来说是很流行…

ConcurrentDictionary字典操作竟然不全是线程安全的?

好久不见&#xff0c;马甲哥封闭居家半个月&#xff0c;记录之前遇到的一件小事。ConcurrentDictionary<TKey,TValue>绝大部分api都是线程安全的[1]&#xff0c;唯二的例外是接收工厂函数的api&#xff1a;AddOrUpdate、GetOrAdd&#xff0c;这两个api不是线程安全的&…

HTML中弹窗中加入图片,javascript里怎么实现点击图片弹出对话框?

JavaScript中可以使用document.getElementsByTagName方法后去img标签&#xff0c;然后遍历所有img标签并为其添加点击事件实现点击弹出对话框。JavaScript实现点击图片弹出对话框&#xff1a;img {width: 500px;height: 300px;}//获取所有的img标签var imgObjs document.getEl…

Dcloud课程2 什么是Dcloud

Dcloud课程2 什么是Dcloud 一、总结 一句话总结&#xff1a;DCloud提供了一套快速开发应用的跨平台技术方案。 1、DCloud的产品架构&#xff1f; MUI(H5)HBuilder 2、什么是MUI&#xff1f; 最接近原生体验的移动App的UI框架。 3、什么是H5&#xff1f; html5功能增强标准 二、…

html5 轮询自动刷新数据,后台调用exe,前端定时轮询调用结果

前提使用asp.net core 2.1前端使用vueui使用element-ui前端发送请求用Axios新建asp.net core程序1.jpg修改Index.html{Layout null;}test{{ msg }}发送请求打开记事本// 创建 Vue 实例&#xff0c;得到 ViewModelvar vm new Vue({el: #app,data: {msg: 准备发送请求打开exe},…

洛谷 P2951 [USACO09OPEN]捉迷藏Hide and Seek

题目描述 Bessie is playing hide and seek (a game in which a number of players hide and a single player (the seeker) attempts to find them after which various penalties and rewards are assessed; much fun usually ensues). She is trying to figure out in which…

linux下tomcat开启远程调试

1.center下&#xff0c;在startup.sh文件首行中添加如下语句 declare -x CATALINA_OPTS"-server -Xdebug -Xnoagent -Djava.compilerNONE -Xrunjdwp:transportdt_socket,servery,suspendn,address8000"(不要换行&#xff0c;要在同一行)Ubuntu下&#xff0c;在catali…