注意:在创建项目之前确保自己的maven配置成功.
我们为什么要用springboot创建这个项目:
如果不使用SpringBoot框架创建工程,工程里面如果需要引入其框架,除了要在pom.xml文件总添加大量的依赖信息外,还需要有对应的xml配置文件,在配置文件中需要书写大量的配置代码,这些工作都需要程序员完成,如果使用了SpringBoot框架创建工程,在引入其它框架时只需程序员完成,如果使用了SpringBoot框架创建工程,在引入其它框架时只需要通过打钩的方式引入框架,不需要书写配置文件,从而大大提高了程序员构建工程的效率.
例如下面这个项目,我们勾选了就是这些
如何处理静态请求
把静态资源文件放在static文件夹中,此文件夹里面的文件是可以直接被客户端请求的,只需要通过以下路径:http://localhost:8080/文件名
如何处理动态请求
通过Controller控制器处理动态请求,在工程自带的包里面.
@ResponseBody注解:
使用此注解修饰Controller类里面的方法后,在方法中可以通过返回值的方式给客户端响应数据.
客户端发出请求的几种方式
1.通过浏览器的地址栏输入请求路径,回车后发出请求
2,通过超链接发出请求
3,通过form表单发出请求
MyBatis框架
此框架是目前最流行的数据持久层框架,使用Mybatis框架后,框架可以帮助我们生产JDBC代码,从而提高开发效率,使用此框架后,程序员只需要通过注解或xml配置文件写好需要执行的SQL语句帮助程序员生成对应的JDBC代码.
如何使用MyBatis框架(就是这个勾选上就行,这个也是我们weibo项目需要勾选的)
如果工程中包含了MyBatis框架,启动工程时需要用到application.properties里面配置的连接数据库信息,如果里面没有配置则启动工程时会报错如下错误提示.
同步请求和异步请求
我们这个工程全是异步请求,说白了,在正在写项目时,我们会用到的都是异步请求
同步:指单线程依次做几件事情
异步:多线程同时做几件事
同步请求:指客户端只有一个主线程,主线程负责页面渲染和监听操作,如果需要主线程发出请求是,会停止页面渲染(清空页面)只负责发请求,当服务器响应了数据之后,主线程再次恢复渲染的职责,把服务器响应的数据显示到页面中,这个过程是将页面内容进行了整体的改变,称为整体刷新,同步请求只能实现页面的整体刷新无法实现局部刷新.
异步请求:指客户端的主线程负责页面渲染和监听操作,由子线程发出请求获取数据,获取到数据后将数据展示到原有页面,这种叫页面的局部刷新,只有通过异步请求才可以实现,
那么客户端如何发出异步请求呢?
通过Axios框架发出异步请求
Axios是一个js框架文件,在html页面中引入此文件即可
文件引入地址:"https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"
下面这个代码就是在js代码中引入Axios和vue框架的代码
既然我们有了Axios框架我们就说说GET和POST请求
GET:请求参数卸载请求地址栏后面,由于参数在地址栏中可见所以不能传递带有敏感信息的参数,参数大小有限制,只能传递几K的数据,
应用场景:一般的查询请求都是用GET,删除数据一般也使用get
POST:请求参数在请求体里面,在请求体里面的参数时不可见的所有可以传递带有敏感信息的参数,请求参数的大小也没有限制
应用场景:有铭感信息的请求,上传请求,参数较多时使用.
对于前后端分离(我们本次的项目很小,虽然都是一个人写的,但是前后端也是进行了分离的)
前后端不分离:指在后端代码中需要些前端页面的代码,这样的话后端程序员需要开发两套Controller,一套负责给浏览器客户端响应页面+数据,另一套Controller负责给手机端响应数据,这样的话对于java后端程序员工作量增加了很多
前后端分离:指在后端代码中不处理页面相关不管客户端是浏览器还是手机端一视同仁只响应数据,这样的话后端只需要提供一套Controller即可,此时浏览器客户端需要的页面需要单独请求获取,获取完页面之后再通过异步请求方式获取数据,然后把数据展示到页面中(这个过程称为页面的布局刷新,只能通过异步请求实现)所以以后为了解决前后端分离的问题,则不再同步请求.
JSON
json是一个轻量级的数据交换格式,也叫做数据封装格式
json的数据格式的转换如上图:
说白了就是在java和javascript语言之间进行装换的装换器(个人理解)
当服务器给客户端响应的数据类型为自定义对象或List集合时,SprinMVC框架会自动将返回的数据转换为JSON格式的字符串,然后通过网络传输给客户端,客户端接收到的数据是JSON格式的字符串,Axios框架会自动将JSON格式字符串转换成javascript语言.
文件上传(在这个项目中,我们最主要的是图片的上传)
文件的上传,我们需要在application.properties中添加配置文件
注意:配置文件的静态资源这里,file:g:/files是我们传的文件存放的路径,客户端虽然点击了上传文件,但是文件其实是保存在他们本机的一个电脑的文件目录中的,我们在数据库中存储的也不是文件本身,而是文件的地址,比如说我们上传的是图片,那么数据库中存的是图片的地址.
设置时间的显示格式
通过JsonFormat注解设置时间的显示格式和时区
Mybatis框架在XML配置文件中书写SQL语句的用法:
因为使用了mybatis框架,其实是可以在mapper接口中直接添加@Mapper注解,和SQL语句的注解进行写sql语句的,但是有很多的缺点
1,如果sql语句太长,存在字符串折行和拼接问题,不够直观
2,一些关联查询的操作不易重复
对于DBA(数据库管理员)更友好,不需要去java代码中改SQL语句而是从配置文件中进行修改.
如何在XML配置文件中写SQL语句呢.
1.在application.properties里添加连接数据库的信息,和之前的一样,然后进行如下操作
2,创建Mybatis配置类,通过MapperScan注解取代每个Mapper接口类中的@Mapper注解
创建的方法如下图.
此时的mapper中和之前也不一样了,如下
然后我们在resource创建mapper文件夹
创建我们的xml文件
然后在application.properties配置文件中,配置书写SQL语句的xml文件在什么位置
到此我们算是配置完成.
POJO
- pojo指简单的java对象,是实体类Entity和值对象VO还有DTO数据传输对象的统称.
- Entity实体类,通常和对于的表字段的数量是一致的
- DTO数据传输对象,当客户端给服务器传递参数时,参数的数量可能比实体类中的数量要少,比如实体类中有10个参数,但是客户端之传递过来三个参数,此时通过DTO好处是只要发现null值就能判断出传输出错了.
- VO值对象,从数据库中的某个表查询数据,有多种场景,有的需要查全表,而有的查询只是需要查一部分数据,如果只查一部分回来的数据直接用Entity接受封装的话,则Entity中会存在大量的null值,这些null值传输给客户端会占用流量,浪费资源,使用VO则可以解决此问题.
创建sprintboot项目如下.(我们创建的是springboot,其实我们写的是mybatis项目)
Server URL:后面我们可以换成https:start.springboot.io 或者https://start.aliyun.com,是因为它自带的不稳定.
导入依赖:
web和sql依赖
然后项目创建成功,我们进行文件的配置
首先是application.properties中进行配置,因为我们此次的微博系统就是使用mybatis和对文件的上传,我们这里是图片文件,所有application,properties的全部配置如下;
spring.datasource.url=jdbc:mysql://localhost:3306/weibo?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
spring.datasource.username=root
spring.datasource.password=root
#配置静态资源文件夹 classpath:static指原来的static文件夹
spring.web.resources.static-locations=file:g:/files,classpath:static
#设置上传文件大小 默认1MB
spring.servlet.multipart.max-file-size=10MB
#配置Mybatis书写SQL语句的xml文件的位置
mybatis.mapper-locations=classpath:mappers/*xml
然后我们配置xml文件,上面最后一行的地址就是xml文件的地址,配置如下
xml文件的代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="这里面放的是对应mapper接口的位置信息">
</mapper>
然后我们创建所有要用到的包,和Mybatis配置类.
MybatisConfig配置类如下:
package cn.tedu.weibo.config;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;
//这里通过注解知道多有的mapper接口都在下面这个包中,扫描这个包就可以
@Configuration
@MapperScan("cn.tedu.weibo.mapper")
public class MybatisConfig {
}
配置完成,我们可以正式的进入项目.
首先我们先明确我们要写的微博项目的功能与实现:
- 1.注册功能
- 2.登录功能
- 3.退出登录功能
- 3,发布微博功能(包括发布文件(图片))(微博在首页展示,无论是否登录都展示)
- 4,评论微博功能
- 5.展示评论的功能
暂时我们就这简单的5个大的功能
1.注册功能
- 1,创建数据库weibo,数据库创建一张User表,和在静态资源文件夹创建一个一个首页(index.html.),里面放两个超链接,分别跳转到登录页面与注册页面.
create database weibo charset=utf8;
use weibo;
create table user(
id int primary key auto_increment,
username varchar(50),
password varchar(50),
nickname varchar(50)
);
- 2,注册页面,我们已经明确我们使用的是异步请求,所有引入vue和Axios框架,然后写我们注册页面的前段代码.
-
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script> <script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
2.1:三个文本输入框,一个按钮,文本输入框中我们要进行数据双向绑定v-model="",按钮中我们要添加点击事件,和reg()方法.@click="reg()" -
<input type="text" v-model="user.username" placeholder="用户名"> <input type="password" v-model="user.password" placeholder="密码"> <input type="text" v-model="user.nickname" placeholder="昵称"> <input type="button" value="注册" @click="reg()">
2.2:我们在data中定义数据,进行数据双向绑定. -
data:{ user:{ username:"",nickname:"",password:"" } },
2.3:然后我们再在mehtods中去绑定reg()方法,使用axios的post方式,向"/reg"地址发出异步post请求,然后把user对象提交过去,服务器放回数据(注册是否成功),成功跳转到首页
reg(){
axios.post("/reg",v.user).then(function (response) {
if(response.data==1){
alert("注册成功")
location.href="/";
}else {
alert("用户名已经存在");
}
})
}
- 3.创建controller.UserController并添加reg方法处理"/reg"请求,返回值int,因为判断登录注册成功,还是用户已经存在,注册不成功
- 4.在pojo的entity包中创建User实体封装接受到的参数.(生成getter和setter还有tostring方法)
- 5,创建UserMapper接口,这个接口中定义我们要实现的方法
- 6然后在mappers的UserMapper.xml配置文件中去写我们的sql语句,这里是注册操作,(注册这个过程我们首先判断数据库有没有这个人,有这个人就不能进行注册了,没有就可以注册,那么我们就需要把注册信息写入数据库,)
6.1:首先我们查询这个人我们查找id,password,和nickname这三个信息就行,为了不浪费内存流量的开销,所有我们在pojo的vo包中创建UserVO接受数据库查询回来的信息.
6.2:同样我们插入的信息中id是自增的,所有我们只插入username,password,nickname所以我们同样在pojo的dto包中创建UserDTO类,接收我们插入的信息.(同样生成getter和setter方法以及tostring)- 7:然后我们就正式的在UserController中处理整个注册事件的流程:
7.1:在UserController中添加注解@Autowired进行自动装配(自动注入)
7.2:使用@RequestBody注解添加方法的参数,这里的参数是我们客户端浏览器传递过来的数据,也就是要插入数据库的数据,所以参数对象是UserDTO
7.3:用UserVO接受我们用sql语句查询到的对象数据,然后判断是否有对象存在,如果存在,那么久用户名已经存在,注册失败,如果不存在,那么就使用mapper.insert(user)进行插入,注册成功.- .8.登录也是同理,只是sql语句进行变换,双向判定的数据不同,传递的对象不一样,登录中我们多传递了一个httpSession session参数,这个参数是将我们查询回来的对象保存到这次会话中, session可以理解为会话,然后有点向map的使用,保存对象,保存进去后,我们在后面都可以取出来用.比如你登录了这个weibo,那么就会保存这次会话,只要你不退出,这次会话就一直保存,里面需要登录才能做的操作都可以做,比如发布微博,评论等等,同样,如果你退出来,那么这次会话也就断开连接,你就不能做登录才能做的操作.
- 所以我们回到首页,我们进行我们登陆后的操作,首页我们的需求如下,登陆之前,页面显示登录注册,登录之后我们显示的是发布微博,退出登陆,所有我们这里会使用v-if和v-else,
- 同样我们需要vue和Axios框架,我们还要在methods同级的地方下添加created:function这个方法,使用axios的get方式向"/currentUser"发出请求,因为created:function是一进入页面就发出请求,然后我们在UserController中处理"/currentUser",使用的是我们保存的session 对象,我们保存的对象如果存在,那么直接能请求到当前登录的用户对象,说明登录了,我们就能请求回来数据,入过不存在,那么就没有登录,就不能请求回来数据,请求回来的数据在data中定义user对象进行接收这个数据,然后把这个数据进行双向绑定,在v-if中判断是否有值,有就说明登录,没有就说明没有登录,然后因为用的v-if和v-else,所以显示的页面也不同.
- 在登录的页面中我们还需要些退出登录和发布微博,所有我们还需要超链到发布微博页面,然后退出登陆在本页面处理.
- 也是使用连接,只是这个超链接可以废除,然后使用绑定@click="logout()"方法退出登陆,绑定后我们在methods中写该方法,该方法用axios的get请求,方式向"/logout"发出请求,修改user对象的值为空,那么就说明没有对象,退出登陆了,所有我们在UserController中处理"/logout",移除这个对象.
2,发布微博
- 1.下面是发布微博,发布微博,首先我们需要在数据库中创建一张微博表,
-
create table weibo( id int primary key auto_increment, content varchar(1000), url varchar(200), created timestamp, user_id int);
- 2然后再在静态资源文件夹创建send.html,这里面要导入前段的三个框架,vue.element-ui.和Axios.我们直接道elementUI中选取照片墙的组件,然后写入我们自己的代码,首先我们先处理好文件的上传,
- 在element_ui中找到如下的组件
- 3.在这个组件中,标签有action="...",这里面是我们进行和Controller绑定的地址,我们在Controller中通过@RequestMapping("...")进行图片的处理,name="..",里面设置上传参数的名称,我们在Controller中相应的处理参数传入的名称要相同.
- 4然后我们开始进行图片的上传,首先我们要在application.properies中配置参数,配置静态资源文件夹,还有设置文件上传的大小.
- 5.然后我们在创建UploadController来进行文件的上传,与删除.文件的上传是上传到我们本机的一个文件夹的位置,所以我们首先客户端上传的文件得到文件的参数,就是name="..."里面的值,作为参数放在文件上传的方法里面.然后我们得到文件的原始文件名,目的是为了得到文件的上传类型,是.txt,还是.png,使用substring和lastIndexOf截取文件的后缀,得到文件类型,然后我们再在本机生成一个位于的标识符,用UUID.randomUUID()进行获取,然后保存到事先准备好的路径就是我们在application.properies中配置的路径,然后就是文件的操作,然后文件的url路径响应给客户端,,在我们的send.html中,我们用handleSucess(response,file,fileList)进行接收响应回来的数据.然后我们就能成功的把图片传到页面,但是现在还不能发布,因为我们还没哟选定发布的方法,我们目前只是选择好了图片,显示到来页面,放在了我们指定的文件夹,发布之前我们都还可以删除更改,所有我们还要在他自带的handleRemove方法里面进行删除图片,我们目前在浏览器端是可以删除的,但是我们发现我们准备的文件夹里面并没有删除,所有我们还要从文件夹中删除,此时通过Axios的get方式向"/remove?url="+响应回来的地址,删除我们在文件夹中的方法,然后我们在UploadController中进行处理这个remove,删除文件夹(磁盘)上的文件.
-
package cn.tedu.weibo.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import java.util.UUID; @RestController public class UploadController { @RequestMapping("/upload") public String upload(MultipartFile pic) throws IOException { //pic代表客户端上传的文件参数,这里的pic和页面html那边的name里面的名称一致 System.out.println("pic = " + pic); //得到图片的原始文件名 String fileName=pic.getOriginalFilename(); System.out.println("原始文件名:"+fileName); //得到原始文件名的后缀 String suffix=fileName.substring(fileName.lastIndexOf(".")); //得到唯一文件名UUID.randomUUID()获取唯一标识符 fileName = UUID.randomUUID()+suffix; System.out.println("唯一文件名:"+fileName); //准备保存图片的路径 String dirPath="d:/files"; //不存在创建,存在不创建 File dirFile=new File(dirPath); if(!dirFile.exists()){ dirFile.mkdirs();//创建文件夹 } //得到文件的完整路径 String filePath=dirPath+"/"+fileName; //把图片保存到上面的路径中 异常抛出 pic.transferTo(new File(filePath)); /*文件上传并保存到磁盘中,这个过程理解 * 先重客户端浏览器页面拿到上传文件的原始文件名,然后我们给这个文件改名,这个名字要唯一,但是要保存原来文件的格式 * 然后再有File把文件写入磁盘,此时我们就要创建一个本机的文件地址,然后传入我们想要保存的地址,这个地址是我们的完整地址 * 这个就是我对文件上传的理解 * 学到的新的内容 * MultipartFile: * UUID.randomUUID():得到文件唯一文件名,获取唯一标识符 * transferTo:把文件保存 * */ //把图片的url路径响应给客户端 /文件名 return "/"+fileName; } @RequestMapping("/remove") public void remove(String url){ //删除磁盘上的文件 new File("d:/files"+url).delete(); } }
- 6,进行微博的发布,在send页面上面添加一个文本框,一个按钮,案例上绑定@click="send()"的方法,然后我们在menthos中进行处理,首先判断我们是否选择了图标,有图片我们才允许上传,然后我们在用Axios的post方式向"weibo/insert"中发出请求,请求回来的数据1,我们Controller中上传成功返回值1,所有为1说有发布完成,回到首页,否则说明没有进行登录,然后去登录页面进行登录.
- 7.到WeiboContrller去对"weibo/insert"的请求进行处理,浏览器响应给我们的就发布微博的路径和内容,所有我们创建weiboDto接收路径和内容的数据,然后我们因为还要判断是否登录,所有还传递一个session参数,用UserVO接收,因为我们开始在登录页面保存进去的时候就是这个类型,用户得到session中保存的对象,然后在创建微博实体类,将weiboDTO中的数据装入weibo实体类,然后在设置当前的时间,和当前用户登录的id.
- 8在mapper中创建WeiboMapper.xml文件,同样引入响应的WeiboMapper地址,在WeiboMapper接口中写我们的插入数据方法,查询所有微博数据的方法,和通过id查找数据的方法,然后我们在xml文件中写查询所有发布的数据的sql语句,和通过id查到的微博的sql语句,和我们插入的sql语句.
- 9.然后在Controller中的weibo/insert中调用插入的方法.
- 10.我们在首页要展示展示我们的所有发布的微博,因为这个是不用登陆一进去就有的数据,所有我们写在created:function()中,通过axios,get向"/weibo/select"发布请求,同样在WeiboController中写一个对应的方法处理"/weibo/select"这个请求,在里面调用查询所有发布微博数据的方法.然后在index.html中获取请求回来的数据,保存到arr数组中,这里用来json的数据格式转换,然后我们在把得到的内容用v_for展示到页面中.
- 11.同时我们在展示W微博的这个过程中我们在创建一个detail.thml页面,进行微博的详情页面展示,用超链接进入这个页面,通过id进入.
- 12.在这个页面中已进入就用我们通过id查找到的那条微博的内容,所有已进入就请求,在created:function中使用Axios.get向"/weibo/selectById"发出请求,然后在Controller中进行处理,调用我们的通过id查到到条微博的方法,,Axios中接收请回来的数据,再在detail.html的data中定义接收数据的对象,然后通过这个定义的对象我们把这天微博的详细内容展示到页面中.
- 13.我们再在detail.html的页面中写一个文本框,一个按钮,按钮绑定点击事件send,然后我们在对send进行发布评论的处理.通过Axios的post向Controller中发去"/comment/insert"请求.
3发布评论
- 1.我们创建CommentController接收send方法发过来的"/comment/insert"处理,这个我们在commentController中创建对于的方法,方法中传入浏览器发过来的参数,评论的内容和评论的那一条微博,然后用CommentDTO进行接收,然后我们还要传入session,因为评论同样要判断是否登录,如果我们先判断是都登录,然后在我们在写登录了的内容,创建评论实体列.把DTO里面的数据装入实体类中,然后设置用户的id,此时用户的id是我们浏览器响应回来的id,然后在用mapper调用插入评论的方法
- 2,创建评论这张表到数据库,就简单地content(内容),user_id(谁进行评论),weibo_id(被评论的那条微博的id),此时我们在detail.html这个页面要展示我们的评论,但是我们想一想,一条微博下面展示的是不是只能对这条微博的评论,而不是数据库中的所有评论,所有我们需要得到weibo_id,这个id我们可以想一想从哪里来,其实它的途径目前我就有两种,一种是和user_id一样,我们之前在展示微博细节的那个方法中查询到过weibo_id,所有我们也可以用装入我们的session中,然后再在我们的commentController中的insert方法中和设置userid一样设置weiboid,然后我们在前端页面中照样在created:function中使用axios的get方式向"/comment/selectByWeiboId"发去请求,此时的请求带参数,带上我上我们weiboId的值,因为我们一条微博下面的评论只能是对这条微博的,因为我们这里参数我们之前进入微博的详情的时候传递过,在地址栏上面能够得到,然后这个又是js语言,所有我们可以截取出来.
- 这里我们在controller中处可以照常传递weiboId
- 3.注意:这里还有一个得到weiboId的方法,这个方法其实才是我们提倡使用的,因为更简单,我们不是在前端页面通过地址栏中的id发请求获取微博详情吗?这个id其实就是我们的weiboId,此时我们可以在我们的send方法中,把我们地址栏中的id赋值给我们的weiboId;同样得到了我们的weiboid
- 这里传递过来的id不是weiboId,而是id,因为我们页面传递过来的是location.search
- 4.得到weiboId的来源以后,我们就可以去后端出来这个请求,我们展示的是所有的评论,所有返回的是List<CommentVO> ,所有我们在CommentMapper接口中定义这个方法,然后再在xml文件中写这个方法的查询语句,最后又返回Controller中调用这个方法,然后把返回的数据发生给前端,然后前端用一个arr数组,接收我们的list集合,这里json数据格式装换,arr在我们的data中有定义,然后在通过v-for,把我们数组中的数据展示到页面中.
整个项目的所有代码的目录结构如下
代码如下
config.MybatisConfig
package cn.tedu.weibo.config;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Repository;
@Configuration
@MapperScan("cn.tedu.weibo.mapper")
public class MybatisConfig {
}
contrller.CommentController
package cn.tedu.weibo.controller;
import cn.tedu.weibo.mapper.CommentMapper;
import cn.tedu.weibo.pojo.dto.CommentDTO;
import cn.tedu.weibo.pojo.entity.Comment;
import cn.tedu.weibo.pojo.vo.CommentVO;
import cn.tedu.weibo.pojo.vo.UserVO;
import cn.tedu.weibo.pojo.vo.WeiboDetailVO;
import com.fasterxml.jackson.databind.util.BeanUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpSession;;
import java.util.List;
@RestController
public class CommentController {
@Autowired(required = false)
CommentMapper mapper;
@RequestMapping("/comment/insert")
public int insert(@RequestBody CommentDTO comment, HttpSession session){
UserVO user=(UserVO) session.getAttribute("user");
WeiboDetailVO wei=(WeiboDetailVO)session.getAttribute("wei");
if(user==null){
return 2;
}
System.out.println("comment = " + comment );
Comment c=new Comment();
BeanUtils.copyProperties(comment,c);
//设置用户的id
c.setUserId(user.getId());
//设置weiboId
c.setWeiboId(wei.getId());
//调用mapper的insert方法
mapper.insert(c);
return 1;
}
@RequestMapping("/comment/selectByWeiboId")
public List<CommentVO> selectByWeiboId(int weiboId){
return mapper.selectByWeiboId(weiboId);
}
}
controller.UploadController
package cn.tedu.weibo.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
@RestController
public class UploadController {
@RequestMapping("/upload")
public String upload(MultipartFile pic) throws IOException {
//pic代表客户端上传的文件参数,这里的pic和页面html那边的name里面的名称一致
System.out.println("pic = " + pic);
//得到图片的原始文件名
String fileName=pic.getOriginalFilename();
System.out.println("原始文件名:"+fileName);
//得到原始文件名的后缀
String suffix=fileName.substring(fileName.lastIndexOf("."));
//得到唯一文件名UUID.randomUUID()获取唯一标识符
fileName = UUID.randomUUID()+suffix;
System.out.println("唯一文件名:"+fileName);
//准备保存图片的路径
String dirPath="d:/files";
//不存在创建,存在不创建
File dirFile=new File(dirPath);
if(!dirFile.exists()){
dirFile.mkdirs();//创建文件夹
}
//得到文件的完整路径
String filePath=dirPath+"/"+fileName;
//把图片保存到上面的路径中 异常抛出
pic.transferTo(new File(filePath));
/*文件上传并保存到磁盘中,这个过程理解
* 先重客户端浏览器页面拿到上传文件的原始文件名,然后我们给这个文件改名,这个名字要唯一,但是要保存原来文件的格式
* 然后再有File把文件写入磁盘,此时我们就要创建一个本机的文件地址,然后传入我们想要保存的地址,这个地址是我们的完整地址
* 这个就是我对文件上传的理解
* 学到的新的内容
* MultipartFile:
* UUID.randomUUID():得到文件唯一文件名,获取唯一标识符
* transferTo:把文件保存
* */
//把图片的url路径响应给客户端 /文件名
return "/"+fileName;
}
@RequestMapping("/remove")
public void remove(String url){
//删除磁盘上的文件
new File("d:/files"+url).delete();
}
}
controller.UserController
package cn.tedu.weibo.controller;
import cn.tedu.weibo.mapper.UserMapper;
import cn.tedu.weibo.pojo.dto.UserDTO;
import cn.tedu.weibo.pojo.dto.UserLoginDto;
import cn.tedu.weibo.pojo.entity.User;
import cn.tedu.weibo.pojo.vo.UserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpSession;
@RestController
public class UserController {
@Autowired(required = false)
UserMapper mapper;
@RequestMapping("/reg")
public int reg(@RequestBody UserDTO user){
System.out.println("user = " + user);
UserVO u=mapper.selectByUsername(user.getUsername());
if(u!=null){
return 2;//用户名已经存在
}
mapper.insert(user);
return 1;
}
@RequestMapping("/login")
public int login(@RequestBody UserLoginDto user, HttpSession session){
System.out.println("user = " + user);
UserVO u=mapper.selectByUsername(user.getUsername());
if(u!=null){
if(user.getPassword().equals(u.getPassword())){
//往session对象中保存(session类似于map集合)
session.setAttribute("user",u);
return 1;
}else {
return 3;
}
}
return 2;
}
@RequestMapping("/currentUser")
public UserVO currentUser(HttpSession session){
//从session拿到我们在login()方法中存入到session里面的数据
return (UserVO) session.getAttribute("user");
}
@RequestMapping("/logout")
public void logout(HttpSession session){
session.removeAttribute("user");
}
}
controller.WeiboController
package cn.tedu.weibo.controller;
import cn.tedu.weibo.mapper.WeiboMapper;
import cn.tedu.weibo.pojo.dto.WeiboDTO;
import cn.tedu.weibo.pojo.entity.User;
import cn.tedu.weibo.pojo.entity.Weibo;
import cn.tedu.weibo.pojo.vo.CommentVO;
import cn.tedu.weibo.pojo.vo.UserVO;
import cn.tedu.weibo.pojo.vo.WeiboDetailVO;
import cn.tedu.weibo.pojo.vo.WeiboListVO;
import com.sun.org.apache.bcel.internal.generic.FADD;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.List;
@RestController
public class WeiboController {
@Autowired(required = false)
WeiboMapper weiboMapper;
@RequestMapping("/weibo/insert")
public int insert(@RequestBody WeiboDTO weibo, HttpSession session){
System.out.println("weibo = " + weibo);
//这里我们在UserController中存入的是userVO类型,所有去除来的时候也是UserVO类型
UserVO user=(UserVO) session.getAttribute("user");
if(user==null){
return 2;
}
//创建微博实体类,并且把DTO里面的数据装进实体类.
Weibo w=new Weibo();
BeanUtils.copyProperties(weibo,w);
//Weibo{id='null', content='微博实体类', url='/808cf2e2-3d78-498f-9066-094af1f9a112.jpg', created=null, userId=null}
//这里输出的是上面这一行,就是没哟值得null输出
System.out.println(w);
//设置当前时间
w.setCreated(new Date());
//设置当前用户登录id
w.setUserId(user.getId());
weiboMapper.insert(w);
return 1;
}
@RequestMapping("/weibo/select")
public List<WeiboListVO> select(){
return weiboMapper.select();
}
@RequestMapping("/weibo/selectById")
public WeiboDetailVO selectById(int id, HttpSession session){
WeiboDetailVO wei=weiboMapper.selectById(id);
session.setAttribute("wei",wei);
return weiboMapper.selectById(id);
}
}
mapper.CommentMapper
package cn.tedu.weibo.mapper;
import cn.tedu.weibo.pojo.entity.Comment;
import cn.tedu.weibo.pojo.vo.CommentVO;
import java.util.List;
public interface CommentMapper {
void insert(Comment comment);
List<CommentVO> selectByWeiboId(int weiboId);
}
mapper.UserMapper
package cn.tedu.weibo.mapper;
import cn.tedu.weibo.pojo.dto.UserDTO;
import cn.tedu.weibo.pojo.vo.UserVO;
public interface UserMapper {
UserVO selectByUsername(String username);
void insert(UserDTO user);
}
mapper.WeiboMapper
package cn.tedu.weibo.mapper;
import cn.tedu.weibo.pojo.entity.Weibo;
import cn.tedu.weibo.pojo.vo.WeiboDetailVO;
import cn.tedu.weibo.pojo.vo.WeiboListVO;
import java.util.List;
public interface WeiboMapper {
void insert(Weibo weibo);
List<WeiboListVO> select();
WeiboDetailVO selectById(int id);
}
pojo.dto.CommentDTO
package cn.tedu.weibo.pojo.dto;
public class CommentDTO {
private String content;
private Integer weiboId;
@Override
public String toString() {
return "CommentDTO{" +
"content='" + content + '\'' +
", weiboId=" + weiboId +
'}';
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Integer getWeiboId() {
return weiboId;
}
public void setWeiboId(Integer weiboId) {
this.weiboId = weiboId;
}
}
pojo.dto.UserDTO
package cn.tedu.weibo.pojo.dto;
public class UserDTO {
//为什么没有id,因为客户端发过来请求是没有id的
private String username;
private String password;
private String nickname;
@Override
public String toString() {
return "UserDTO{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", nickname='" + nickname + '\'' +
'}';
}
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;
}
}
pojo.dto.UserLoginDto
package cn.tedu.weibo.pojo.dto;
public class UserLoginDto {
private String username;
private String password;
@Override
public String toString() {
return "UserLoginDto{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
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;
}
}
WeiboDTO
package cn.tedu.weibo.pojo.dto;
public class WeiboDTO {
private String content;
private String url;
@Override
public String toString() {
return "WeiboDTO{" +
"content='" + content + '\'' +
", url='" + url + '\'' +
'}';
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
entity.Comment
package cn.tedu.weibo.pojo.entity;
public class Comment {
private Integer id;
private String content;
private Integer weiboId;
private Integer userId;
@Override
public String toString() {
return "Comment{" +
"id=" + id +
", content='" + content + '\'' +
", weiboId=" + weiboId +
", userId=" + userId +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Integer getWeiboId() {
return weiboId;
}
public void setWeiboId(Integer weiboId) {
this.weiboId = weiboId;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
}
entity.User
package cn.tedu.weibo.pojo.entity;
public class User {
private Integer id;
private String username;
private String password;
private String nickname;
public User() {
}
public User(Integer id, String username, String password, String nickname) {
this.id = id;
this.username = username;
this.password = password;
this.nickname = nickname;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", nickname='" + nickname + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
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;
}
}
entity.Weibo
package cn.tedu.weibo.pojo.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;
public class Weibo {
private String id;
private String content;
private String url;
private Date created;//发布时间
private Integer userId;//作者id
@Override
public String toString() {
return "Weibo{" +
"id='" + id + '\'' +
", content='" + content + '\'' +
", url='" + url + '\'' +
", created=" + created +
", userId=" + userId +
'}';
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
}
vo.CommentVO
package cn.tedu.weibo.pojo.vo;
public class CommentVO {
private String content;
private Integer id;
private String nickname;
@Override
public String toString() {
return "CommentVO{" +
"content='" + content + '\'' +
", id=" + id +
", nickname='" + nickname + '\'' +
'}';
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
}
vo.UserVO
package cn.tedu.weibo.pojo.vo;
public class UserVO {
//这里面没有用户,因为这里面使我们从数据库里面要查询的内容,不需要用户名
private Integer id;
private String password;
private String nickname;
@Override
public String toString() {
return "UserVO{" +
"id=" + id +
", password='" + password + '\'' +
", nickname='" + nickname + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
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;
}
}
vo.WeiboDetailVO
package cn.tedu.weibo.pojo.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;
public class WeiboDetailVO {
private Integer id;
private String content;
private String url;
private Date created;
private String nickname;
@Override
public String toString() {
return "WeiboDetailVO{" +
"id=" + id +
", content='" + content + '\'' +
", url='" + url + '\'' +
", created=" + created +
", nickname='" + nickname + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
}
vo.WeiboListVO
package cn.tedu.weibo.pojo.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;
public class WeiboListVO {
private Integer id;
private String content;
private String nickname;
/*通过JsonFormat设置时间格式 timezone = "GMT+8"设置为东八区*/
//2022年10月12号 15时24分22秒 2022-10-12 15:24:22
//yyyy年MM月dd号 HH时mm分ss秒 yyyy-MM-dd HH:mm:ss
@JsonFormat(pattern ="yyyy-MM-dd HH:mm:ss",timezone ="GMT+8" )
private Date created;//发布微博的时间
@Override
public String toString() {
return "WeiboListVO{" +
"id=" + id +
", content='" + content + '\'' +
", nickname='" + nickname + '\'' +
", created=" + created +
'}';
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
}
mappers.CommentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.tedu.weibo.mapper.CommentMapper">
<insert id="insert">
insert into comment values(null,#{content},#{weiboId},#{userId})
</insert>
<select id="selectByWeiboId" resultMap="commentRM">
select content,nickname,c.id cid
from comment c join user u
where c.user_id=u.id
and c.weibo_id=#{weiboId}
</select>
<resultMap id="commentRM" type="cn.tedu.weibo.pojo.vo.CommentVO">
<id column="c.id" property="id"></id>
<result column="content" property="content"></result>
<result column="nickname" property="nickname"></result>
</resultMap>
</mapper>
mappers.UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.tedu.weibo.mapper.UserMapper">
<select id="selectByUsername" resultType="cn.tedu.weibo.pojo.vo.UserVO">
select id,nickname,password
from user where username=#{username}
</select>
<insert id="insert">
insert into user values(
null,#{username},#{password},#{nickname}
)
</insert>
</mapper>
mappers.WeiboMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.tedu.weibo.mapper.WeiboMapper">
<insert id="insert">
INSERT INTO weibo VALUES (
null,#{content},#{url},#{created},#{userId}
)
</insert>
<!--这里我们w.id 如果不去做手动映射,name我们就去id这个别名,而不是wid,因为wid需要识别,手动映射-->
<select id="select" resultType="cn.tedu.weibo.pojo.vo.WeiboListVO">
select w.id id,created,content,nickname
from weibo w join user u
on w.user_id=u.id
</select>
<select id="selectById" resultType="cn.tedu.weibo.pojo.vo.WeiboDetailVO" >
select w.id id,created,content,nickname,url
from weibo w join user u
on w.user_id=u.id
where w.id=#{id}
</select>
</mapper>
static.detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<h1>微博详情页面</h1>
<h2>{{weibo.nickname}}说:{{weibo.content}}</h2>
<img :src="weibo.url" width="200" alt="">
<hr>
<h1>评论相关</h1>
<input type="text" v-model="comment.content" placeholder="评论内容...">
<input type="button" value="发表评论" @click="send()">
<h2>评论展示</h2>
<div>
<h3 v-for="comments in arr">
内容:{{comments.content}}<br>
作者昵称:{{ comments.nickname}}
</h3>
</div>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script>
let v=new Vue({
el:"body>div",
data:{
weibo:{},
comment:{
content:"", weiboId:""
},
arr:[]
},
methods:{
send() {
/* //把进入页面请求到weibo对象里面的id取出赋值给评论对象
v.comment.weiboId=v.weibo.id;*/
axios.post("/comment/insert",v.comment).then(function (response) {
if (response.data==1){
alert("评论完成")
location.reload();
}else {
alert("请先登录")
location.href="/login.html"
}
})
}
},
created:function () {
//通过地址栏中的id发请求获取微博详情
axios.get("/weibo/selectById"+location.search).then(function (response) {
v.weibo=response.data;
})
//通过weiboId获取评论内容
axios.get("/comment/selectByWeiboId?weiboId="+location.search.substring(location.search.lastIndexOf("=")+1)).then(function (response){
v.arr=response.data;
})
/* axios.get("/comment/selectByWeiboId"+location.search).then(function (response){
v.arr=response.data;
})
//使用在前端页面获取weiboId的值,我们需要上面的send处理方法中进行赋值,但是我们在后端页面传递的参数也是id,因为location.search获取的是?id=xx
*/
}
})
</script>
</body>
</html>
static.index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>微博首页</title>
</head>
<body>
<div>
<h1>微博首页</h1>
<!--判断user.nickname有值代表登录了-->
<div v-if="user.nickname!=null">
<h2>欢迎{{user.nickname}}回来</h2>
<a href="/send.html">发布微博</a>
<a href="javascript:void(0)" @click="logout()">退出登录</a>
</div>
<div v-else><!--没有登录是显示这个div里面的内容-->
<a href="/reg.html">注册</a>
<a href="/login.html">登录</a>
</div>
<hr>
<div v-for="weibo in arr">
<!--展示微博-->
<h3>
<a :href="'/detail.html?id='+weibo.id">{{weibo.nickname}}说:{{weibo.content}}</a>
<span>{{weibo.created}}</span>
</h3>
</div>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script>
let v=new Vue({
el:"body>div",
data:{
user:{},
arr:[]
},
methods:{
logout(){
//v.user={}.不用谢下面的代码,在页面上看着和下面实现的效果一样,但是服务器中还保存着上一个对象,没有测地的删除,所以一定要在controller中处理logout.
axios.get("/logout").then(function (response) {
//修改user的值,页面会跟着改变
if(confirm("确认退出吗?")){
v.user={};//此时user的值中没有对象,为空对象,都没退出登录了.
}
})
}
},
created:function () {
//发请求获取当前登录的用户对象
axios.get("/currentUser").then(function (response) {
v.user=response.data
})
//发请求获取所有微博数据,展示在页面当中
axios.get("/weibo/select").then(function (response) {
v.arr=response.data;
})
}
})
</script>
</body>
</html>
static.login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
<div>
<h1>登录页面</h1>
<input type="text" placeholder="用户名" v-model="user.username">
<input type="password" placeholder="密码" v-model="user.password">
<input type="button" value="登录" @click="login()">
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script>
let v=new Vue({
el:"body>div",
data:{
user:{
username:"",password:""
}
},
methods:{
login(){
axios.post("/login",v.user).then(function (response) {
if(response.data==1){
alert("登录成功");
location.href='/';
}else if(response.data==2){
alert("用户名不存在");
}else {
alert("密码错误");
}
})
}
}
})
</script>
</body>
</html>
static.reg.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册页面</title>
</head>
<body>
<div>
<h1>注册</h1>
<input type="text" v-model="user.username" placeholder="用户名">
<input type="password" v-model="user.password" placeholder="密码">
<input type="text" v-model="user.nickname" placeholder="昵称">
<input type="button" value="注册" @click="reg()">
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script>
let v=new Vue({
el:"body>div",
data:{
user:{
username:"",nickname:"",password:""
}
},
methods:{
reg(){
axios.post("/reg",v.user).then(function (response) {
if(response.data==1){
alert("注册成功")
location.href="/";
}else {
alert("用户名已经存在");
}
})
}
}
})
</script>
</body>
</html>
static.send.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- import CSS -->
<link rel="stylesheet" href="https://cdn.staticfile.org/element-ui/2.15.9/theme-chalk/index.css">
</head>
<body>
<div id="app">
<input type="text" placeholder="说点什么..." v-model="weibo.content">
<input type="button" value="发布" @click="send()">
<!--action设置上传地址:这里我们改为了/upload,意味着我们往这里发请求
name:设置上传参数的名称
limit:设置上传图片的数量:
:on-success="handleSuccess"我们在vue和axios中我们使用axios得到controller放回的信息,但是el
这个组件自己带有这个方法,就能返回数据
-->
<el-upload
action="/upload"
name="pic"
limit="1"
list-type="picture-card"
:on-success="handleSuccess"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove">
<i class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
<hr>
</div>
</body>
<!--import Axios -->
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
<!-- import Vue before Element -->
<script src="https://cdn.staticfile.org/vue/2.6.14/vue.min.js"></script>
<!-- import JavaScript -->
<script src="https://cdn.staticfile.org/element-ui/2.15.9/index.min.js"></script>
<script>
let v = new Vue({
el: '#app',
data: function() {
return{
dialogImageUrl: '',
dialogVisible: false,
weibo:{
content:"" ,
url:""
}
}
},
methods:{
handleRemove(file, fileList) {
console.log(file, fileList);
//当删除页面中图片时触发的方法
//发请求删除服务器中的图片
//file代表当前删除的图片文件 file.response代表上传该文件成功时服务器响应的内容(当前图片路径)
axios.get("/remove?url="+file.response).then(function () {
console.log("删除服务器图片完成")
})
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
handleSuccess(response,file,fileList){
//response代表服务器上传成功时响应的数据,此处的response和Axios框架发出请求得到的response不同,类似于response.date
//file代表当前上传成功的文件
//fileList代表上传成功的所有文件(是一个数组)
v.weibo.url=response;
},
send(){
if(v.weibo.url==""){
alert("请选择上传的图片");
return;
}
axios.post("/weibo/insert",v.weibo).then(function (response) {
if(response.data==1){
alert("发布完成!");
location.href="/";//回到首页
}else {
alert("请先登录")
location.href="/login.html"
}
})
}
}
})
</script>
</html>
application.properties
# 数据库连接地址(这里换成你自己的数据库,下面的用户名与密码也是)
spring.datasource.url=jdbc:mysql://localhost:3306/weibo?serverTimezone=UTC
# 数据库用户名&密码:
spring.datasource.username=root
spring.datasource.password=root
spring.servlet.multipart.max-file-size=10MB
#这里我用的盘是d盘下面的files文件夹,你可以自己更换,但是controller中同样要换
spring.web.resources.static-locations=file:d:/files,classpath:static
#配置Mybatis书写SQL语句的小xml文件的位置,这个位置也是不确定的,按照自己的路径来
mybatis.mapper-locations=classpath:mappers/*xml
数据库,我们这个项目我创建的是一个叫微博的数据库.然后数据库里面的名字按照pojo.entity中的类型对应创建,表也是按照pojo.entity中的类创建.
对于这个项目的总结,该项目我们主要是使用mybatis框架,然后结合简单的前段框架,在异步请求的情况下进行的一个项目,我们主要做的就是数据库的增删改查,然后就没有什么了,这个项目主要就是带我们了解mybatis和异步请求.