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

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 我只会HelloWorld,但是我却完成了一个SpringBoot项目!(1)

##序


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


##01 兔哥,收我为徒吧

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


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


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


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


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


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


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


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


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


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


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


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


“!”


##02 先建表吧

根据兔哥的说法,他要做一个能发布教程的系统,教程,不就是文章嘛。emmm…

我先建一个文章表肯定没错的,SpringBoot啥的待会再说吧。

-49.png

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

路径:打开公众号

50.png

点击经典博客,在这里:

51.png

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


##03 搭建SpringBoot项目

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


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

52.png



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

53.png


54、.png55.png56.png

点击Finish完成。

现在,修改一下pom文件:

57.png


<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包的,不用我操心啦。

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

58.png


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

server:
  port: 8080
  context-path: /edu
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/edu?characterEncoding=UTF-8
    username: root
    password: 
  jpa:
    database: mysql
    hibernate:
      ddl-auto: update
      show-sql: true
  resources:
    static-locations: classpath:static/
  mvc:
    view:
      prefix: /WEB-INF/jsp/
      suffix: .jsp

先写一个User类:

59.png


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的数据库。

60.png


61.png


这是启动类:

62.png

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);
   }
}

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

63.png



没报错欸!看下数据库:

64.png65.png


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

##03 访问登录页面吧

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

66.png


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

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

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

67.png


这是公共的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;
        //初始化canvas
        init();
    })
    //绘制圆的最大半径
    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这里放静态资源:

68.png


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

  resources:
    static-locations: classpath:static/


接下来是java的部分

69.png


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

看到了登录页面:70.png


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

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
5月前
|
Java Spring
SpringBoot-项目复制
本文介绍如何复制SpringBoot-项目文件并顺利启动复制后的项目。
101 0
|
11月前
|
Java
Springboot项目启动的三种方式
Springboot项目启动的三种方式
187 0
|
2月前
|
XML Java Maven
创建第一个springboot项目、用springboot实现页面跳转、@Controller和@RestController的区别
这篇文章介绍了如何创建第一个Spring Boot项目,实现页面跳转,以及`@Controller`和`@RestController`的区别,并提供了代码示例和配置说明。
创建第一个springboot项目、用springboot实现页面跳转、@Controller和@RestController的区别
|
3月前
|
Java Spring
创建SpringBoot项目的方式
创建SpringBoot项目的方式
82 1
|
4月前
|
Oracle Java 开发工具
创建第一个Springboot项目HelloWorld
创建第一个Springboot项目HelloWorld
28 3
|
10月前
|
IDE Java Maven
SpringBoot一1(初次使用)+HelloWord
SpringBoot一1(初次使用)+HelloWord
41 0
|
Java Maven Spring
创建第一个 SpringBoot 项目
创建第一个 SpringBoot 项目
139 0
|
Java Spring
第一个SpringBoot项目的创建(下)
第一个SpringBoot项目的创建(下)
|
XML Java 应用服务中间件
第一个SpringBoot项目的创建(上)
第一个SpringBoot项目的创建(上)
131 0
|
Java Maven
02.第一个Springboot程序
02.第一个Springboot程序
下一篇
无影云桌面