这部分功能主要是实现发表一条动态并在朋友圈显示的功能。
上图是动态对应的数据库表单,我们每次发动态时,可选的有动态的文字部分或者是图片部分,而时间就是当前时间,own_id通过获取当前登录的用户信息获取。
图片在数据库存储方式选择图片地址拼接方式,中间使用逗号隔开(当然,还可以选择更特殊一点的标记符号,因为我在测试过程中发现,有的图片地址中就含有逗号,这样,我们在从数据库取出来图片字段进行字符串切割时,会把这个图片地址切成多份,那么在页面肯定会显示找不到图片的…)
这部分只是一条插入语句,而且我是通过逆向工程生成的代码,说一这部分没添加代码:
<insert id="insert" parameterType="com.luckysheep.model.Dynamic" >
<!--
WARNING - @mbggenerated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Fri Jun 12 14:10:02 CST 2020.
-->
insert into dynamic (img, own_id,
time_pub, content)
values (#{img,jdbcType=VARCHAR}, #{ownId,jdbcType=INTEGER},
#{timePub,jdbcType=TIMESTAMP}, #{content,jdbcType=LONGVARCHAR})
</insert>
@Override
public void insertDynamtic(Dynamic dynamic) {
dynamicMapper.insert(dynamic);
}
@PostMapping("/pubDynastic")
public String pubDynastic(@RequestParam("imghead1")MultipartFile[] imghead, HttpServletRequest request){
String myText = request.getParameter("myText");
String property = System.getProperty("user.dir");
String picture = "";
if(null != imghead && imghead.length > 0){
for (MultipartFile picFile : imghead) {
if(null != picFile && null != picFile.getOriginalFilename()){
String filePath = property+"\\src\\main\\resources\\static\\img\\"+ picFile.getOriginalFilename();
File fileMdkr = new File(filePath);
if(!fileMdkr.getParentFile().exists()){
fileMdkr.mkdirs();//如果目录不存在,在这里逐层创建
}
try {
//用springMVC把内存图片写入磁盘中
picFile.transferTo(fileMdkr);
} catch (IOException e) {
e.printStackTrace();
}
String sqlPicture = "http://localhost:8080/img/"+picFile.getOriginalFilename();
picture = picture + sqlPicture+",";
}
}
}
picture = picture.substring(0,picture.length()-1);
Dynamic dynamic = new Dynamic();
dynamic.setImg(picture);
dynamic.setTimePub(new Date());
dynamic.setContent(myText);
User user = (User) request.getSession().getAttribute("user");
dynamic.setOwnId(user.getId());
dynamicService.insertDynamtic(dynamic);
return "redirect:/dynamic/dynamiclist";
}
注意,这里使用System.getProperty(“user.dir”)来获取项目路径,springboot用request.getServletContext().getRealPath("/")方法获得的路径不是项目路径,而是c盘下一个tomcat目录路径。而且,图片上传需要用MultipartFile来接收,由于是可能上传多张图片,所以这里选用数组。
具体可参见:org.springframework.web.multipart.MultipartException: The current request is not a multipart request.
<div class="card">
<div class="card-body">
<h4 class="mb-3" style="word-wrap: break-word;font-family: 华文行楷;font-size: large;">写一条动态吧:</h4>
<form id="discrubForm" method="post" th:action="@{/dynamic/pubDynastic}" enctype="multipart/form-data">
<div class="container-fluid">
<div>
<textarea placeholder="写点什么..." name="myText" cols="100%" rows="5" style="width: 95%;word-wrap: break-word;font-family: 华文行楷;font-size: large;"></textarea>
</div>
<div id="preview1"style="float: left; margin-right: 5px" >
<img id="imghead1" style="height: 100%;width: 100%" border=0 th:src="@{/img/12231331132.jpg}">
</div>
<div id="preview2" style="float: left; margin-right: 5px">
<img id="imghead2" style="height: 100%;width: 100%" border=0 th:src="@{/img/12231331132.jpg}">
</div>
<div id="preview3"style="float: left; margin-right: 5px; margin-right: 5px" >
<img id="imghead3" style="height: 100%;width: 100%" border=0 th:src="@{/img/12231331132.jpg}">
</div>
<div id="preview4" style="float: left;">
<img id="imghead4" style="height: 100%;width: 100%" border=0 th:src="@{/img/12231331132.jpg}">
</div>
<div style="margin-top: 50px" align="right">
<input type="file" name="imghead1" onchange="previewImage1(this)" multiple="multiple" />
</div>
</div>
<div align="center">
<button type="submit" class="mt-3 btn waves-effect waves-light btn-success">发表</button>
</div>
</form>
</div>
</div>
function previewImage1(file)
{
var MAXWIDTH = 90;
var MAXHEIGHT = 90;
var t_files = file.files;
if (t_files.length > 4){
alert("最多可传4张...");
return;
}
for (var j = 0; j < t_files.length;j++){
var filetemp = file.files[j];
var reader = new FileReader();
var i = 0;
reader.onload = function(evt){
for (i;i < t_files.length;) {
var div = document.getElementById('preview' + (i + 1));
div.innerHTML = ' + (i + 1) + ' style="width: 100%;height: 100%">';
var img = document.getElementById('imghead' + (i + 1));
img.onload = function () {
var rect = clacImgZoomParam(MAXWIDTH, MAXHEIGHT, img.offsetWidth, img.offsetHeight);
img.width = rect.width;
img.height = rect.height;
img.style.marginTop = rect.top + 'px';
}
img.src = evt.target.result;
break;
}
i++;
}
reader.readAsDataURL(filetemp);
}
}
function clacImgZoomParam( maxWidth, maxHeight, width, height ){
var param = {top:0, left:0, width:width, height:height};
if( width>maxWidth || height>maxHeight )
{
rateWidth = width / maxWidth;
rateHeight = height / maxHeight;
if( rateWidth > rateHeight )
{
param.width = maxWidth;
param.height = Math.round(height / rateWidth);
}else
{
param.width = Math.round(width / rateHeight);
param.height = maxHeight;
}
}
param.left = Math.round((maxWidth - param.width) / 2);
param.top = Math.round((maxHeight - param.height) / 2);
return param;
}
FileReader的使用可以参见这篇文章,我也是第一次用,理解不深,肯定会有比我这种遍历动态填充回显图片的方法,大家可以去找找资料。
HTML5 之 FileReader 方法上传并读取文件 .
上述代码完成后,便可以实现发动态的功能,但是还会有一个问题,那就是点击发送后,页面重定向到朋友圈页面后,我们发的这条新动态的图片加载错误,可能需要刷新好多次才能显示出来:
解决办法:
重写WebMvcConfigurer的addResourceHandlers方法,将我们的服务器存放图片的文件目录添加进入:
@Configuration
public class myWebMvcConfigurer implements WebMvcConfigurer {
@Autowired
private loginInterceptor login;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(login)
.addPathPatterns("/**")
.excludePathPatterns("/manager/login","/manager/loginPage","/user/**","/img/**");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
String path = System.getProperty("user.dir")+"\\src\\main\\resources\\static\\img\\";
registry.addResourceHandler("/img/**").addResourceLocations("file:"+path);
}
}
沉舟侧畔千帆过,病树前头万木春…