##序

本系列的写作风格是第一人称,目的是为了让教程看起来更有意思一点,叶小凡是我某本JS书籍的主人公名字。以下经历纯属虚构,如有雷同,纯属巧合!

##01 兔哥,收我为徒吧
我叫叶小凡,即将毕业,正愁找工作。之前在网上关注了一位博主,网名叫剽悍一小兔,感觉文章写的还可以,后来关注了他的公众号,学会了基本的环境配置。可是,也就仅此而已了,我只会HelloWorld。

这一天,我微信上问他,你为啥叫剽悍一小兔啊?

“没多想,我挺喜欢兔子的,应该很好吃,脑袋一热,就取了这个名字!”

“兔哥,我刚毕业,想学Java,能不能收我为徒啊?”

“是么,你可要想好,跟我修行可是很辛苦的!”

“我已经想好了,我虽然只会HelloWorld,但是我愿意学。”

“这样,你先用SpringBoot帮我做一个系统出来,我打算做一个教育网站,正好要用,你什么时候给我做出来,我就什么时候收你为徒!”

我一听就惊呆了,连忙说道:“可是我只会HelloWorld啊…”

“没事,我可以指导你怎么写,放心,只会HelloWorld也没有关系,你一定可以的!”

“我明白了,兔哥,你是打算把修行的内容平摊到每一天中,让我在做网站的时候,就学到了编程的技术,对吗?”

“不是,我只是单纯地不想自己写而已!”

“。。。。。。额,最后一个问题,为什么你每说完一句话,都要加个感叹号啊?”

“!”

##02 先建表吧
根据兔哥的说法,他要做一个能发布教程的系统,教程,不就是文章嘛。emmm…
我先建一个文章表肯定没错的,SpringBoot啥的待会再说吧。

兔哥:“你先别着急建文章表,要不你先把我关于springboot的入门教程看了,其实你用spring data jpa的话,可以直接写JavaBean,顺便把表建了,很方便。”

路径:打开公众号

点击经典博客,在这里:

“我靠,你从哪冒出来的,吓死宝宝了!”我吃了一惊,然后就去看了一下教程,感觉其实也挺简单的嘛。

##03 搭建SpringBoot项目
ok,说干就干,先把系统给建起来。兔哥的文章里面讲的是在线生成springboot项目,我偏不,我就自己建。

当然,我已经通过看这里的文章,把环境都搭建好了,maven也配置好了。

接下来就是撸起袖子加油干,打开eclipse,创建一个maven项目。

点击Finish完成。

现在,修改一下pom文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.tuzi</groupId><artifactId>edu</artifactId><version>0.0.1-SNAPSHOT</version><name>兔子编程</name><description>某个很水的在线教育平台</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.9.RELEASE</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><!-- servlet依赖. --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId></dependency><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId></dependency><!-- tomcat的支持.--><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-jasper</artifactId></dependency>  <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional> <!-- 这个需要为 true 热部署才有效 --></dependency><!-- ORM 框架采用JPA --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!-- mysql --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.21</version></dependency><!-- springboot test --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><properties><java.version>1.8</java.version></properties><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>1.4.2.RELEASE</version></plugin></plugins><resources><resource><directory>${basedir}/src/main/webapp</directory><targetPath>META-INF/resources</targetPath><includes><include>**/**</include></includes></resource><resource><directory>src/main/resources</directory><filtering>false</filtering><includes><include>**/**</include></includes></resource></resources></build></project>

基本的配置都有了,保存了以后maven会去自动下载对应的jar包的,不用我操心啦。

然后,这边建一个简单的目录结构:

配置文件就用yml吧,兔哥的教程里面也是yml的,然后这边我加了点mvc的配置,因为视图层我只会jsp:

server:port: 8080context-path: /eduspring:datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/edu?characterEncoding=UTF-8username: rootpassword: jpa:database: mysqlhibernate:ddl-auto: updateshow-sql: trueresources:static-locations: classpath:static/mvc:view:prefix: /WEB-INF/jsp/suffix: .jsp

先写一个User类:

package com.edu.entity;import javax.persistence.*;@Entity
public class User {@Id@Column(length = 20)private String userName;@Column(length = 20)private String password;@Column(length = 30)private String nickName;@Column(length = 80)private String headerPic;@Column(length = 1)private String isVip;@Column(length = 1)private String isLogined;@Column(length = 2)private String roleId;@Column(length = 1)private String isDelete;@Column(length = 8)private String createTime;@Column(length = 8)private String lastLoginTime;@Column(length = 64)private String ipAddr;//无参构造方法,这个必须要有,不然会报错public User() {}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getNickName() {return nickName;}public void setNickName(String nickName) {this.nickName = nickName;}public String getHeaderPic() {return headerPic;}public void setHeaderPic(String headerPic) {this.headerPic = headerPic;}public String getIsVip() {return isVip;}public void setIsVip(String isVip) {this.isVip = isVip;}public String getRoleId() {return roleId;}public void setRoleId(String roleId) {this.roleId = roleId;}public String getIsDelete() {return isDelete;}public void setIsDelete(String isDelete) {this.isDelete = isDelete;}public String getCreateTime() {return createTime;}public void setCreateTime(String createTime) {this.createTime = createTime;}public String getIsLogined() {return isLogined;}public void setIsLogined(String isLogined) {this.isLogined = isLogined;}public String getLastLoginTime() {return lastLoginTime;}public void setLastLoginTime(String lastLoginTime) {this.lastLoginTime = lastLoginTime;}public String getIpAddr() {return ipAddr;}public void setIpAddr(String ipAddr) {this.ipAddr = ipAddr;}}

这个User类主要是用来做用户的登录的,嗯,反正他自己一个人用,我就做登录功能,不注册了。

然后,用mysql-front工具去新建一个叫做edu的数据库。

这是启动类:

package com.edu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}}

接下来就是见证奇迹的时刻,运行启动类:

没报错欸!看下数据库:

来了来了,真的来了,好高兴哦,又吃成长快乐了!

##03 访问登录页面吧
既然是个系统,肯定得有一个登录页面撒,可是我html和css写的很一般,美工又不会做,就只能网上找一找现成的登录模板,才可以维持得了生活,这样子。

兔哥:“别去乱搜了,我们得加快进度啊,我已经给你找好了,直接用这一套吧!”

“我靠,你能不能别总是一下子就跑出来吓人好不啦!”我又吃了一惊。

于是,兔哥给我发了一个资料包,我根据他的要求把一系列文件放在了对应的地方。

这是公共的jsp和登录页面——login.jsp。

taglib.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%//获取当前项目路径
String path = request.getContextPath();
int port = request.getServerPort();
String basePath = null;
if(port==80){basePath = request.getScheme()+"://"+request.getServerName()+path;
}else{basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path;
}
pageContext.setAttribute("basePath", basePath);%>

login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@include  file="common/taglib.jsp"%>
<!doctype html>
<html lang="en"><head><meta charset="UTF-8"><meta name="Generator" content="EditPlus®"><meta name="Author" content=""><meta name="Keywords" content=""><meta name="Description" content=""><title>Document</title><style>#canvas { position: fixed;top: 0;z-index: -100;opacity:0.6;}.box{display: flex;justify-content: center;margin-top: 50px;perspective: 500px;transform-style: preserve-3d;animation: fadeInUp 0.5s;}.font {float: left;width: 100px;height: 100px;background: #fff;color: #16142B;border: 1px solid #16142B;font-family: consolas;font-weight: bold;font-size: 50px;text-align: center;line-height: 100px;transition: 0.8s;box-shadow: 0 5px 10px black, inset 0 5px 2px #777, inset 0 -5px 2px #333, inset 5px 0px 2px #444, inset -5px 0px 2px #444;border-radius: 20px;}#mainContent {position:absolute;left:50%;margin-left:-220px;margin-top:20px;}.box2 {position:relative;top:24px;color:#222;}input {display: inline-block;width: 100%;height: 28px;padding: 6px 12px;font-size: 14px;line-height: 1.42857143;color: #555;background-color: #fff;background-image: none;border: 1px solid #ccc;border-radius: 4px;}#message {color:red;}</style></head><body><div class="box"><div class="font" id="d">小</div><div class="font" id="k">兔</div><div class="font" id="p">教</div><div class="font" id="l">育</div></div><div id="mainContent" style="text-align:center;"><div class="box2"><div style="height:24px;">   <span id="message"></span>   </div><form action="user/login" method="post"><input type="text" class="inputs" id="account" name="account" autofocus="autofocus" placeholder="请输入账号" maxLength="20">&nbsp;&nbsp;&nbsp;&nbsp;<input type="password" class="inputs" id="password" name="password" placeholder="请输入密码" maxLength="20"><p class="btn"><input type="button" style="height:38px;width:106%;" id="loginbtn" hidden='true' onclick="tm_login(this)" class="submit" value="登陆"><p></form></div></div><canvas id="canvas" width="686" height="300"></canvas><script type="text/javascript" src="${basePath}/js/jquery-1.11.1.min.js"></script><script type="text/javascript" src="${basePath}/js/util.js"></script><script>/*** 获取canvas对象,设置宽度高度自适应* @type {[type]}*/var canvas = document.querySelector("#canvas");canvas.width = window.innerWidth;canvas.height = window.innerHeight;canvas.globalAlpha = .1;canvas.fillStyle = 'rgba(255, 255, 255, 0)';var ctx = canvas.getContext("2d");/*** 屏幕鼠标坐标* @type {Object}*/var mouse = {x: undefined,y: undefined}/*** @param  {鼠标移动事件,回调函数,赋值给鼠标坐标}* @return {[type]}*/window.addEventListener("mousemove",function (event) {mouse.x = event.x;mouse.y = event.y;// console.log(mouse);});/*** @param  {重新设置窗口大小,使canvas宽高自适应屏幕}* @return {[type]}*/window.addEventListener("resize",function () {canvas.width = window.innerWidth;canvas.height = window.innerHeight;//初始化canvasinit();})//绘制圆的最大半径var maxRadius = 10;// var minRadius = 2;//圆的颜色数组var colorArray = ['#58D68D','#E67F22','#3598DB','#E84C3D','#9A59B5','#27AE61','#D25400','#BEC3C7','#297FB8']/*** @param {x圆中心的x坐标}* @param {y圆中心的y坐标}* @param {dx圆运动的x偏移量}* @param {dy圆运动的y偏移量}* @param {radius圆的半径}* minRadius圆的最小半径* bg圆的背景颜色* draw绘制函数* update圆运动偏移*/function Circle(x, y, dx, dy, radius) {this.x = x;this.y = y;this.dx = dx;this.dy = dy;this.radius = radius;this.minRadius = radius;this.bg = colorArray[Math.floor(Math.random()*colorArray.length)];this.draw = function() {ctx.beginPath();ctx.strokeStyle = "#777";ctx.fillStyle = this.bg;ctx.arc(this.x,this.y,this.radius,Math.PI/180*0,Math.PI/180*360,false);// ctx.stroke();ctx.fill();}this.update = function() {//圆触碰边界时反弹,偏移值为负if (this.x + this.radius > innerWidth || this.x - this.radius < 0 ) {this.dx = -this.dx;}if (this.y + this.radius > innerHeight || this.y - this.radius < 0 ) {this.dy = -this.dy;}//刷新绘制时圆的偏移运动this.x += this.dx;this.y += this.dy;//鼠标半径50像素范围内的圆,它们的半径逐步增加到最大值if (mouse.x - this.x < 50 && mouse.x - this.x >-50 && mouse.y - this.y < 50 && mouse.y - this.y >-50) {if (this.radius < maxRadius) {this.radius += 1;}//其他的所有圆半径减小到最小值}else if (this.radius > this.minRadius) {this.radius -= 1;}//根据更新的值进行绘制this.draw();}}//圆的对象数组var circleArray = [];/*** 初始化函数,制造800个随机坐标、偏移速度和半径的圆,加入到对象数组* @return {[type]}*/function init() {circleArray = []for (var i = 0; i < 800; i++) {var x = Math.random()*window.innerWidth;var y = Math.random()*window.innerHeight;var dx = (Math.random()-0.5)*2;var dy = (Math.random()-0.5)*2;var radius = Math.random()*3 +1;circleArray.push(new Circle(x, y, dx, dy, radius));}}init();/*** 动画函数* @return {[type]}*/function animate() {//更新前清楚画布ctx.clearRect(0,0,window.innerWidth,window.innerHeight);requestAnimationFrame(animate);//每个圆都调用update()方法for (var i = 0; i < circleArray.length; i++) {circleArray[i].update();}}animate();$(function(){//敲入键盘的enter建进行提交登陆$(document).keydown(function(e){if(e.keyCode == 13){//触发登陆按钮的事件$("#loginbtn").trigger("click");}});});//已定义减少和服务器端的交互---静态化function tm_login(obj){var account = $("#account").val();var password = $("#password").val();if(isEmpty(account)){$("#account").focus();tm_showmessage("请输入账号");return;}if(isEmpty(password)){$("#password").focus();tm_showmessage("请输入密码");return;}//$(obj).parent().css("paddingLeft",387);$(obj).attr("value","登陆中...").removeAttr("onclick");$.ajax({type:"post",url:"User/login.do",error:function(){$(obj).attr("value","登陆").attr("onclick","tm_login(this)");},data:{"account":account,"password":password},success:function(data){data = eval("("+data+")");if(data.code == 0){window.location.href = "view.do?path=index";}else{$("#account").select();$("#password").val("");$(obj).attr("value","登陆").attr("onclick","tm_login(this)");tm_showmessage(data.msg);}}});}//显示错误信息function tm_showmessage(message){$("#message").show().html(message).stop(true,true).fadeOut(3000);}//找到文本框,并注册得到焦点事件/*  $("input").focus(function(){//让当前得到焦点的文本框改变其背景色$(this).css("background","skyblue").css("color","#fff");});//找到文本框,并注册失去焦点事件$("input").blur(function(){//让当前失去焦点的文本框背景色变为白色$(this).css("background","white").css("color","#000");}); */</script></body>
</html>

兔哥说是网上随便找的,看起来挺牛掰的,咱也不敢问,等以后学到前端知识的时候再说吧。

然后是static这里放静态资源:

因为在application.yml里面已经配置静态资源了,所以这样就能直接访问static文件夹里面的东西了。

  resources:static-locations: classpath:static/

接下来是java的部分

ViewController就是视图访问控制器,看下代码:

package com.edu.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
public class ViewController {@RequestMapping("/view/{page}")public String view(@PathVariable(name = "page") String page) {return page;}}

意思就是页面访问这个映射地址,直接返回 WEB-INF/jsp里面对应的文件。

启动项目,然后我们访问
http://localhost:8080/edu/view/login

看到了登录页面:

本章源码已经上传群文件,有需要的小伙伴直接去下载哦。

我只会HelloWorld,但是我却完成了一个SpringBoot项目!(1)相关推荐

  1. 第一节:创建SpringBoot项目并运行HelloWorld

    SpingBoot 365计划开始更新了,计划手敲365个SpringBoot案例回顾总结形成知识体系.目前已经输出了32节的内容.所有源码托管在GitHub和Gitee上. 1.第一节:创建Spri ...

  2. 基于maven, 你的第一个SpringBoot应用的HelloWorld程序(写的步骤)

    Maven中SpringBoot HelloWorld实现 主要的教程(官方) 创建工程 Feil -> new -> project -> Maven -> Next -&g ...

  3. android工程的建立,第一个Android项目HelloWorld的建立及剖析

    1.建立一个简单的Hello World程序 步骤1:启动Eclipse,选择 New->Other,如下图所示 步骤2:在出现的窗口中选择Android Project,如下图所示: 步骤3: ...

  4. 2021-09-29破解小米“铁蛋”,只需9999元,你也可以做一个四足机器人!

    https://www.eet-china.com/news/202109291008.html 2021-09-29破解小米"铁蛋",只需9999元,你也可以做一个四足机器人! ...

  5. 第一个OpenDayLight项目:HelloWorld

    第一个opendaylight项目:HelloWorld! 1.前言 ​  出于本人研究课题需要,实现自定义opendaylight控制器的功能,需要修改控制器的内部代码,因此必须梳理清楚ODL的内部 ...

  6. 阿里极客公益——1000+阿里技术专家来回答你的问题或许你挑灯夜战只为一道难题 或许你百思不解只求一个答案 或许你绞尽脑汁只因一种未知 那么他们来了,阿里1000+位技术专家来云栖问答为你解答技

    原文链接:点击打开链接 或许你挑灯夜战只为一道难题 或许你百思不解只求一个答案 或许你绞尽脑汁只因一种未知 那么他们来了,阿里1000+位技术专家来云栖问答为你解答技术难题了 他们用户自己手中的技术来 ...

  7. SpringBoot项目用tomcat启动,没有报错,控制台只输出org.apache.catalina.startup.catalina.start server startup in xxxms

    背景:最近在使用SpringBoot项目过程中,代码写好测试完,部署到服务器上启动使用外置的tomcat启动,控制台只输出org.apache.catalina.startup.catalina.st ...

  8. 2023年春节祝福第二弹——送你一只守护兔,让它温暖每一个你【html5 css3】画会动的小兔子,炫酷充电,字体特效

    2023年春节祝福第二弹 送你一只守护兔,让它温暖每一个你! [html5 css3]画一只会动的兔子 目录 一.送你一只守护兔,效果图 二.前言 三.代码解释及部分特效教程 (1).css3 立体字 ...

  9. 您现在只需免费与相机捆绑即可购买一个PSVR

    (52VR开发网2017年5月4日讯)任何可以做的,以降低进入VR球体的价格都是一个好主意.去年10月发布的PlayStation VR(PSVR)耳机,这些选项有点让人无法理解.价值400美金的核心 ...

  10. 刷新COCO目标检测纪录!谷歌只靠AI扩增数据,就把一个模型变成SOTA,已开源

    栗子 发自 凹非寺  量子位 报道 | 公众号 QbitAI 谷歌大脑Quoc Le团队,又训练出了一只地表最强的模型. 这是一个目标检测模型,从前并不是最强大. 但自从团队用机器学习解锁了特别的数据 ...

最新文章

  1. 听说程序猿不会撩妹,我笑了
  2. class没有发布到tomcat_SpringBoot内置tomcat启动原理
  3. 三维重建 3D reconstruction 有哪些实用算法?
  4. java存储整数_关于数组:Java:存储大量整数的最佳数据类型是什么?
  5. LeetCode Best Time to Buy and Sell Stock with Cooldown(动态规划)
  6. c#-检查USB硬件变化
  7. 张帅用赢球庆生 搭档斯托瑟晋级澳网女双八强
  8. 使用LightBDD轻松实现行为驱动开发
  9. HDOJ(HDU) 1994 利息计算(简单题目)
  10. Scikit-learn 秘籍 翻译完成
  11. python加密解密算法_Python基于DES算法加密解密实例
  12. typec扩展坞hdmi没反应_HDMI+两个USB接口,让surface秒变办公神器?这个扩展坞真香...
  13. 浅谈暴力破解及验证码安全
  14. 热电传感器(1)——原理和定律
  15. python绘制正多边形_python : turtle 画正多边形
  16. 求推荐一款移动硬盘,日立和西数哪个好?
  17. 基于JAVA的鲜花店商城平台【数据库设计、源码、开题报告】
  18. Excel的基本操作
  19. 双网卡 跃点_关于windows 双网卡和跃点数研究
  20. 阿里 卫哲谈阿里人力招聘价值观

热门文章

  1. 2020伊始,电动车又给自己刷了一遍谎言buff
  2. 百度为手游盛世添把火
  3. 我的大学十年 (转)
  4. 自然语言处理中的中英文分词工具
  5. Linux misc设备(二)蜂鸣器驱动
  6. N沟道和P沟道MOS管的四个不同点
  7. 小酥的Python学习日记 2022.7.3
  8. 改版后的CSDN如何更换皮肤
  9. Warning: Procedure created with compilation errors.
  10. Swing绝对布局之setBounds