javascript
layui上传文件请求接口异常_SpringMVC实现文件上传与下载,拦截器,异常处理
第一章:響應(yīng)數(shù)據(jù)和結(jié)果視圖
1. 返回字符串
Controller方法返回字符串可以指定邏輯視圖的名稱,根據(jù)視圖解析器為物理視圖的地址。
public String sayHello() {
System.out.println("Hello SpringMVC!!");
// 跳轉(zhuǎn)到XX頁面
return "success";
}
UserController:
@Controller@RequestMapping("/user")
public class UserController {
@RequestMapping("testString")
public String testString(Model model){
System.out.println("testString執(zhí)行了!!");
// 模擬從數(shù)據(jù)庫中查詢的數(shù)據(jù)
User user = new User();
user.setUsername("小白");
user.setPassword("123");
model.addAttribute("user",user);
return "success";
}
}
jsp:請求地址
<a href="user/testString">testStringa>success.jsp:EL表達(dá)式取值
測試成功!
${requestScope.user.username}
${requestScope.user.password}
2. 無返回值情況
如果控制器的方法返回值編寫成void,執(zhí)行程序報404的異常,?默認(rèn)查找JSP頁面沒有找到。
默認(rèn)會跳轉(zhuǎn)到?@RequestMapping(value="/initUpdate") initUpdate.jsp的頁面。
可以使用請求轉(zhuǎn)發(fā)或者重定向跳轉(zhuǎn)到指定的頁面
jsp:
<a href="user/testVoid">testVoida>控制器:
/*** 無返回值情況
* 請求轉(zhuǎn)發(fā)一次請求,不用編寫項(xiàng)目的名稱
* 請求重定向二次請求,需要獲取項(xiàng)目名稱
*/
@RequestMapping("testVoid")
public void testVoid(HttpServletRequest req, HttpServletResponse resp) throws Exception {
System.out.println("testVoid執(zhí)行了!!");
// 編寫請求轉(zhuǎn)發(fā)的程序,
// req.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(req,resp);
// 重定向,不能直接進(jìn)WEB-INF的文件夾
resp.sendRedirect(req.getContextPath()+"/index.jsp");
// 設(shè)置中文亂碼
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
// 直接會進(jìn)行響應(yīng)輸出流到頁面!
resp.getWriter().print("你好");
}
請求轉(zhuǎn)發(fā)成功:
重定向:
打開響應(yīng)流頁面:運(yùn)行方式:
3 .返回ModelAndView對象
ModelAndView?對象是 Spring 提供的一個對象,可以用來調(diào)整具體的 JSP 視圖
jsp:
<a href="user/testModelAndView">testModelAndViewa>控制器:
/*** 返回ModelAndView
* @return
*/
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
// 創(chuàng)建ModelAndView對象
ModelAndView mv = new ModelAndView();
System.out.println("testModelAndView方法執(zhí)行了...");
// 模擬從數(shù)據(jù)庫中查詢出User對象
User user = new User();
user.setUsername("小鳳");
user.setPassword("456");
user.setAge(30);
// 把user對象存儲到mv對象中,也會把user對象存入到request對象
mv.addObject("user",user);
// 跳轉(zhuǎn)到success的.jsp頁面
mv.setViewName("success");
return mv;
}
測試結(jié)果:
第二章:SpringMVC框架提供的轉(zhuǎn)發(fā)和重定向
1. forward請求轉(zhuǎn)發(fā)
jsp:
<a href="user/testForward">testForwarda>controller方法返回String類型,想進(jìn)行請求轉(zhuǎn)發(fā)可以編寫成:
控制器:
/*** 使用forward關(guān)鍵字進(jìn)行請求轉(zhuǎn)發(fā)
* "forward:轉(zhuǎn)發(fā)的JSP路徑",不走視圖解析器了,所以需要編寫完整的路徑
* @return
* @throws Exception
*/
@RequestMapping("/testForward")
public String testForward() throws Exception {
System.out.println("testForward...");
// return "forward:/WEB-INF/pages/success.jsp";
return "forward:/WEB-INF/pages/success.jsp";
}
結(jié)果:
2. redirect重定向
jsp:
<a href="user/testRedirect">testRedirecta>控制器:
/*** 重定向
* @return
* @throws Exception
*/
@RequestMapping("/testRedirect")
public String testRedirect() throws Exception {
System.out.println("testRedirect...");
return "redirect:/index.jsp";
// return "redirect:/user/findAll";
}
第三章:SpringMVC響應(yīng)JSON數(shù)據(jù)
@ResponseBody 注解
DispatcherServlet會攔截到所有的資源,導(dǎo)致一個問題就是靜態(tài)資源(img、css、js)也會被攔截到,從而不能被使用。解決問題就是需要配置靜態(tài)資源不進(jìn)行攔截,在springmvc.xml配置文件添加如下配置:
mvc:resources標(biāo)簽配置不過濾
location元素表示webapp目錄下的包下的所有文件
mapping元素表示以/static開頭的所有請求路徑,如/static/a 或者/static/a/b
<mvc:resources location="/css/" mapping="/css/**"/>
<mvc:resources location="/img/" mapping="/img/**"/>
<mvc:resources location="/js/" mapping="/js/**"/>
jsp:
<html>
<head>
<title>Titletitle>
<script type="text/javascript" src="js/jquery-1.7.2.js">script>
<script type="text/javascript">$(function () {$("#btn").click(function () {// alert("hello");
$.ajax({//請求地址
url:"user/testAjax",//表示發(fā)給服務(wù)器的數(shù)據(jù)
data:{"name":"小白","age":18},//響應(yīng)的數(shù)據(jù)類型
dataType: "json",//設(shè)置字符集
contentType:"application/json;charset=UTF-8",//表示請求類型
type: "post",
success:function (data) {alert(data);}});});});script>
head>
<body>
<button id="btn">發(fā)送ajax請求button>
body>
html>
控制器:獲取請求體數(shù)據(jù)
/*** 獲取請求體數(shù)據(jù)
* @return
* @throws Exception
*/
@RequestMapping("/testAjax")
public void testAjax(@RequestBody String body) throws Exception {
System.out.println(body);
}
導(dǎo)入依賴:?json字符串和JavaBean對象互相轉(zhuǎn)換的過程中,需要使用jackson的jar包
<dependency><groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>2.9.0version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>2.9.0version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-annotationsartifactId>
<version>2.9.0version>
dependency>
控制器:將請求過來的字符串轉(zhuǎn)換成JavaBean:
@Controllerpublic class HelloController {
@RequestMapping("/testResponseJson")
public void testResponseJson(@RequestBody User user){
System.out.println("Json字符封裝成javaBean:"+ user);
}
}
控制器:將JavaBean對象轉(zhuǎn)換成Json響應(yīng)到客戶端:
/*** 異步請求
*
* @return
* @throws Exception
*/
@RequestMapping(value = "/testAjax",method = RequestMethod.POST)
public @ResponseBody
User testAjax(@RequestBody User user){
// 客戶端發(fā)送ajax的請求,傳的是json字符串,后端把json字符串封裝到user對象中
System.out.println(user);
// 做響應(yīng),模擬查詢數(shù)據(jù)庫
user.setUsername("小黑");
user.setPassword("123");
//做響應(yīng)
return user;
}
jsp:
<script type="text/javascript">$(function () {$("#btn").click(function () {// alert("hello");$.ajax({//請求地址
url:"user/testAjax",//表示發(fā)給服務(wù)器的數(shù)據(jù)
data:'{"username":"小白","password":"123","age":18}',//響應(yīng)的數(shù)據(jù)類型
dataType: "json",//設(shè)置字符集
contentType:"application/json;charset=UTF-8",//表示請求類型
type: "post",
success:function (data) {alert(data);alert(data.username);alert(data.password);alert(data.age)}});});});script>
第四章:文件上傳與下載
文件上傳前提:
form表單的enctype取值必須是:multipart/form-data
默認(rèn)值是:application/x-www-form-urlencoded)
enctype:是表單請求正文的類型
method屬性取值必須是Post?C 提供一個文件選擇域
當(dāng)form表單的enctype取值不是默認(rèn)值后,request.getParameter()將失效。
依賴導(dǎo)入:
<dependency>
<groupId>commons-fileuploadgroupId>
<artifactId>commons-fileuploadartifactId>
<version>1.3.1version>
dependency>
<dependency>
<groupId>commons-iogroupId>
<artifactId>commons-ioartifactId>
<version>2.4version>
dependency>
jsp:表單:
當(dāng)form表單的enctype取值為Mutilpart/form-data時,請求正文內(nèi)容就變成:每一部分都是MIME類型描述的正文--%>
<form action="user/fileupload" method="post" enctype="multipart/form-data">
選擇文件:<input type="file" name="upload"/><br/>
<input type="submit" value="上傳文件"/>
1.傳統(tǒng)方式文件傳輸:
控制器:
@RequestMapping("/fileupload")public String fileupload(HttpServletRequest req) throws Exception {
System.out.println("測試成功!");
// 使用fileupload組件完成文件上傳
// 上傳的位置
String path = req.getSession().getServletContext().getRealPath("/uploads/");
//創(chuàng)建File對象,一會向該路徑下上傳文件
File file = new File(path);
// 判斷路徑是否存在,如果不存在,創(chuàng)建該路徑
if (!file.exists()) {
file.mkdir();
}
// 解析request對象,獲取上傳文件項(xiàng)
DiskFileItemFactory factory = new DiskFileItemFactory();//磁盤文件項(xiàng)工廠
ServletFileUpload upload = new ServletFileUpload(factory);
//解析request(裝的都是文件項(xiàng))
List<FileItem> items = upload.parseRequest(req);
//遍歷
for (FileItem item: items){
// 進(jìn)行判斷,當(dāng)前item對象是否是上傳文件項(xiàng)
if(item.isFormField()){
// 說明普通表單向
}else {
// 說明上傳文件項(xiàng)
// 獲取上傳文件的名稱
String filename = item.getName();
// 把文件的名稱設(shè)置唯一值,uuid
String uuid = UUID.randomUUID().toString().replace("-", "");
filename = uuid+"_"+filename;
item.write(new File(path,filename));
//刪除臨時文件
item.delete();
}
}
return "success";
}
2.SpringMVC文件傳輸
jsp表單:name必須和MultipartFile的名稱一樣
<h3>SpringMVC方式文件上傳h3><form action="user/fileupload2" method="post" enctype="multipart/form-data">
選擇文件:<input type="file" name="upload" /><br/>
<input type="submit" value="上傳" />
form>
文件解析器配置:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxInMemorySize" value="10485760">property>
bean>
控制器:
@RequestMapping("/fileupload2")public String fileupload2(HttpServletRequest req, MultipartFile upload) throws Exception {
System.out.println("測試成功!");
// 使用fileupload組件完成文件上傳
// 上傳的位置
String path = req.getSession().getServletContext().getRealPath("/uploads/");
//創(chuàng)建File對象,一會向該路徑下上傳文件
File file = new File(path);
// 判斷路徑是否存在,如果不存在,創(chuàng)建該路徑
if (!file.exists()) {
file.mkdir();
}
// 說明上傳文件項(xiàng)
// 獲取上傳文件的名稱
String filename = upload.getName();
// 把文件的名稱設(shè)置唯一值,uuid
String uuid = UUID.randomUUID().toString().replace("-", "");
filename = uuid + "_" + filename;
// 完成文件上傳
upload.transferTo(new File(file,filename));
return "success";
}
3.跨服務(wù)器文件上傳:
在實(shí)際開發(fā)中,我們會有很多處理不同功能的服務(wù)器。(注意:此處說的不是服務(wù)器集群)
應(yīng)用服務(wù)器:?負(fù)責(zé)部署我們的應(yīng)用
數(shù)據(jù)庫服務(wù)器:?運(yùn)行我們的數(shù)據(jù)庫
緩存和消息服務(wù)器:?負(fù)責(zé)處理大并發(fā)訪問的緩存和消息
文件服務(wù)器:?負(fù)責(zé)存儲用戶上傳文件的服務(wù)器。
流程:
1.配置一個新的工程,創(chuàng)建uploads文件夾
2.配置服務(wù)器:
3.導(dǎo)入開發(fā)需要的jar包
<dependency><groupId>com.sun.jerseygroupId>
<artifactId>jersey-coreartifactId>
<version>1.18.1version>
dependency>
<dependency>
<groupId>com.sun.jerseygroupId>
<artifactId>jersey-clientartifactId>
<version>1.18.1version>
dependency>
4.編寫文件上傳的JSP頁面:
<h3>跨服務(wù)器方式文件上傳h3><form action="user/fileupload3" method="post" enctype="multipart/form-data">
選擇文件:<input type="file" name="upload"/><br/>
<input type="submit" value="上傳"/>
form>
5.編寫控制器:
/*** 跨服務(wù)器文件上傳
*
* @param upload
* @return
* @throws Exception
*/
@RequestMapping("/fileupload3")
public String fileupload3( MultipartFile upload) throws Exception {
System.out.println("跨服務(wù)器上傳成功!");
// 使用fileupload組件完成文件上傳
// 定義圖片服務(wù)器的請求路徑
String path = "http://localhost:9090/uploads/";
// 說明上傳文件項(xiàng)
// 獲取上傳文件的名稱
String filename = upload.getName();
// 把文件的名稱設(shè)置唯一值,uuid
String uuid = UUID.randomUUID().toString().replace("-", "");
filename = uuid + "_" + filename;
// 創(chuàng)建客戶端對象
Client client = Client.create();
//連接圖片服務(wù)器
WebResource webResource = client.resource(path + filename);
// 上傳文件
webResource.put(upload.getBytes());
return "success";
}
如果報405:在tomcat配置文件中加入這個參數(shù)
測試上傳成功:
第五章:SpringMVC異常處理
異常處理思路
Controller調(diào)用service,service調(diào)用dao,異常都是向上拋出的,最終由DispatcherServlet找異常處理器進(jìn)行異常的處理。
SpringMVC的異常處理:
jsp:
<h3>異常處理h3><a href="user/testException">testExceptiona>
自定義異常類:
@Datapublic class SysException extends Exception{
//存儲 提示信息
private String message;
public SysException(String message) {
this.message = message;
}
}
自定義異常處理器:實(shí)現(xiàn)HandlerExceptionResolver接口
public class SysExceptionResolver implements HandlerExceptionResolver {/**
* 跳轉(zhuǎn)到具體頁面
*/
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
SysException e = null;
//① a instanceof A:判斷對象a是否是類A的實(shí)例。如果是,返回true;如果不是,返回false。
//② 如果 a instanceof A返回true,則 a instanceof B也返回true.其中,類B是類A的父類。
if (ex instanceof SysException){
//強(qiáng)轉(zhuǎn)(如果ex是SysException的實(shí)例)
e = (SysException) ex;
}else {
e = new SysException("系統(tǒng)維護(hù)中...");
}
// 創(chuàng)建ModelAndView對象
ModelAndView mv = new ModelAndView();
// 把message信息存儲到mv對象中,也會把message對象存入到request域?qū)ο?br /> mv.addObject("message",e.getMessage());
// 跳轉(zhuǎn)到異常頁面.jsp
mv.setViewName("error");
return mv;
}
}
配置異常處理器:
<bean id="sysExceptionResolver" class="cn.codewhite.exception.SysExceptionResolver"/>
控制器:
@Controller@RequestMapping("/user")
public class UserController {
@RequestMapping("/testException")
public String testException() throws SysException{//往瀏覽器拋異常Exception
System.out.println("testException執(zhí)行了!");
//模擬異常
try {
int i = 1 / 0;
} catch (Exception e) {
// 打印異常信息
e.printStackTrace();
// 拋出自定義異常信息
throw new SysException("查詢所有用戶出現(xiàn)了錯誤...");
}
return "success";
}
}
error.jsp:
<h1>${requestScope.message}h1>測試:
結(jié)果:跳轉(zhuǎn)到了異常頁面。
第六章:SpringMVC框架中的攔截器
Spring MVC 的處理器攔截器類似于Servlet開發(fā)中的過濾器Filter,用于對處理器進(jìn)行預(yù)處理和后處理。
可以定義攔截器鏈,連接器鏈就是將攔截器按著一定的順序結(jié)成一條鏈,在訪問被攔截的方法時,攔截器鏈
中的攔截器會按著定義的順序執(zhí)行。
過濾器是Servlet規(guī)范的一部分,任何框架都可以使用過濾器技術(shù)。
攔截器是SpringMVC框架獨(dú)有的。
過濾器配置了/*,可以攔截任何資源。
攔截器只會對控制器中的方法進(jìn)行攔截。
它也是AOP思想的具體應(yīng)用。
我們要想自定義攔截器, 要求必須實(shí)現(xiàn):HandlerInterceptor接口。
過濾器與攔截器區(qū)別:
過濾器是servlet規(guī)范中的一部分,任何java web工程都可以使用
攔截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能用。
過濾器在url-pattern中配置了**/***之后,可以對所有要訪問的資源攔截。
攔截器它是只會攔截訪問的控制器方法,如果訪問的是jsp,html,css,image或者js是不會進(jìn)行攔截的。
1.單個攔截器:
控制器:
@Controller@RequestMapping("/user")
public class UserController {
@RequestMapping("/testInterceptor")
public String testInterceptor(){
System.out.println("testInterceptor!");
return "success";
}
}
1.創(chuàng)建類,實(shí)現(xiàn)HandlerInterceptor接口,重寫需要的方法
/*** @author JUNSHI 405773808@qq.com
* @create 2020-05-30 14:35
*/
public class MyInterceptor1 implements HandlerInterceptor {
/**
* 預(yù)處理 controller方法執(zhí)行前
* return true放行,執(zhí)行下一個攔截器,如果沒有,執(zhí)行controller中的方法
* return false不放行
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("MyInterceptor1執(zhí)行了...");
return true;
}
}
2.在springmvc.xml中配置攔截器類
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/user/*"/>
<bean class="cn.codewhite.interceptor.MyInterceptor1"/>
mvc:interceptor>
mvc:interceptors>
運(yùn)行結(jié)果:
HandlerInterceptor接口中的方法
preHandle方法是controller方法執(zhí)行前攔截的方法
可以使用request或者response跳轉(zhuǎn)到指定的頁面
return true放行,執(zhí)行下一個攔截器,如果沒有攔截器,執(zhí)行controller中的方法。
return false?不放行, 不會執(zhí)行controller中的方法。
postHandle是controller方法執(zhí)行后執(zhí)行的方法,在JSP視圖執(zhí)行前。
可以使用request或者response跳轉(zhuǎn)到指定的頁面
如果指定了跳轉(zhuǎn)的頁面,那么controller方法跳轉(zhuǎn)的頁面將不會顯示。
postHandle方法是在JSP執(zhí)行后執(zhí)行
request或者response不能再跳轉(zhuǎn)頁面了
2.多個攔截器:
多個攔截器執(zhí)行順序:
index.jsp:
<h3>攔截器h3><a href="user/testInterceptor">testInterceptora>
success.jsp:
<h3>執(zhí)行成功!h3>控制器:
@Controller@RequestMapping("/user")
public class UserController {
@RequestMapping("/testInterceptor")
public String testInterceptor(){
System.out.println("testInterceptor!");
return "success";
}
}
攔截器1:
public class MyInterceptor1 implements HandlerInterceptor {/**
* 預(yù)處理 controller方法執(zhí)行前
* return true放行,執(zhí)行下一個攔截器,如果沒有,執(zhí)行controller中的方法
* return false不放行
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("攔截器1:preHandle攔截器攔截了 前111");
return true;
}
/**
* 后處理方法,controller方法執(zhí)行后,success.jsp執(zhí)行之前
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("攔截器1:postHandle方法執(zhí)行了 后111");
}
/**
* success.jsp頁面執(zhí)行后,該方法會執(zhí)行
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("攔截器1:afterCompletion方法執(zhí)行了 最后111");
}
}
攔截器2:
/*** 自定義攔截器2
*/
public class MyInterceptor2 implements HandlerInterceptor {
/**
* 預(yù)處理 controller方法執(zhí)行前
* return true放行,執(zhí)行下一個攔截器,如果沒有,執(zhí)行controller中的方法
* return false不放行
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("攔截器2:preHandle攔截器攔截了 前222");
return true;
}
/**
* 后處理方法,controller方法執(zhí)行后,success.jsp執(zhí)行之前
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("攔截器2:postHandle方法執(zhí)行了 后222");
}
/**
* success.jsp頁面執(zhí)行后,該方法會執(zhí)行
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("攔截器2:afterCompletion方法執(zhí)行了 最后222");
}
}
springmvc.xml:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/user/*"/>
<bean class="cn.codewhite.interceptor.MyInterceptor1"/>
mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="cn.codewhite.interceptor.MyInterceptor2"/>
mvc:interceptor>
mvc:interceptors>
運(yùn)行結(jié)果:
寫在后邊
以上都是SpringMVC的一些重要內(nèi)容,如果需要SSM框架的PDF版筆記可以找我。
總結(jié)
以上是生活随笔為你收集整理的layui上传文件请求接口异常_SpringMVC实现文件上传与下载,拦截器,异常处理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 缠中说禅---三买
- 下一篇: input子系统基础之按键2——inpu