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风格详解相关推荐

  1. RESTful 风格详解

    一. 什么是Restful风格 1.1 概念 RESTFUL是一种网络应用程序的设计风格和开发方式,基于HTTP,可以使用 XML 格式定义或 JSON 格式定义.最常用的数据格式是JSON.由于JS ...

  2. Rest架构风格详解

    Rest架构风格详解 何为架构风格? 设计模式 架构模式 架构风格 Rest架构风格 客户端-服务器(Client-Server, CS) 无状态(Stateless) 缓存(Cache) 统一接口 ...

  3. REST风格详解(很多其他人经验总结加上我自己的归纳到一起了,从推出到使用)

    文章目录 一.REST演化过程小故事 Level 0 - 面向前台 Level 1 - 面向资源 Level 2 - 打上标签 Level 3 - 完美服务 二.REST详解 传统API接口 REST ...

  4. RESTful的详解

    文章目录 1. RESTful是什么? 2. 传统风格与RESTful风格对比 2.1 传统风格 2.1 RESTful风格 3. RESTful的实现 3.1 GET.POST方式 3.1.1 创建 ...

  5. RESTful架构详解【转】

    1. 什么是REST REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移. 它首次出现在2000年Roy Fielding的 ...

  6. RESTful 架构详解

    1. 什么是REST REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移. 它首次出现在2000年Roy Fielding的 ...

  7. RESTful 架构详解设计模式一种约束

    1. 什么是REST REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移. 它首次出现在2000年Roy Fielding的 ...

  8. springmvc教程--RESTful支持详解

    RESTful支持 1.1 需求 RESTful方式商品修改.商品查询. 1.2 添加DispatcherServlet的rest配置 <servlet><servlet-name& ...

  9. iOS 键盘风格详解UIKeyboardType

    一.键盘风格 UIKit框架支持8种风格键盘. [java] view plaincopy print? typedef enum { UIKeyboardTypeDefault,           ...

  10. go 时间格式风格详解

    为什么80%的码农都做不了架构师?>>>    一段代码 这里有一段代码 play 更能解说 layout. 可以看出, go 自动识别并转换 time 字符串是完全可能的. tim ...

最新文章

  1. Matlab图像处理基本函数(1)
  2. WPF 故事板动画示例
  3. JDBC连接MySQL数据库代码模板
  4. Cloud for Customer的事件处理队列
  5. ieee754浮点数转换工具_关于JS浮点数运算不精确的原因和解决方案
  6. java web快速入门_Web安全快速入门
  7. 文件上传(Vue+Springboot)
  8. Ubuntu - 新建管理员用户
  9. mysql8导入不同schme_新特性解读 | MySQL 8.0.22 任意格式数据导入
  10. 从ext2文件系统上读出超级块
  11. groovy+mysql数据库_groovy - groovy连接数据库
  12. 计算机基础进制转换(二进制、八进制、十进制、十六进制)
  13. 北京开通企业登记“e窗通”服务平台 开办企业可3天完成
  14. Praat脚本-004 | 替换标注内容
  15. php采集今日头条出现问题,PHP采集今日头条内容页时,解析页面上的JS转为json
  16. 史上最详细的新浪广告系统技术架构优化历程
  17. 【Paper】DTWSequence Analysis
  18. vue中实现电子签名
  19. delphi 两行代码实现合并多张图片生成mp4视频
  20. masory 刷新约束方法 释义

热门文章

  1. 服务器iscsi如何修复,服务器重启后,iSCSI目标卡住了重新连接
  2. SpringCloud 第十二章 Gateway新一代网关
  3. matlab二极管伏安特性,基于Matlab对Spice二极管特性受温度影响的研究
  4. 大数据开发基础入门与项目实战(一)Java SE之4.方法和封装
  5. 获取并处理中文维基百科语料
  6. 8086中寻址方式详解
  7. 【Linux学习笔记】关于ubuntu开机菜单栏和任务栏不见了的有效解决方法
  8. 一键开关电路设计(一)
  9. html怎么设置火狐ie兼容模式,火狐浏览器兼容模式如何设置?火狐浏览器兼容模式设置方法分享...
  10. html5 页面整体居中,html5标题居中 DIV布局怎么在页面水平居中