Spring mvc中的异常

做统一处理,全局异常处理器

异常处理类代码: 必须实现接口  然后返回值是ModelAndView  那就可以做个展示页面了

package com.toov5.mvc.utils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView; public class CustomerExceptionResolver implements HandlerExceptionResolver{ public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) { ModelAndView mav = new ModelAndView();
mav.addObject("msg","系统发生异常,请联系管理员!");
mav.setViewName("msg"); return mav;
} }

这个类要告诉 spring mvc  所以要配置下:

    <!-- 全局异常处理器配置 -->
<bean class="com.toov5.mvc.utils.CustomerExceptionResolver"> </bean>

访问controller    1/0的错误

所有页面都返回这个也不是很好~

升级:

更友好 更灵活的

自定义异常 :

自定义异常类:

package com.toov5.mvc.utils;

public class MyException extends Exception {

    private String msg;

    public MyException(String msg) {
super();
this.msg = msg;
} public String getMsg() {
return msg;
} public void setMsg(String msg) {
this.msg = msg;
} }

Controller的使用:

 @RequestMapping("queryVoid")
public void queryVoid(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException, MyException {
response.setCharacterEncoding("utf-8");
//假设这里是根据ID查询商品信息 搜索不到商品
if (true) {
throw new MyException("搜索失败!");
}
int i = 1/0;
PrintWriter writer = response.getWriter();
writer.println("rsponse打印的消息。。。。");
}

访问结果:

小结: 自定异常类   实现全局异常处理器 配置异常处理器

Spring mvc中的图片上传:

配置浏览器访问的 目录   在tomcat配置虚拟目录

本地的目录 映射到配置的虚拟目录

通过:   http://localhost:8080/pic/aa.jpg  可以获取到图片

上传图片需要jar包

配置多媒体解析器:  配置的id也是固定不变的

<!-- 配置多媒体处理器 -->
<!-- 注意:这里id必须填写:multipartResolver -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 最大上传文件大小 -->
<property name="maxUploadSize" value="8388608" />
</bean>

Controller:

@RequestMapping("updateItem")
public String updatItem(Item item, Model model, MultipartFile pictureFile) throws IllegalStateException, IOException { //pictureFile图片名字要对应
//防止被覆盖 图片新名字
String newName = UUID.randomUUID().toString();
String oldName = pictureFile.getOriginalFilename(); //图片原来的名字。
//后缀获取
String sux = oldName.substring(oldName.lastIndexOf("."));
//新建本地文件流
File file = new java.io.File("C:\\Users\\Administrator\\Desktop\\pics\\"+newName+sux);
//写入本地磁盘
pictureFile.transferTo(file); //写入本地磁盘
//保存图片到数据库
item.setPic(newName+sux); model.addAttribute("item",item);
model.addAttribute("msg","修改商品信息成功!");
return "itemEdit"; }

前端:

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>修改商品信息</title> </head>
<body>
<span>${msg}</span>
<!-- 上传图片是需要指定属性 enctype="multipart/form-data" -->
<!-- <form id="itemForm" action="" method="post" enctype="multipart/form-data"> -->
<form id="itemForm" action="${pageContext.request.contextPath }/updateItem.action" method="post" enctype="multipart/form-data">>
<input type="hidden" name="id" value="${item.id }" /> 修改商品信息:
<table width="100%" border=1>
<tr>
<td>商品名称</td>
<td><input type="text" name="name" value="${item.name }" /></td>
</tr>
<tr>
<td>商品价格</td>
<td><input type="text" name="price" value="${item.price }" /></td>
</tr> <tr>
<td>商品生产日期</td>
<td><input type="text" name="createtime"
value="<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>" /></td>
</tr>
<tr>
<td>商品图片</td>
<td>
<c:if test="${item.pic !=null}">
<img src="/pic/${item.pic}" width=100 height=100/>
<br/>
</c:if>
<input type="file" name="pictureFile"/>
</td>
</tr> <tr>
<td>商品简介</td>
<td><textarea rows="3" cols="30" name="detail">${item.detail }</textarea>
</td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="提交" />
</td>
</tr>
</table> </form>
</body> </html>

注意:

前端表格:<form id="itemForm" action="${pageContext.request.contextPath }/updateItem.action" method="post" enctype="multipart/form-data"> >

上传图片时候  前端要注意传输类型    并且是post的 get没办法提交文件 在url拼接

 关于JSON的交互

用JSON不用HTML  解析方便  不占用大量的网络传输量

开发:

jar包

在Controller里面加个

@Responbody

然后 可以返回 对象类型了

页面获取到的是Json字符串!

@RequestMapping("getItem")
@ResponseBody
public Item getItem() {
Item item =itemService.getItemById(3);
return item;
}

传入Json

为啥加了

 @ResponseBody 可以实现json的响应支持?

原因是:

<!-- 配置注解驱动,相当于同时使用最新处理器映射跟处理器适配器,对json数据响应提供支持 同时使用自定义转换器Myconvert-->
<mvc:annotation-driven conversion-service="MyConvert"/>

 

传入JSON:

  @RequestMapping("getItem")
@ResponseBody
public Item getItem(@RequestBody Item item) {
System.out.println(item);
item.setName("张三");
return item;
}

出入的JSON 用Item类型的接受  字段是对应的  并且一定要加注解  @RequestBody

关于Restful  不是协议 也不是标准  是个风格!

//RESTful风格url上的参数通过{}点位符绑定

//点位符参数名与方法参数名不一致时,通过@PathVariable绑定

 @RequestMapping("item/{id}")  //url最后的参数值  被下面的括号中的id获取到
public String itemQuery(@PathVariable Integer id, Model model) {
Item item =itemService.getItemById(id);
model.addAttribute("item",item);
return "itemEdit"; }

用个大括号做个占位符

如果名字不一致 需要稍加改动

 @RequestMapping("item/{id}")  //url最后的参数值  被下面的括号中的id获取到
public String itemQuery(@PathVariable(@PathVariable("id")) Integer idUse, Model model) {

注意区别: @RequestParam 的参数是通过  url?拼接来的

@PathVariable 是url后面占位符的 参数

访问:

http://localhost:8080/SSM01/item/3.action

这里需要加  .action的后缀

修改下Spring mvc 配置文件可以搞定

关于Spring mvc拦截器:

/**  :  拦截所有请求 包括二级以上目录

拦截器:

package com.toov5.mvc.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; public class MyInterceptor implements HandlerInterceptor { public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception { System.out.println("...afterCompletion...");
} public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception { System.out.println(".......postHandle......");
} public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("........preHandle......");
return true; //对拦截请求放行 true放行
} }

进行配置 告诉Spring mvc

    <!-- 全局异常处理器配置 -->
<bean class="com.toov5.mvc.utils.CustomerExceptionResolver"> </bean> <mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.toov5.mvc.interceptor.MyInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>

Controller做标记(观察执行顺序):

    @RequestMapping( value="itemList", method={RequestMethod.POST,RequestMethod.GET})
public ModelAndView itemList() {
ModelAndView mav = new ModelAndView();
List<Item> itemList = itemService.getItemList();
mav.addObject("itemList",itemList);
mav.setViewName("itemList"); //jsp的名字
System.out.println("ItemController.itemList************执行了****************");
return mav;
}

访问后的执行结果:

注意这里修改了 日志的打印级别 否则打印的消息太细致 不容易观察:

详细介绍:

如果多个拦截器在一起呢?

再加一个拦截器 然后进行配置:

package com.toov5.mvc.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; public class MyInterceptor2 implements HandlerInterceptor { //方法执行后被执行 可以处理异常 或者清理资源 或者记录日志等操作
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception { System.out.println("...afterCompletion..2...");
}
//方法执行之后 同时可以获取到 ModelAndView 也就是返回视图之前 被执行
//设置页面的公用参数等操作
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception { System.out.println(".......postHandle..2......");
} //进入方法前被执行 登录拦截 权限校验 然后决定是否放行
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("........preHandle..2......");
return true; //对拦截请求放行 true放行
} }
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.toov5.mvc.interceptor.MyInterceptor"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.toov5.mvc.interceptor.MyInterceptor2"></bean>
</mvc:interceptor>
</mvc:interceptors>

结果:

执行顺序 与 配置中的 顺序有关

一排人  钻山洞  钻进去 没出路 返回的过程了类似

如果第一个拦截器不放行: 只有这个方法执行了  目的地 网页也没有获取到

第一个放行 第二个不放行: 木有获取网页内容   拦截器只要放行 就会执行自己的 afterCompletion  不放行的是不被执行的   两个都执行才执行handler里面的方法

案例: 登录拦截器

如果没有登录 访问别的页面时候 会别拦截 跳转到 登录页面

如果登录了 当前回话里面 随便点击 随便跳转玩儿

拦截器负责拦截 这个请求 看看 session回话里面 有没有 登录信息标记  如果被标记了 就放行  如果没有那就拦截 跳转到登录页面

Jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>用户登录</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/user/login.action">
用户名:<input type="text" name="username" /><br>
密码:<input type="password" name="password" /><br>
<input type="submit">
</form>
</body>
</html>

Controller:

package com.toov5.mvc.controller;

import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
@RequestMapping("user")
public class UserController { @RequestMapping("toLogin")
public String toLogin() {
return"login";
} @RequestMapping("login")
public String login(String username, String password,HttpSession session) {
if (username.equals("admin")) {
session.setAttribute("username", username);
return "redirect:/itemList.action"; //user 下面没有这个请求地址 这个是根目录下面的所以 /需要加上
}
return "login";
} }

拦截器:

package com.toov5.mvc.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; public class LoginInterceptor implements HandlerInterceptor { //方法执行后被执行 可以处理异常 或者清理资源 或者记录日志等操作
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception { System.out.println("...afterCompletion..2...");
}
//方法执行之后 同时可以获取到 ModelAndView 也就是返回视图之前 被执行
//设置页面的公用参数等操作
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception { System.out.println(".......postHandle..2......");
} //进入方法前被执行 登录拦截 权限校验 然后决定是否放行
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception { Object object = request.getSession().getAttribute("username");
if (object == null) {
//这里要写全路径
response.sendRedirect(request.getContextPath()+"/user/toLogin.action");
}
return true; //对拦截请求放行 true放行
} }

mvc配置:

    <mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.toov5.mvc.interceptor.MyInterceptor"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.toov5.mvc.interceptor.MyInterceptor2"></bean>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<!-- 配置不拦截目录 -->
<mvc:exclude-mapping path="/user/**"/> <!-- user打头的都不拦截 -->
<bean class="com.toov5.mvc.interceptor.LoginInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>

后期补充了:

package com.toov5.controller;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView; @Controller
public class HelloController {
@RequestMapping("hello")
public ModelAndView hello(HttpServletRequest request){ ////////////可以很灵活的使用 HttpServletRequest
System.out.println("hello springmvc...");
ModelAndView mav = new ModelAndView();
//设置模型数据,用于传递到jsp
//mav.addObject("msg", "hello springmvc......");
//设置视图名字,用于响应用户
request.setAttribute("msg", "httpservletrequest的内容");
mav.setViewName("/WEB-INF/jsp/hello.jsp"); return mav;
}
}

Springmvc中的一些问题解决的更多相关文章

  1. 在Springmvc中获取properties属性

    一些关键的属性一般都会拿出来作为配置,比如数据库连接等.在springmvc中也提供了获取property的类,比如@Value来获取.我接触spring很浅,基本上都是百度的问题解决方法,百度到@v ...

  2. SpringMvc中的数据校验

    SpringMvc中的数据校验 Hibernate校验框架中提供了很多注解的校验,如下: 注解 运行时检查 @AssertFalse 被注解的元素必须为false @AssertTrue 被注解的元素 ...

  3. 【Spring】SpringMVC中浅析Date类型数据的传递

    在控制器中加入如下代码: @InitBinder public void initBinder(ServletRequestDataBinder bin){ SimpleDateFormat sdf ...

  4. 详解SpringMVC中GET请求

    GET请求概述 GET请求,请求的数据会附加在URL之后,以?分割URL和传输数据,多个参数用&连接.URL的编码格式采用的是ASCII编码,而不是uniclde,所有的非ASCII字符都要编 ...

  5. SpringMVC中使用Interceptor拦截器

    SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那 ...

  6. 如何在springMVC 中对REST服务使用mockmvc 做测试

    如何在springMVC 中对REST服务使用mockmvc 做测试 博客分类: java 基础 springMVCmockMVC单元测试  spring 集成测试中对mock 的集成实在是太棒了!但 ...

  7. springMVC 返回类型选择 以及 SpringMVC中model,modelMap.request,session取值顺序

    springMVC 返回类型选择 以及 SpringMVC中model,modelMap.request,session取值顺序 http://www.360doc.com/content/14/03 ...

  8. SpringMVC中使用Cron表达式的定时器

    SpringMVC中使用Cron表达式的定时器 cron(定时策略)简要说明 顺序: 秒 分 时 日 月 星期 年份 (7个参数,空格隔开各个参数,年份非必须参数) 通配符: , 如果分钟位置为* 1 ...

  9. SpringMVC中使用Json传数据

    在web项目中使用Json进行数据的传输是非常常见且有用的,在这里介绍下在SpringMVC中使用Json传数据的一种方法,在我的使用中,主要包括下面四个部分(我个人喜好使用maven这类型工具进行项 ...

随机推荐

  1. @PostMapping

    @PostMapping映射一个POST请求 Spring MVC新特性 提供了对Restful风格的支持 @GetMapping,处理get请求 @PostMapping,处理post请求 @Put ...

  2. Redis Bloom Filter

    原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11632622.html 背景 比如刷抖音的时候,抖音会不停的推荐新的内容,而它每次推荐时候都要去重,以 ...

  3. webpack 图片文件处理loader

    目录结构: 引用图片: body { /*background: red;*/ /*background: url("../img/test2.jpg"); 小图片*/ backg ...

  4. Kafka长文总结

    Kafka是目前使用较多的消息队列,以高吞吐量得到广泛使用 特点: 1.同时为发布和订阅提供搞吞吐量.Kafka的设计目标是以时间复杂度为O(1)的方式提供消息持久化能力的,即使对TB级别以上数据也能 ...

  5. SpringMvc返回JSON的工作原理。

    一:导入jar包.然后在springmvc.xml中配置上这么一句话 <!-- 能支持springmvc更高级的一些功能,JSR303校验,快捷的ajax,处理JSON数据.映射动态请求 --& ...

  6. PHPthink 配置目录

    系统默认的配置文件目录就是应用目录(APP_PATH),也就是默认的application下面,并分为应用配置(整个应用有效)和模块配置(仅针对该模块有效). ├─application 应用目录 │ ...

  7. 【LeetCode 75】颜色分类

    题目链接 [题解] 维护一个左边界l和一个右边界r 其中0..l-1都是'0' 而 r+1..n-1都是'2' 我们令i=l;i<=r; 枚举每一个a[i]; ①如果a[i]=2.那么把a[i] ...

  8. LOJ 2721 「NOI2018」屠龙勇士——扩展中国剩余定理

    题目:https://loj.ac/problem/2721 1.注意别一输入 p[ i ] 就 a[ i ] %= p[ i ] ,因为在 multiset 里找的时候还需要真实值. 2.注意用 m ...

  9. [CSP-S模拟测试]:math(裴蜀定理)

    题目传送门(内部题22) 输入格式 第一行有$2$个整数$n,k$.第二行有$n$个正整数$a_i$. 输出格式 第一行有一个整数$s$,表示可以生成的非负整数的个数.第二行有$s$个可以生成的非负整 ...

  10. 杂项-Tmod:常见错误提示

    ylbtech-杂项-Tmod:常见错误提示 1.返回顶部 1. The column 'Content' was specified multiple times for 'T'.select a. ...