Restful风格详解
SpringMVC Restful风格及实例、参数的转换
一、Restful风格
1、Restful风格的介绍
Restful 一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
REST(英文:Representational State Transfer,简称REST)描述了一个架构样式的网络系统,比如 web 应用程序。在目前主流的三种Web服务交互方案中,REST相比于SOAP(Simple Object Access protocol,简单对象访问协议)以及XML-RPC更加简单明了,无论是对URL的处理还是对Payload的编码,REST都倾向于用更加简单轻量的方法设计和实现。值得注意的是REST并没有一个明确的标准,而更像是一种设计的风格。
原则条件
REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。
Web 应用程序最重要的 REST 原则是,客户端和服务器之间的交互在请求之间是无状态的。从客户端到服务器的每个请求都必须包含理解请求所必需的信息。如果服务器在请求之间的任何时间点重启,客户端不会得到通知。此外,无状态请求可以由任何可用服务器回答,这十分适合云计算之类的环境。客户端可以缓存数据以改进性能。
在服务器端,应用程序状态和功能可以分为各种资源。资源是一个有趣的概念实体,它向客户端公开。资源的例子有:应用程序对象、数据库记录、算法等等。每个资源都使用 URI (Universal Resource Identifier) 得到一个唯一的地址。所有资源都共享统一的接口,以便在客户端和服务器之间传输状态。使用的是标准的 HTTP 协议,比如 GET、PUT、POST 和 DELETE。Hypermedia 是应用程序状态的引擎,资源表示通过超链接互联。
干货(简单明了):
Restful是一种设计风格。对于我们Web开发人员来说。就是使用一个url地址表示一个唯一的资源。然后把原来的请求参数加入到请求资源地址中。然后原来请求的增,删,改,查操作。改为使用HTTP协议中请求方式GET、POST、PUT、DELETE表示。
把请求参数加入到请求的资源地址中
原来的增,删,改,查。使用HTTP请求方式,POST、DELETE、PUT、GET分别一一对应。
二、如何学习restful风格,这里需要明确两点:
1、就是把传统的请求参数加入到请求地址是什么样子?
传统的方式是:
比如:http://ip:port/工程名/资源名?请求参数
举例:http://127.0.0.1:8080/springmvc/book?action=delete&id=1
restful风格是:
比如:http://ip:port/工程名/资源名/请求参数/请求参数
举例:http://127.0.0.1:8080/springmvc/book/1
请求的动作删除由请求方式delete决定
2、restful风格中请求方式GET、POST、PUT、DELETE分别表示查、增、改、删。
GET请求 对应 查询
http://ip:port/工程名/book/1 HTTP请求GET 表示要查询id为1的图书
http://ip:port/工程名/book HTTP请求GET 表示查询全部的图书POST请求 对应 添加
http://ip:port/工程名/book HTTP请求POST 表示要添加一个图书PUT请求 对应 修改
http://ip:port/工程名/book/1 HTTP请求PUT 表示要修改id为1的图书信息DELETE请求 对应 删除
http://ip:port/工程名/book/1 HTTP请求DELETE 表示要删除id为1的图书信息
3、SpringMVC中如何发送GET请求、POST请求、PUT请求、DELETE请求
我们知道发起GET请求和POST请求,只需要在表单的form标签中,设置method=”get” 就是GET请求。
设置form标签的method=”post”。就会发起POST请求。而PUT请求和DELETE请求。要如何发起呢。
要有post请求的form标签
在form表单中,添加一个额外的隐藏域_method=”PUT”或_method=”DELETE”
在web.xml中配置一个Filter过滤器org.springframework.web.filter.HiddenHttpMethodFilter(注意,这个Filter一定要在处理乱码的Filter后面)
<!-- 负责把隐藏域中的put,改为请求的put请求 -->
<filter><filter-name>HiddenHttpMethodFilter</filter-name><filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping><filter-name>HiddenHttpMethodFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
三、Restful风格的Controller如何实现
1、Controller实现代码
@Controller
public class RestfulController {@RequestMapping(value="/book/1",method=RequestMethod.GET)public String queryBookById() {System.out.println("根据id查询一本图书");return "/restful.jsp";}@RequestMapping(value="/book",method=RequestMethod.GET)public String queryBooks() {System.out.println("查询全部图书");return "/restful.jsp";}@RequestMapping(value="/book",method=RequestMethod.POST)public String addBook() {System.out.println("post请求 添加图书");return "/restful.jsp";}@RequestMapping(value="/book/1",method=RequestMethod.PUT)public String updateBook() {System.out.println("修改图书");return "/restful.jsp";}@RequestMapping(value="/book/1",method=RequestMethod.DELETE)public String deleteBook() {System.out.println("删除图书");return "/restful.jsp";}}
2、restful风格的jsp页面
```html
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title></head><body><a href="${ pageContext.request.contextPath }/book/1">查询一本图书</a><a href="${ pageContext.request.contextPath }/book">查询全部图书</a><form action="${ pageContext.request.contextPath }/book" method="post"><input type="submit" value="post添加图书"/></form><form action="${ pageContext.request.contextPath }/book/1" method="post"><!-- 表示这是put请求 --><input type="hidden" name="_method" value="PUT"/><input type="submit" value="put修改图书"/></form><form action="${ pageContext.request.contextPath }/book/1" method="post"><!-- 表示这是DELETE请求 --><input type="hidden" name="_method" value="DELETE"/><input type="submit" value="DELETE 删除图书"/></form></body>
</html>
四、Restful风格在高版本Tomcat中无法转发到jsp页面
在Tomcat8之后的一些高版本,使用restful风格访问然后转发到jsp页面。就会有如下的错误提示:
解决有两个方法:
1、在需要跳转去的页面中设置当前是错误页面isErrorPage=“true”
2、在put或delete方法中,使用重定向返回
五、@PathVariable 路径参数获取
前面我们已经知道如何编写和配置restful风格的请求和控制器。
那么 现在的问题是。如何接收restful风格请求的参数。比如前面的id值。
第一种情况,一个path参数:
/*** @PathVariable 注解表示取路径参数的值。<br/>* value="/book/{id}" 这里我们把id写成了{id}这是路径参数<br/>* @PathVariable(name="id") 这里的name属性表示把路径参数id的值注入到请求方法的id参数中*/
@RequestMapping(value="/book/{id}",method=RequestMethod.GET)
public String queryBookById(@PathVariable(name="id") Integer id) {System.out.println("根据id查询一本图书。 id ====>>>> " + id);return "/restful.jsp";
}
第二种情况,多个path参数:
/*** @PathVariable 注解表示取路径参数的值。<br/>* value="/book/{id}" 这里我们把id写成了{id}这是路径参数<br/>* @PathVariable(name="id") 这里的name属性表示把路径参数id的值注入到请求方法的id参数中<br/>* name的属性,表示取路径中哪个参数。默认情况下。参数名是name的值<br/>*/
@RequestMapping(value = "/book/{id}/{abc}", method = RequestMethod.GET)
public String queryBookById(@PathVariable(name = "id") Integer id,@PathVariable(name = "abc") String abc) {System.out.println("根据id查询一本图书。 id ====>>>> " + id);System.out.println("abc ===>>>> " + abc);return "/restful.jsp";
}
六、Restful风格实现的CRUD图书
把前面的传统请求方式的图书的CRUD换成刚刚讲的Restful风格的图书模块的CRUD。只需要修改页面端的请求方式和地址,以及服务器端Controller的接收。
1、Restful风格的crud工程的搭建
2、列表功能实现
Controller中的代码:
/*** 查询全部图书* * @return*/
@RequestMapping(value = "/book", method = RequestMethod.GET)
public ModelAndView list() {// 2 转发到book/bookList.jsp页面ModelAndView modelAndView = new ModelAndView("bookList");// 1 查询全部的图书,保存到request域中modelAndView.addObject("bookList", bookService.queryBooks());return modelAndView;
}
请求方式:
图书管理
3、删除功能实现
Controller中的代码:
@RequestMapping(value = "/book/{id}",method=RequestMethod.DELETE)
public ModelAndView delete(@PathVariable(name="id") Integer id) {// 调用BookService删除图书bookService.deleteBookById(id);// 重定向 到图书列表管理页面return new ModelAndView("redirect:/book");
}
到web.xml中去配置 支持restful风格的Filter过滤器
<!-- 配置支持restful的Filter过滤器 -->
<filter><filter-name>HiddenHttpMethodFilter</filter-name><filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping><filter-name>HiddenHttpMethodFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
bookList.jsp中,需要修改提交的方式:
<td><!-- 表示啥也不干 --><a class="deleteA" itemId="${ book.id }" href="javascript:void(0);">删除</a>、<a href="${ pageContext.request.contextPath }/book/getBook?id=${book.id}">修改</a><form id="item_${ book.id }" action="${ pageContext.request.contextPath }/book/${book.id}" method="post"><input type="hidden" name="_method" value="DELETE" /></form></td>
<script type="text/javascript">$(function(){// 给删除绑定单击事件$("a.deleteA").click(function(){// 提示用户确认操作if ( confirm("你确定要删除【" + $(this).parent().parent().find("td:first").text() + "】吗?")){// 点击删除,提交form表单// submit(function(){})是给表单的提交事件添加功能// submit() 让表单提交$("#item_" + $(this).attr("itemId")).submit();}});});
</script>
4、添加功能实现
@RequestMapping(value = "/book", method = RequestMethod.POST)
public ModelAndView add(Book book) {// 1 调用bookService保存bookService.addBook(book);// 2 重定向回图书列表管理页面return new ModelAndView("redirect:/book");
}
bookEdit.jsp页面请求方式需要调整:
5、更新功能实现
更新图书分为两个步骤:
查询需要更新的图书,填充到更新页面
提交请求,发送数据给服务器更新保存修改。
5.1、查询需要更新的图书,填充到更新页面
@RequestMapping(value = "/book/{id}", method = RequestMethod.GET)
public ModelAndView getBook(@PathVariable(name = "id") Integer id) {ModelAndView modelAndView = new ModelAndView();// 模型 是需要修改的图书===调用BookService.queryBookByIdmodelAndView.addObject("book", bookService.queryBookById(id));// 设置跳转的页面modelAndView.setViewName("bookEdit");return modelAndView;
}
5.2、提交请求,发送数据给服务器更新保存修改。
@RequestMapping(value = "/book/{id}",method=RequestMethod.PUT)
public ModelAndView update(@PathVariable Integer id, Book book) {// 保存修改bookService.updateBook(book);// 跳到图书列表管理页面return new ModelAndView("redirect:/book");
}
bookEdit.jsp页面的修改
<center><h3>添加图书</h3><c:if test="${ not empty requestScope.book }"><form action="${ pageContext.request.contextPath }/book/${requestScope.book.id}" method="post"></c:if><c:if test="${ empty requestScope.book }"><form action="${ pageContext.request.contextPath }/book" method="post"></c:if><c:if test="${ not empty requestScope.book }"><input type="hidden" name="_method" value="PUT"/></c:if><input type="hidden" name="id" value="${ requestScope.book.id }"/><table><tr><td>书名</td><td><input name="name" type="text" value="${ requestScope.book.name }"/></td></tr><tr><td>作者</td><td><input name="author" type="text" value="${ requestScope.book.author }" /></td></tr><tr><td>价格</td><td><input name="price" type="text" value="${ requestScope.book.price }" /></td></tr><tr><td>销量</td><td><input name="sales" type="text" value="${ requestScope.book.sales }" /></td></tr><tr><td>库存</td><td><input name="stock" type="text" value="${ requestScope.book.stock }"/></td></tr><tr><td align="center" colspan="2"><input type="submit" /></td></tr></table></form>
</center>
6、字符集的Filter一定要在Restful的Filter前面
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
forceRequestEncoding
true
forceResponseEncoding
true
CharacterEncodingFilter
/*
<!-- 配置支持restful的Filter过滤器 -->
<filter><filter-name>HiddenHttpMethodFilter</filter-name><filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping><filter-name>HiddenHttpMethodFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
七、SpringMVC标签库
1、搭建SpringMVC开发环境
2、创建对象模型Person对象
public class Person {private Integer id;private String name;private Date birthDate;private String email;private BigDecimal salary;
PersonController控制器代码:
@Controller
public class PersonController {@RequestMapping(value="/toAddPerson")public String toAddPerson(Map<String, Object> map) {System.out.println("经过Controller控制器");map.put("person", new Person());//return "/person/addPerson.jsp";}@RequestMapping("/addPerson")public String addPerson(Person person) {System.out.println("添加用户:" + person);return "/index.jsp";}}
addPerson.jsp页面
<body>添加用户<!-- action 提交的地址method 请求的方式modelAttribute SpringMVC的标签库,需要跟隐含模型中一个对象相对应modelAttribute="person"一定要和隐含模型中的key相对应也就是Person用户模块,隐含模型中的key是person,表单的modelAttribute属性值也是person如果是图书模块,隐含模型中的key是book,表单的modelAttribute属性值也是book--><form:form action="${ pageContext.request.contextPath }/addPerson" modelAttribute="person" method="post"><!-- 每个input 的path属性值要跟模型的属性名相对应 -->id <form:input path="id"/><br/>name <form:input path="name"/><br/>birthDate <form:input path="birthDate"/><br/>email <form:input path="email"/><br/>salary <form:input path="salary"/><br/><input type="submit" /></form:form>
</body>
八、自定义参数转换器
1、WebDataBinder类介绍
在SpringMVC中有WebDataBinder类。这个类专门用来负责将请求参数类型转换。以及请求参数数据验证,错误信息绑定等功能。
WebDataBinder会调用各种类型转换器,得到属性相对应类型的值。然后再注入到属性中(调用setXxxx方法)
在WebDataBinder类中有三个组件分别处理三种不同的功能。
conversionService 负责处理参数类型转换。把请求的参数转换成为Controller中的方法参数值。
converters 在ConversionService组件中需要各种类型转换器,在conversionService组件中需要依赖于各种转换器类去实现转换工作。
validators 负责验证传入的参数值是否合法。bindingResult 负责接收验证后的错误信息。
下图展示了WebDataBinder、ConversionService、Converter的关系。
如果我们要自定义请求参数的类型转换器。需要实现
org.springframework.core.convert.converter.Converter<S,T>接口。
然后注入到ConversionService组件中。最后再将ConversionService注入到WebDataBinder中。
创建ConversionService组件,需要配置
org.springframework.format.support.FormattingConversionServiceFactoryBean对象。
2、自定义String到java.util.Date类型转换器
public class MyStringToDate implements Converter<String, Date> {private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");/*** convert方法负责转换<br/>* source客户端发送过来的值<br/>* Date转换之后的结果*/@Overridepublic Date convert(String source) {if (source == null) {return null;}source = source.trim();try {// 调用转换器return sdf.parse(source);} catch (ParseException e) {e.printStackTrace();throw new IllegalArgumentException("Invalid java.util.Date value '" + source + "'");}}}
到ApplicationContext.xml中去配置,并使用
<!-- 配置一个类型转换器组件 --><bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"><!-- 把你自定义的类型转换器注入到ConversionService组件中 --><property name="converters"><set><bean class="com.webcode.converter.MyStringToDate"/></set></property></bean><!-- springMVC的标配 --><mvc:default-servlet-handler/><!-- SpringMVC中的高级功能conversion-service="conversionService" 将你自己配置的类型转换器,注入到SpringMVC的系统中--><mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
3、@DateTimeFormat注解类型转换器
我们也可以像上面。在类的Date类型的属性上标上注解。就可以自动将String类型转换成为Date数据
pattern属性表示 日期的格式。最完成的格式是:yyyy-MM-dd hh:mm:ss
yyyy 表示年份必须是4位MM 表示月份必须是2位dd 表示日期必须是2位hh 表示小时,必须是2位mm 表示分钟,必须是2位ss 表示秒钟,必须是2位
九、较验器----参数的有效性验证Validate----Hibernate
在JavaEE6.0中,定义了很多的验证规范。这些规范统称为:JSR303验证规范。
而这些规范的实现。我们使用现在业内比较认可的Hibernate-Validate验证
@AssertTrue 用于boolean字段,该字段只能为true @AssertFalse该字段的值只能为false@CreditCardNumber对信用卡号进行一个大致的验证@DecimalMax只能小于或等于该值@DecimalMin只能大于或等于该值@Digits(integer=,fraction=)检查是否是一种数字的整数、分数,小数位数的数字@Email检查是否是一个有效的email地址@Future检查该字段的日期是否是属于将来的日期@Length(min=,max=)检查所属的字段的长度是否在min和max之间,只能用于字符串@Max该字段的值只能小于或等于该值@Min该字段的值只能大于或等于该值@NotNull不能为null@NotBlank不能为空,检查时会将空格忽略@NotEmpty不能为空,这里的空是指空字符串@Null检查该字段为空@Past检查该字段的日期是在过去@Pattern(regex=,flag=)被注释的元素必须符合指定的正则表达式@Range(min=,max=,message=)被注释的元素必须在合适的范围内@Size(min=, max=)检查该字段的size是否在min和max之间,可以是字符串、数组、集合、Map等@URL(protocol=,host,port)
检查是否是一个有效的URL,如果提供了protocol,host等,则该URL还需满足提供的条件
使用Hiberante的验证器较验数据分以下步骤:
入Hibernate验证的jar包
hibernate-validator-5.0.0.CR2.jar
hibernate-validator-annotation-processor-5.0.0.CR2.jarclassmate-0.8.0.jarjboss-logging-3.1.1.GA.jarvalidation-api-1.1.0.CR1.jar2. 在实体bean对象的属性上使用校验的注解
3. 在Controller的方法参数上,给需要验证的bean对象。添加验证注解@Valid,以及在验证对象后跟一个BindingResult 对象用于接收验证的错误信息
/*** @Valid当前方法的person参数我要做数据较验<br/>* BindingResult用来接收前面一个对象的错误信息*/
@RequestMapping("/addPerson")
public String addPerson(@Valid Person person, BindingResult personBindingResult) {if (personBindingResult.hasErrors()) {personBindingResult.getAllErrors().forEach(System.out::println);return "/person/addPerson.jsp";}System.out.println("添加用户:" + person);return "/index.jsp";
}
4. 在SpringMVC的form表单字段后,使用<form:errors path="字段名" />输出对应字段的错误信息
<form:form action="${ pageContext.request.contextPath }/addPerson" modelAttribute="person" method="post"><!-- 每个input 的path属性值要跟模型的属性名相对应 -->id:<form:input path="id"/><form:errors path="id" /><br/>name:<form:input path="name"/><form:errors path="name" /><br/>birthDate:<form:input path="birthDate"/><form:errors path="birthDate" /><br/>email:<form:input path="email"/><form:errors path="email" /><br/>salary:<form:input path="salary"/><form:errors path="salary" /><br/><input type="submit" />
</form:form>
十、自定义错误信息的回显
1、错误消息规则:
这是校验错误的key规则:
格式1: Pattern.bean.property
说明: 校验格式.隐含模型包.属性名
示例: Email.person.email person对象的email属性验证Email格式失败格式2: Pattern.property
说明: 校验格式.属性名
示例: Email.email 任何对象的email属性验证Email格式失败格式3: Pattern.javaType
说明: 校验格式.字段数据类型
示例: Email.java.lang.String 任何String类型的属性验证Email格式失败key4: Pattern
说明: 校验格式
示例: Email 校验Email格式失败
参数转换失败的key规则:
格式1: typeMismatch.bean.property
说明: 类型不匹配.隐含模型包.属性名
示例: typeMismatch.person.birthDate person对象的birthDate属性转换失败格式2: typeMismatch.property
说明: 类型不匹配.属性名
示例: typeMismach.birthDate 任何对象的birthDate属性转换失败格式3: typeMismatch.javaType
说明: 类型不匹配.字段数据类型
示例: typeMismach.java.util.Date Java.util.Date类型转换失败格式4: typeMismatch
说明: 类型不匹配
示例: typeMismach 字段类型转换失败
2、在源码目录下配置错误信息的属性配置文件
Past=\u8FD9\u4E2A\u65F6\u95F4\u4E0D\u5BF9
typeMismatch.java.util.Date=\u975E\u6CD5\u8F93\u5165
Length=\u957F\u5EA6\u5FC5\u987B\u662F 5 \u5230 12 \u4F4D
Email=\u4E0D\u597D\u597D\u5E72\u6D3B\u660E\u5929\u6CA1\u996D\u5403
Min=\u4E0D\u80FD\u5C0F\u4E8E 3000
typeMismatch.salary=\u5DE5\u8D44\u8F93\u5165\u4E0D\u5BF9
3、在application.xml中配置属性信息
<!-- org.springframework.context.support.ResourceBundleMessageSource可以做加载properties属性配置文件使用,还可以做国际化-->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"><!-- basename配置文件名,但不带后缀--><property name="basename" value="errors"/>
</bean>使用占位符{数字}
对于SpringMvc模型来说,传值是框架做的工作。我们只需要写好数字即可。
第一个参数Spring传入的是验证的属性名
Restful风格详解相关推荐
- RESTful 风格详解
一. 什么是Restful风格 1.1 概念 RESTFUL是一种网络应用程序的设计风格和开发方式,基于HTTP,可以使用 XML 格式定义或 JSON 格式定义.最常用的数据格式是JSON.由于JS ...
- Rest架构风格详解
Rest架构风格详解 何为架构风格? 设计模式 架构模式 架构风格 Rest架构风格 客户端-服务器(Client-Server, CS) 无状态(Stateless) 缓存(Cache) 统一接口 ...
- REST风格详解(很多其他人经验总结加上我自己的归纳到一起了,从推出到使用)
文章目录 一.REST演化过程小故事 Level 0 - 面向前台 Level 1 - 面向资源 Level 2 - 打上标签 Level 3 - 完美服务 二.REST详解 传统API接口 REST ...
- RESTful的详解
文章目录 1. RESTful是什么? 2. 传统风格与RESTful风格对比 2.1 传统风格 2.1 RESTful风格 3. RESTful的实现 3.1 GET.POST方式 3.1.1 创建 ...
- RESTful架构详解【转】
1. 什么是REST REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移. 它首次出现在2000年Roy Fielding的 ...
- RESTful 架构详解
1. 什么是REST REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移. 它首次出现在2000年Roy Fielding的 ...
- RESTful 架构详解设计模式一种约束
1. 什么是REST REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移. 它首次出现在2000年Roy Fielding的 ...
- springmvc教程--RESTful支持详解
RESTful支持 1.1 需求 RESTful方式商品修改.商品查询. 1.2 添加DispatcherServlet的rest配置 <servlet><servlet-name& ...
- iOS 键盘风格详解UIKeyboardType
一.键盘风格 UIKit框架支持8种风格键盘. [java] view plaincopy print? typedef enum { UIKeyboardTypeDefault, ...
- go 时间格式风格详解
为什么80%的码农都做不了架构师?>>> 一段代码 这里有一段代码 play 更能解说 layout. 可以看出, go 自动识别并转换 time 字符串是完全可能的. tim ...
最新文章
- Matlab图像处理基本函数(1)
- WPF 故事板动画示例
- JDBC连接MySQL数据库代码模板
- Cloud for Customer的事件处理队列
- ieee754浮点数转换工具_关于JS浮点数运算不精确的原因和解决方案
- java web快速入门_Web安全快速入门
- 文件上传(Vue+Springboot)
- Ubuntu - 新建管理员用户
- mysql8导入不同schme_新特性解读 | MySQL 8.0.22 任意格式数据导入
- 从ext2文件系统上读出超级块
- groovy+mysql数据库_groovy - groovy连接数据库
- 计算机基础进制转换(二进制、八进制、十进制、十六进制)
- 北京开通企业登记“e窗通”服务平台 开办企业可3天完成
- Praat脚本-004 | 替换标注内容
- php采集今日头条出现问题,PHP采集今日头条内容页时,解析页面上的JS转为json
- 史上最详细的新浪广告系统技术架构优化历程
- 【Paper】DTWSequence Analysis
- vue中实现电子签名
- delphi 两行代码实现合并多张图片生成mp4视频
- masory 刷新约束方法 释义
热门文章
- 服务器iscsi如何修复,服务器重启后,iSCSI目标卡住了重新连接
- SpringCloud 第十二章 Gateway新一代网关
- matlab二极管伏安特性,基于Matlab对Spice二极管特性受温度影响的研究
- 大数据开发基础入门与项目实战(一)Java SE之4.方法和封装
- 获取并处理中文维基百科语料
- 8086中寻址方式详解
- 【Linux学习笔记】关于ubuntu开机菜单栏和任务栏不见了的有效解决方法
- 一键开关电路设计(一)
- html怎么设置火狐ie兼容模式,火狐浏览器兼容模式如何设置?火狐浏览器兼容模式设置方法分享...
- html5 页面整体居中,html5标题居中 DIV布局怎么在页面水平居中