SSM上傳使用者頭像。解決HTTP 400,儲存到本地以及資料庫儲存路徑,在頁面顯示的問題
第一次用SSM上傳使用者圖片,遇到很多問題,這裡逐一記錄:
1.儲存到本地某個資料夾
2.在頁面顯示圖片
3.報錯HTTP 400 bad request
用maven搭建的專案,結構如圖:
主要是實體類裡面的合作伙伴需要實現上傳圖片並顯示出來(String t_url用來儲存圖片路徑)
實體類
public class Coorperativepartner { int t_id; String t_name; String t_url; Date t_createtime; Date t_updatetime; /*private MultipartFile file; public MultipartFile getFile() { return file; } public void setFile(MultipartFile file) { this.file = file; }*/ public int getT_id() { return t_id; } public void setT_id(int t_id) { this.t_id = t_id; } public String getT_name() { return t_name; } public void setT_name(String t_name) { this.t_name = t_name; } public String getT_url() { return t_url; } public void setT_url(String t_url) { this.t_url = t_url; } public Date getT_createtime() { return t_createtime; } public void setT_createtime(Date t_createtime) { this.t_createtime = t_createtime; } public Date getT_updatetime() { return t_updatetime; } public void setT_updatetime(Date t_updatetime) { this.t_updatetime = t_updatetime; } }
Dao層 只需要看add
import java.util.List; import org.apache.ibatis.annotations.Param; import com.atnews.Entity.Coorperativepartner; public interface CoorperativepartnerMapper { //錕酵夥拷錕叫憋拷 public List<Coorperativepartner> selectCoorperativepartnerList(); //錕斤拷玫錕斤拷錕斤拷錕斤拷錕斤拷錕斤拷錕斤拷息 public Coorperativepartner selectCoorperativepartnerById(Integer id); //刪錕斤拷 public int deleteCoorperativepartnerById(Integer id); //淇敼淇℃伅 public int updateCoorperativepartner(Coorperativepartner coorperativepartner); //鏂板鍚堜綔浼欎即 public int addCoorperativepartner(Coorperativepartner coorperativepartner); //顯示所有合作伙伴圖片 public List<String> getAlllogo(); //通過名稱查詢 public Coorperativepartner selectCoorperativepartnerByName(@Param("name")String name); }
Service層 只需要看add
@Service public class CoorperativepartnerService implements CoorperativepartnerMapper { @Autowired private CoorperativepartnerMapper coorperativepartnerMapper; //錕斤拷取錕斤拷錕斤拷錕斤拷錕斤拷錕斤拷錕斤拷錕斤拷息 public Coorperativepartner selectCoorperativepartnerById(Integer id) { Coorperativepartner coorperativepartner=this.coorperativepartnerMapper.selectCoorperativepartnerById(id); return coorperativepartner; } //刪錕斤拷 public int deleteCoorperativepartnerById(Integer id) { int flag=0; flag=this.coorperativepartnerMapper.deleteCoorperativepartnerById(id); System.out.println("flag="+flag); return flag; } //鏇存柊 public int updateCoorperativepartner(Coorperativepartner coorperativepartner) { int flag=0; flag=this.coorperativepartnerMapper.updateCoorperativepartner(coorperativepartner); System.out.println("flag="+flag); return flag; } //鏂板 public int addCoorperativepartner(Coorperativepartner coorperativepartner) { int flag=0; flag=this.coorperativepartnerMapper.addCoorperativepartner(coorperativepartner); System.out.println("flag="+flag); return flag; } //顯示所有資訊 public List<Coorperativepartner> selectCoorperativepartnerList() { return this.coorperativepartnerMapper.selectCoorperativepartnerList(); } //顯示所有合作伙伴圖片 public List<String> getAlllogo() { return this.coorperativepartnerMapper.getAlllogo(); } public Coorperativepartner selectCoorperativepartnerByName(String name) { Coorperativepartner coorperativepartner=this.coorperativepartnerMapper.selectCoorperativepartnerByName(name); return coorperativepartner; } }
Mapper.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="com.atnews.Dao.CoorperativepartnerMapper">
<!-- 獲得所有資訊 -->
<select id="selectCoorperativepartnerList" resultType="com.atnews.Entity.Coorperativepartner">
select * from xbh_cooperativepartner
</select>
<!-- 獲得所有logo -->
<select id="getAlllogo" resultType="String">
select t_url from xbh_cooperativepartner
</select>
<!-- 查詢單個使用者通過ID -->
<select id="selectCoorperativepartnerById" parameterType="Integer" resultType="com.atnews.Entity.Coorperativepartner">
select * from xbh_cooperativepartner where t_id=#{id}
</select>
<!-- 查詢單個使用者通過名稱 -->
<select id="selectCoorperativepartnerByName" parameterType="String" resultType="com.atnews.Entity.Coorperativepartner">
select * from xbh_cooperativepartner where t_name=#{name}
</select>
<!-- 刪除 合作伙伴-->
<delete id="deleteCoorperativepartnerById" parameterType="Integer">
delete from xbh_cooperativepartner where t_id=#{id}
</delete>
<!-- 新增合作伙伴 -->
<insert id="addCoorperativepartner" parameterType="com.atnews.Entity.Coorperativepartner">
insert into xbh_cooperativepartner(t_name,t_url) values(#{t_name},#{t_url})
</insert>
<!-- 修改合作伙伴 -->
<update id="updateCoorperativepartner" parameterType="com.atnews.Entity.Coorperativepartner" >
update xbh_cooperativepartner set t_name=#{t_name},t_url=#{t_url} where t_id=#{t_id}
</update>
</mapper>
Contronller層 重點是controller裡面的add方法
第一種方法:由於實體類的欄位較少,ID自動遞增,建立和修改時間是其他方法實現,所以在新增的時候只需要管名稱和圖片,所以用每個欄位傳引數的方法來實現新增,對照前端頁面來看傳遞過來的引數
@RequestMapping(value="/addCoorperativepartner")
public String addCoorperativepartner(@RequestParam("t_url")MultipartFile file,@RequestParam("t_name")String t_name, HttpServletRequest request,Model model)throws IOException{
//檔案不為空
if(!file.isEmpty()){
Coorperativepartner coorperativepartner=new Coorperativepartner();
coorperativepartner.setT_name(t_name);
//得到原始名稱
String originalFilename = file.getOriginalFilename();
// 儲存到本地路勁
String dirPath = "D:\\upload";
String newFilename =t_name+"_"+originalFilename;
//儲存圖片路徑
coorperativepartner.setT_url(newFilename);
System.out.println("dirPath:"+dirPath);
File filePath = new File(dirPath,newFilename);
// 若檔案不存在則建立
if (!filePath.exists()) {
filePath.mkdirs();
}
System.out.println("newFilename:"+newFilename);
file.transferTo(filePath);
int rows=this.coorperativepartnerService.addCoorperativepartner(coorperativepartner);
System.out.println("rows="+rows);
return "redirect:/Coorperativepartner/getAllCoorperativepartner";
}
else{
return "error";
}
}
PS:上傳到D:\upload
jsp頁面,程式碼懶得減少了,直接copy過來的,樣式表,程式碼縮排沒有整理
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="Content-Type" content="multipart/form-data;charset=UTF-8" />
<title>AdminLTE 2 | Data Tables</title>
<jsp:include page="link.jsp"></jsp:include>
<link
href="<%=basePath %>res/umeditor1.2.3/themes/default/css/umeditor.css"
type="text/css" rel="stylesheet">
<link
href="<%=basePath %>res/bootstrap-datetimepicker/css/bootstrap-datetimepicker.min.css"
rel="stylesheet">
<link
href="<%=basePath %>res/bootstrap-datetimepicker/css/bootstrap-datetimepicker-standalone.css"
rel="stylesheet">
</head>
<body class="hold-transition skin-blue sidebar-mini">
<div class="wrapper">
<jsp:include page="header.jsp"></jsp:include>
<!-- Left side column. contains the logo and sidebar -->
<jsp:include page="sidebar.jsp"></jsp:include>
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<jsp:include page="infoHead.jsp">
<jsp:param value="合作伙伴資料新增" name="title" />
<jsp:param value="在這裡你可以新增合作伙伴資料" name="subTitle" />
</jsp:include>
<!-- Main content -->
<section class="content">
<div class="row">
<div class="col-xs-12">
<div class="box">
<div class="box-header">
<h3 class="box-title">合作伙伴資料新增表單</h3>
</div>
<!-- /.box-header -->
<div class="box-body">
<form enctype="multipart/form-data"
name="Coorperativepartner"
class="form-horizontal"
>
<div class="box-body">
<div class="form-group">
<label class="col-xs-1 control-label">名稱:</label>
<div class="col-xs-6 input-group">
<input name="t_name" type="text" class="form-control"
placeholder="名稱">
</div>
</div>
<div class="form-group">
<label class="col-xs-1 control-label">圖片:</label>
<div class="col-xs-6 input-group">
<input name="t_url" type="file" class="form-control" id="t_url"
placeholder="圖片">
</div>
</div>
<!-- /.box-body -->
<input type="button" value="新增" onclick="createCoorperativepartner()">
<!-- /.box-footer -->
</form>
</div>
<!-- /.box-body -->
</div>
</div>
<!-- /.col -->
</div>
<!-- /.row -->
</section>
<!-- /.content -->
</div>
<!-- /.content-wrapper -->
<jsp:include page="footer.jsp"></jsp:include>
</div>
<!-- ./wrapper -->
<jsp:include page="js.jsp"></jsp:include>
<script
src="<%=basePath %>res/bootstrap-datetimepicker/js/moment.min.js"></script>
<script
src="<%=basePath %>res/bootstrap-datetimepicker/js/moment-with-locales.min.js"></script>
<script
src="<%=basePath %>res/bootstrap-datetimepicker/js/bootstrap-datetimepicker.min.js"></script>
<!-- 配置檔案 -->
<script type="text/javascript" src="<%=basePath %>res/umeditor1.2.3/third-party/template.min.js"></script>
<script type="text/javascript"
src="<%=basePath %>res/umeditor1.2.3/umeditor.config.js"></script>
<!-- 編輯器原始碼檔案 -->
<script type="text/javascript"
src="<%=basePath %>res/umeditor1.2.3/umeditor.js"></script>
<script type="text/javascript" src="<%=basePath %>res/umeditor1.2.3/lang/zh-cn/zh-cn.js"></script>
</body>
</html>
<script type="text/javascript">
function check(){
var file=document.getElementById("t_url").value;
if(file==""||file.length==0){
alert("請選擇上傳檔案!");
return false;
}
var img_id=document.getElementById("t_url").value; //根據id得到值
var index= img_id.indexOf("."); //得到"."在第幾位
img_id=img_id.substring(index); //截斷"."之前的,得到字尾
if(img_id!=".bmp"&&img_id!=".png"&&img_id!=".gif"&&img_id!=".jpg"&&img_id!=".jpeg"){ //根據字尾,判斷是否符合圖片格式
alert("不是指定圖片格式,重新選擇");
document.getElementById('movie_img').value=""; // 不符合,就清除,重新選擇
return false;
}
alert("file"+file);
return true;
}
//建立合作伙伴
function createCoorperativepartner() {
var result=check();
if(result==true){
var form = document.forms[0];
form.action = "<%=basePath %>Coorperativepartner/addCoorperativepartner";
form.method = "post";
form.submit();
}
else{
alert("上傳圖片失敗!");
}
}
</script>
重點是表單中需要新增:
<form enctype="multipart/form-data"以及需要注意的是標籤的name屬性<input name="t_name" type="text" class="form-control"
placeholder="名稱">,<input name="t_url" type="file" class="form-control" id="t_url"
placeholder="圖片">
頁面顯示:(哈哈哈,技術不過關,在上傳的時候還沒有實現圖片預覽)
新增之後的顯示頁面:
顯示介面的jsp:(直接貼上了顯示的關鍵部分)
<thead>
<tr>
<th>合作伙伴id</th>
<th>合作伙伴名稱</th>
<!--<th>合作伙伴建立時間</th>
<th>合作伙伴修改時間</th>-->
<th>合作伙伴圖片</th>
</tr>
</thead>
<tbody>
<c:forEach items="${coorperativepartners }" var="item">
<tr>
<td>${item.t_id }</td>
<td>${item.t_name }</td>
<!-- <td>${item.t_createtime }</td>
<td>${item.t_updatetime }</td> -->
<td>
<c:if test="${item.t_url !=null }">
<img id="images" class="logo" alt="logo" src="/images/${item.t_url }">
</c:if>
</td>
<td>${item.t_url }</td>
<td>
<button onclick="toEdit(${item.t_id})" type="button" class="btn btn-default ">
<i class="fa fa-edit"></i>編輯
</button>
<button onclick="deleteCoorperativepartner(${item.t_id})" type="button" class="btn btn-default ">
<i class="fa fa-close"></i>刪除
</button>
</td>
</tr>
</c:forEach>
</tbody>
全是自己試過的程式碼,這種情況下不會報HTTP 400的錯誤,檔案也上傳成功顯示成功。但是問題來了,如果遇到實體類屬性很多的,那麼通過這種傳遞每一個具體的屬性引數過來,這也太麻煩,不省事了吧。網上也有很多方法,我也嘗試過,如下:
@RequestMapping(value="/addCoorperativepartner")
public String addCoorperativepartner(MultipartFile file,Coorperativepartner coorperativepartner, HttpServletRequest request,Model model)throws IOException{
//判斷檔案是否存在
if(!file.isEmpty()){
//得到原始名
String originalFilename = file.getOriginalFilename();
//這裡是上傳到Tomcat的釋出路徑下面,反正很長,也不是我想要的儲存到磁碟上某個位置
//這個最後再來說改上傳位置的問題,哈哈哈
//F:\Java neon_demo\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\news....
String dirPath = request.getServletContext().getRealPath("/upload/");
File filePath = new File(dirPath);
// 不存在則建立
if (!filePath.exists()) {
filePath.mkdirs();
}
// 使用UUID命名
String newFilename =UUID.randomUUID() +"_"+originalFilename;
file.transferTo(new File(dirPath + newFilename));
coorperativepartner.setT_url(newFilename);
int rows=this.coorperativepartnerService.addCoorperativepartner(coorperativepartner);
System.out.println("rows="+rows);
return "redirect:/Coorperativepartner/getAllCoorperativepartner";
}
else{
return "demo";
}
}
這個時候上傳就會出現HTTP 400 bad request的錯誤,即使我加上了@RequestParam("t_url")MultipartFile file也會報錯
HTTP 400 bad request錯誤的主要原因:jsp的form表單提交的欄位型別和後臺接收欄位型別不匹配造成的(例如,form中為String,後臺接收為Integer)也可能是引數傳過來的順序錯誤
可是已經一樣了啊,也說明了引數,那麼為什麼會報錯?怎麼看傳過來的具體引數型別和順序?我也很想知道。莫法,繼續改吧......
其實改動的只需要一丟丟地方,就是在form表單中的上傳檔案的name屬性的值改下就行,不與pojo 的屬性名衝突就行。
我這裡就是name與屬性名一樣了 private String t_url;
<input name="t_url" type="file" class="form-control" id="t_url"
placeholder="圖片">
只要這兩個不一致就行,親測有效。
最後來記錄一下上傳到本地某個位置:
1.雙擊server
2.點選modules
3.點選add external
之後顯示圖片就可以直接這樣寫了:<img id="images" class="logo" alt="logo" src="/images/${item.t_url }">
如果不想這樣修改,也可以直接在Tomcat的conf檔案裡面修改server.xml配置檔案:
把檔案存放路徑目錄對映到tomcat中,方法如下:
1、找到tomcat的配置檔案(\conf\server.xml)並開啟
2、在【host】與【/host】之間加入如下程式碼:【<Context path="/file" docBase="E:\test" debug="0" reloadable="true"/>】其中:【path】就是對映的路徑,【docBase】就是你的檔案所在路徑
3、呼叫方法:【E:\test】下有一張test.jpg的圖片
【img 標籤中的src改為“/file/test.jpg”】
4、測試ok