2021/07/24 SpringBoot2 Web开发快速入门
- 环境:JDK13、IDEA、SpringBoot2.5.3、maven3.8.1
目录
一、辅助插件
1、lombok
2、spring-boot-devtools
3、Spring Initailizr(项目初始化向导)
二、配置文件
1、yaml文件赋值
基本语法
三、Web开发
1、SpringMVC自动配置概览
2、静态资源
3、欢迎页
4、常用参数注解
@PathVariable(路径变量)和 @RequestHeader(获取请求头)
@RequestParam(获取前端返回的参数)和@Cookie(获取Cookie)
@RequstBody(获取请求体【post请求才有】)
四、视图解析与模板引擎
1、模板引擎-Thymeleaf
thymeleaf简介
基本语法
开发步骤
页面跳转
检查用户是否登录
抽取公共部分
表格的遍历
五、 拦截器
六、文件上传
七、错误处理
1、默认规则
八、Web原生组件注入(Servlet,Filter,Listener)
1、注解注入方式
①Servlet
②Filter
③Listener
2、使用RegistrationBean
一、辅助插件
1、lombok
可以生成get,set方法,有参无参构造器,日志等的注解,引入依赖后去在idea的插件商店中搜索lombok并安装即可
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.16</version><scope>provided</scope> </dependency>
2、spring-boot-devtools
热部署插件,改变项目代码不需要重新部署也可以生效,只需重新编译项目
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><version>2.5.2</version> </dependency>
3、Spring Initailizr(项目初始化向导)
在idea中new project按照提示选择需要的组件创建一个工程,自动分配目录
二、配置文件
SpringBoot项目给属性赋值的方式
1、yaml文件赋值
基本语法
- key: value;kv之间有空格
- 大小写敏感
- 使用缩进表示层级关系
- 缩进不允许使用tab,只允许空格
- 缩进的空格数不重要,只要相同层级的元素左对齐即可
- '#'表示注释
- 字符串无需加引号,如果要加,''与""表示字符串内容 会被 转义/不转义
1、创建两个实体类Person和Dog
package com.kuang.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Data
@AllArgsConstructor
@NoArgsConstructor
@Component
public class Dog {private String name;private Integer age;
}
package com.kuang.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;import java.util.Date;
import java.util.List;
import java.util.Map;@AllArgsConstructor
@Data
@NoArgsConstructor
@Component
@ConfigurationProperties(prefix = "person")
public class Person {private String name;private Integer age;private Boolean happy;private Date birth;private Map<String,Object> maps;private List<Object> lists;private Dog dog;
}
注意:Person类中的@ConfigurationProperties,与配置文件绑定,如果属性值中有 \n 被单引号包围,则原样输出,双引号包围输出换行
此注解即可以引用yaml文件中对应person开头的属性的值,以此为属性赋值,下面是yaml文件内容,yaml文件语法对空格要求极为严格,以下为:对peson对象的各个属性进行赋值,yaml中对象person的首字母必须小写,属性名与实体类要么一致,要么遵循松散绑定
person:name: Youngage: 22happy: truemaps: {k1: v1,k2: v2}lists:- 1- 2- 你好dog:name: 旺财age: 3birth: 2021/7/22
测试:
package com.kuang;import com.kuang.pojo.Person;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
class SpringbootApplicationTests {@Autowiredprivate Person person;@Testvoid contextLoads() {System.out.println(person);}}
结果:
Person(name=Young, age=22, happy=true, birth=Thu Jul 22 00:00:00 GMT+08:00 2021, maps={k1=v1, k2=v2}, lists=[1, 2, 你好], dog=Dog(name=旺财, age=3))
当然这只是一种方式,使用@Value注解与properties文件亦可
三、Web开发
1、SpringMVC自动配置概览
Spring Boot provides auto-configuration for Spring MVC that works well with most applications.(大多场景我们都无需自定义配置)
The auto-configuration adds the following features on top of Spring’s defaults:
- Inclusion of
ContentNegotiatingViewResolver
andBeanNameViewResolver
beans.
- 内容协商视图解析器和BeanName视图解析器
- Support for serving static resources, including support for WebJars (covered later in this document)).
- 静态资源(包括webjars)
- Automatic registration of
Converter
,GenericConverter
, andFormatter
beans.
- 自动注册
Converter,GenericConverter,Formatter
- Support for
HttpMessageConverters
(covered later in this document).
- 支持
HttpMessageConverters
(后来我们配合内容协商理解原理)
- Automatic registration of
MessageCodesResolver
(covered later in this document).
- 自动注册
MessageCodesResolver
(国际化用)
- Static
index.html
support.
- 静态index.html 页支持
- Custom
Favicon
support (covered later in this document).
- 自定义
Favicon
- Automatic use of a
ConfigurableWebBindingInitializer
bean (covered later in this document).
- 自动使用
ConfigurableWebBindingInitializer
,(DataBinder负责将请求数据绑定到JavaBean上)
2、静态资源
默认情况下,Spring Boot 提供来自类路径中名为
/static
(或/public
或/resources
或/META-INF/resources
)的目录作为静态资源目录,默认情况下,资源映射在 上
/**
,但您可以使用spring.mvc.static-path-pattern
属性对其进行调整。例如,将所有资源重新分配到/resources/**
可以实现如下:
spring.mvc.static-path-pattern=/resources/**
即为:
spring:mvc:static-path-pattern: /res/**
表示res文件夹下所有资源都为静态资源
注意:如果controller与静态资源重合,请求会先找controller解决,如果没有找到对应的controller,则找静态资源,若找不到静态资源,则404
3、欢迎页
它首先在配置的静态内容位置中查找index.xml文件。如果没有找到,它就会寻找一个index
模板。如果找到其中之一,它会自动用作应用程序的欢迎页面。
两种方式设置欢迎页
- 默认静态资源路径下 index.html
- ccontroller能处理/index
- 可以配置静态资源路径
- 但是不可以配置静态资源的访问前缀。否则导致 index.html不能被默认访问
spring:
# mvc:
# static-path-pattern: /res/** 这个会导致welcome page功能失效resources:static-locations: [classpath:/haha/]
4、常用参数注解
@PathVariable(路径变量)和 @RequestHeader(获取请求头)
可用于restful风格
/** @PathVariable* 参数map默认可以返回请求参数的键值对形式*/@GetMapping("/a/{user}/{pwd}")@ResponseBodypublic String a(@PathVariable("user") String name,@PathVariable("pwd") String password ,@PathVariable Map<String,String> map ){return name+"|"+password+"|"+map;}
结果:
我们在次注解的底层代码中,可以找到这样一段注释
* <p>If the method parameter is {@link java.util.Map Map<String, String>}* then the map is populated with all path variable names and values.
也就是说,当有一个参数为Map<String,String>类型时,自动用变量名和值填充映射
/** @PathVariable*/@GetMapping("/a/{user}/{pwd}")public Map<String,Object> a(@PathVariable("user") String name,@PathVariable("pwd") String password ,@PathVariable Map<String,String> map,@RequestHeader("User-Agent") String userAgent,@RequestHeader Map<String,String> header){Map<String, Object> hashMap = new HashMap<>();hashMap.put("name",name);hashMap.put("password",password);hashMap.put("map",map);hashMap.put("user-agent",userAgent);hashMap.put("header",header);return hashMap;}
测试:
@RequestParam(获取前端返回的参数)和@Cookie(获取Cookie)
@RequestMapping("/b")public Map<String,Object> hello(@RequestParam("hobby") String hobby,@RequestParam Map<String,String> params,@CookieValue("JSESSIONID") String JSESSIONID,@CookieValue("JSESSIONID") Cookie cookie){Map<String,Object> hashMap = new HashMap<>();hashMap.put("hobby",hobby);hashMap.put("params",params);hashMap.put("JSESSIONID",JSESSIONID);hashMap.put("cookie",cookie);System.out.println(cookie.getName()+"---->"+cookie.getValue());return hashMap;}
测试:
@RequstBody(获取请求体【post请求才有】)
@PostMapping("/save")public Map post(@RequestBody String body){Map<String,Object> hashMap = new HashMap<>();hashMap.put("requestBody",body);return hashMap;}
表单如下
结果:
四、视图解析与模板引擎
视图解析:SpringBoot默认不支持 JSP,需要引入第三方模板引擎技术实现页面渲染
1、模板引擎-Thymeleaf
thymeleaf简介
Thymeleaf is a modern server-side Java template engine for both web and standalone environments, capable of processing HTML, XML, JavaScript, CSS and even plain text.
现代化、服务端Java模板引擎
基本语法
1、表达式
表达式名字 |
语法 |
用途 |
变量取值 |
${...} |
获取请求域、session域、对象等值 |
选择变量 |
*{...} |
获取上下文对象值 |
消息 |
#{...} |
获取国际化等值 |
链接 |
@{...} |
生成链接 |
片段表达式 |
~{...} |
jsp:include 作用,引入公共页面片段 |
2、字面量
文本值: 'one text' , 'Another one!' ,…数字: 0 , 34 , 3.0 , 12.3 ,…布尔值: true , false
空值: null
变量: one,two,.... 变量不能有空格
3、文本操作
字符串拼接: +
变量替换: |The name is ${name}|
4、数学运算
运算符: + , - , * , / , %
5、布尔运算
运算符: and , or
一元运算: ! , not
6、比较运算
比较: > , < , >= , <= ( gt , lt , ge , le )等式: == , != ( eq , ne )
7、条件运算
If-then: (if) ? (then)
If-then-else: (if) ? (then) : (else)
Default: (value) ?: (defaultvalue)
开发步骤
1、引入启动器
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>
2、直接开发即可
编写一个controller
package com.young.controller;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;@Controller
public class ViewTestController {@GetMapping("/young")public String young(Model model){//model的数据会被放在request域中model.addAttribute("msg","你好young!");model.addAttribute("link","http://www.4399.com");return "success";}
}
编写跳转的网页success.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1 th:text="${msg}">哈哈</h1><a href="http://www.atguigu.com" th:href="${link}">去4399【1】</a><a href="http://www.atguigu.com" th:href="@{link}">去4399【2】</a>
</body>
</html>
测试
点击‘去4399【1】’
成功跳转
点击‘去4399【2】’
404错误,将按钮改成:
<a href="http://www.atguigu.com" th:href="@{http://www.4399.com}">去4399【2】</a>
可以跳转成功,以此区分@{}与${},前者是直接取值,后者是动态取值
页面跳转
利用重定向防止登录表单信息的重复提交
package com.young.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;@Controller
public class IndexController {//去登录页@GetMapping({"/","/login"})public String loginPage(){return "login";}//处理登录请求@PostMapping("/login")public String login(String username, String pwd){//重定向,防止表单重复提交return "redirect:main.html";}@GetMapping("/main.html")public String main(){//刷新只会刷新main页面,而不会重复刷新login请求return "main";}
}
注意:SpringBoot中请求必须经过视图解析器,所有需要两个请求方法完成重定向
检查用户是否登录
//处理登录请求@PostMapping("/login")public String login(User user, HttpSession session,Model model){if (!user.getUserName().isEmpty() && "root".equals(user.getPwd())){//重定向,防止表单重复提交session.setAttribute("loginUser",user);return "redirect:main.html";}model.addAttribute("msg","用户名或密码错误!");return "login";}@GetMapping("/main.html")public String main(HttpSession session, Model model){//是否登录,拦截器User user = (User) session.getAttribute("loginUser");if (user != null){//刷新只会刷新main页面,而不会重复刷新login请求return "main";}else {model.addAttribute("msg","信息已过期,重新登路");return "login";}}
抽取公共部分
可以在抽取出的common页面(示例)的某标签中使用 th:fragment="名称"或者id为一个片段取名称,然后在要引入的页面内使用一下三种方式引用
注意:div标签为示例,common为公共页面名称(省略html后缀),两个冒号后面的参数为片段名
<div th:insert="common :: 名称/#id"></div>
效果:head中有属性th:fragment,直接将head标签整个插入到页面中
<div><head><!--common--><link href="/css/style.css" rel="stylesheet"><link href="/css/style-responsive.css" rel="stylesheet"><!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --><!--[if lt IE 9]><script src="/js/html5shiv.js"></script><script src="/js/respond.min.js"></script><![endif]-->
</head></div>
<div th:replace="common :: 名称/#id"></div>
效果:head中有属性th:fragment,直接替换掉了div标签
<head><!--common--><link href="/css/style.css" rel="stylesheet"><link href="/css/style-responsive.css" rel="stylesheet"><!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --><!--[if lt IE 9]><script src="/js/html5shiv.js"></script><script src="/js/respond.min.js"></script><![endif]-->
</head>
<div th:include="common :: 名称/#id"></div>
效果:head中有属性th:fragment,head标签没了,直接将head的内容插入
<div><!--common--><link href="/css/style.css" rel="stylesheet"><link href="/css/style-responsive.css" rel="stylesheet"><!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --><!--[if lt IE 9]><script src="/js/html5shiv.js"></script><script src="/js/respond.min.js"></script><![endif]-->
</div>
表格的遍历
th:each方法
在请求中放入一些User对象返回给前端
@RequestMapping("/dynamic_table")public String dynamic_table(Model model){List<User> users = Arrays.asList(new User("root1", "123"), new User("root2", "123"),new User("root3", "123"), new User("root4", "123"));model.addAttribute("users",users);return "table/dynamic_table";}
如下方式进行遍历
<tr class="gradeX" th:each="user:${users}"><td ></td><td th:text="${user.userName}"></td><td th:text="${user.pwd}"></td></tr>
其中,user为得到的users的单个对象名(自定义),用法与jsp中差不多,此外,还有如下用法
当我们想要对遍历出的对象计数输出在前端页面时,写法如下:
如图,可以在user对象后面加逗号,任意定义一个名字,用${}调用,可以调用其方法,我们调用count计数输出
<tr class="gradeX" th:each="user,sta:${users}"><td th:text="${sta.count}"></td><td th:text="${user.userName}"></td><td th:text="${user.pwd}"></td></tr>
成功
五、 拦截器
写一个类实现HandlerInterceptor接口,并实现接口中的三个方法
/*** 登录检查* 1、配置好拦截器要拦截哪些请求* 2、把这些配置放在容器中*/
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {/*** 目标方法执行之前* @param request* @param response* @param handler* @return* @throws Exception*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String requestURI = request.getRequestURI();log.info("preHandle拦截的请求路径是{}",requestURI);//登录检查逻辑HttpSession session = request.getSession();Object loginUser = session.getAttribute("loginUser");if(loginUser != null){//放行return true;}//拦截住。未登录。跳转到登录页request.setAttribute("msg","请先登录");
// re.sendRedirect("/");request.getRequestDispatcher("/").forward(request,response);return false;}/*** 目标方法执行完成以后* @param request* @param response* @param handler* @param modelAndView* @throws Exception*/@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {log.info("postHandle执行{}",modelAndView);}/*** 页面渲染以后* @param request* @param response* @param handler* @param ex* @throws Exception*/@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {log.info("afterCompletion执行异常{}",ex);}
}
在SpringMVC中,配置拦截器在配置文件中,这里可以用如下方法配置:
创建一个Config类,实现WebMvcConfigurer,关于mvc的配置都需要继承此类,实现类中的addInterceptor方法注册拦截器,并且注明拦截规则
/*** 1、编写一个拦截器实现HandlerInterceptor接口* 2、拦截器注册到容器中(实现WebMvcConfigurer的addInterceptors)* 3、指定拦截规则【如果是拦截所有,静态资源也会被拦截】*/
@Configuration
public class AdminWebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**") //所有请求都被拦截包括静态资源.excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**"); //放行的请求}
}
六、文件上传
前端代码如下:
<div class="form-group"><label for="exampleInputFile">头像</label><input name="headImg" type="file" id="exampleInputFile">
</div><div class="form-group"><label for="exampleInputFile">生活照</label><input name="photos" type="file" multiple>
</div>
当要选择多个图片时,加上属性multiple
@RequestMapping(value = "/upload",method = RequestMethod.POST)public String upload(@RequestParam("email") String email,@RequestParam("username") String username,@RequestPart("headImg") MultipartFile headImg,@RequestPart("photos") MultipartFile[] photos) throws IOException {if (!headImg.isEmpty()){//如果上传来的照片非空,保存到文件服务器,OOS服务器headImg.transferTo(new File("E:\\SpringBoot\\" + headImg.getOriginalFilename()));}if (photos.length > 0){//有长度说明有图片for (MultipartFile photo : photos) {if (!photo.isEmpty()){//非空photo.transferTo(new File("E:\\SpringBoot\\"+photo.getOriginalFilename()));}}}return "main";}
@RequestPart注解配合图片使用,MultipartFile类型可以接受并提供封装好的方法处理图片
调用 transferTo 方法可以将图片存在指定位置,getOriginalFilename方法可以得到本地图片名
七、错误处理
1、默认规则
- 默认情况下,Spring Boot提供
/error
处理所有错误的映射 - 对于机器客户端,它将生成JSON响应,其中包含错误,HTTP状态和异常消息的详细信息。对于浏览器客户端,响应一个“ whitelabel”错误视图,以HTML格式呈现相同的数据
- 要对其进行自定义,添加
View
解析为error
- 要完全替换默认行为,可以实现
ErrorController
并注册该类型的Bean定义,或添加ErrorAttributes类型的组件
以使用现有机制但替换其内容。 - error/下的4xx,5xx页面会被自动解析;
八、Web原生组件注入(Servlet,Filter,Listener)
1、注解注入方式
①Servlet
必须使用@WebServlet注解和@ServletCompentScan注解配合
package com.young.servlet;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet(urlPatterns = "/my")
public class MyServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.getWriter().write("6666");}
}
package com.young;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;@ServletComponentScan(basePackages = "com.young.servlet")
@SpringBootApplication
public class BootWeb05Application {public static void main(String[] args) {SpringApplication.run(BootWeb05Application.class, args);}}
@WebServlet(urlPatterns = "/my"):注册servlet类并且指定链接(无视拦截器)
@ServletComponentScan(basePackages = "com.young.servlet"):标在主类上进行包扫描
②Filter
package com.young.servlet;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;@WebFilter(urlPatterns = "")
public class MyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {}@Overridepublic void destroy() {}
}
@WebFilter(urlPatterns = " "):指定过滤资源路径
③Listener
同样使用@WebListener注解
2、使用RegistrationBean
ServletRegistrationBean
FilterRegistrationBean
ServletListenerRegistrationBean
@Configuration
public class MyRegistConfig {@Beanpublic ServletRegistrationBean myServlet(){MyServlet myServlet = new MyServlet();return new ServletRegistrationBean(myServlet,"/my","/my02");}@Beanpublic FilterRegistrationBean myFilter(){MyFilter myFilter = new MyFilter();
// return new FilterRegistrationBean(myFilter,myServlet());FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(myFilter);filterRegistrationBean.setUrlPatterns(Arrays.asList("/my","/css/*"));return filterRegistrationBean;}@Beanpublic ServletListenerRegistrationBean myListener(){MySwervletContextListener mySwervletContextListener = new MySwervletContextListener();return new ServletListenerRegistrationBean(mySwervletContextListener);}
}
2021/07/24 SpringBoot2 Web开发快速入门相关推荐
- [转]Android web开发快速入门
本文转自:http://www.apkbus.com/android-16708-1-1.html 通俗的讲,就是为移动设备开发网页.伴随着3G时代的到来.浏览器技术的不断进步,越来越多的人开始离开P ...
- 「译」Web安全快速入门
Web安全快速入门 ──几个Web开发人员必知的安全缩略语 原文:A quick introduction to web security 作者:Austin Tackaberry 发表时间:2018 ...
- HealthKit开发快速入门教程之HealthKit数据的操作
HealthKit开发快速入门教程之HealthKit数据的操作 数据的表示 在HealthKit中,数据是最核心的元素.通过分析数据,人们可以看到相关的健康信息.例如,通过统计步数数据,人们可以知 ...
- Apple Watch开发快速入门教程
Apple Watch开发快速入门教程 试读下载地址:http://pan.baidu.com/s/1eQ8JdR0 介绍:苹果为Watch提供全新的开发框架WatchKit.本教程是国内第一本A ...
- OUYA游戏开发快速入门教程第1章了解OUYA及其设备
OUYA游戏开发快速入门教程第1章了解OUYA及其设备 OUYA是基于Andorid系统的游戏主机.围绕OUYA游戏机,已经形成一个完整的生态圈.在国外,OUYA已经成为知名的游戏平台.本章会站在玩家 ...
- OUYA游戏开发快速入门教程
OUYA游戏开发快速入门教程 试读地址:http://pan.baidu.com/s/1o63a3W2 本教程是国内唯一OUYA游戏开发教程.本教程基于Unity全面讲解OUYA游戏开发方式.内容包 ...
- C#游戏开发快速入门 2.1 构建游戏场景
C#游戏开发快速入门 2.1 构建游戏场景 如果已经计划好了要编写什么样的游戏,在打开Unity以后,要做的第一件事情就是构建游戏场景(Scene).游戏场景就是玩家游戏时,在游戏视图中看到的一切, ...
- WebService 理论详解、JWS(Java Web Service) 快速入门
目录 WebService (web服务)概述 WebService 平台技术 WebService 工作原理 WebService 开发流程 常见 Web Service 框架 JWS(Java W ...
- 微信小程序开发快速入门
最近整理文件,找到一个18年写的微信小程序开发快速入门,对于新手还是值得一看的,三年多过去了,可能一些接口已经更新了,不过,整体思想还是没变的. 如果你熟悉JavaScript,那你基本上看完这个文档 ...
- 01 如何学习Python Web开发从入门到实战
Python Web开发从入门到实战 前言: Python Web是学校所学的课程,我希望在学习的同时通过写笔记的形式来记录我学习以及由学校学习转而自身对此方向感兴趣的一个过程,更多还是让自己在课程结 ...
最新文章
- 比尔·盖茨官宣离婚!除了孩子和基金会,一切都是浮云
- 全领域涨点 | Evolving Attention在CV与NLP领域全面涨点
- C++类特殊成员函数
- 遥感计算机分类实验的难点,8-遥感实验.doc
- Java学习 第四章 java面向对象(二)
- 构建DRM系统的重要基石——EME、CDM、AES、CENC和密钥
- audacity_如何在Audacity中快速编辑多个文件
- DDD实战课--学习笔记
- 基于结构体的二进制文件读写
- AddThis AddFeed WordPress插件发布 [转]
- Linux视频教程—笔记(全)
- 43. TA镜像文件的签名
- win7修改ftp服务器密码,win7ftp服务器设置用户名密码设置
- centos7搭建单机kafka,开启SASL/PLAIN加密,并使用kafka tool 登录
- 织梦网站模板的建站优势
- xshell 导入.xsh 文件
- JAVA SE 实战篇 C7 基于CSFramework的聊天室 (下) 客户端APP
- 用python实现水纹特效
- 如何用查看wifi密码
- win102004优化_这就是win102004版的17个新功能,微软windows真是越来越强了
热门文章
- matlab 读取.pgm,【数字图像处理】pbm/pgm/ppm图片的读写(Matlab)
- matlab改变图片尺寸及像素与尺寸的转换
- CRAFT: Character Region Awareness for Text Detection ---- 论文翻译
- 一步一步建立自己的神经网络
- 二维码名片页面的样式设计
- cad二开之不通过netload加载命令(bundle文件的使用)
- 【PMP】关键路径法
- 线性代数笔记【空间向量】
- supp(),支持集理解
- Cocos2d-x3.2刀塔创奇三消游戏源码,跑酷游戏源码,塔防游戏源码