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. hive之压缩

    对数据进行压缩可以节约磁盘空间,提高系统吞吐量和性能,但是压缩和解压缩会增加CPU的开销. 1.hive的压缩编/解码器 BZip2和GZip压缩率高,但是需要消耗较多的CPU开销.LZO和Snapp ...

  2. 使用yum命令报错

    树莓派(Raspberry Pi 3) centos7使用yum命令报错File "/usr/bin/yum", line 30 except KeyboardInterrupt, ...

  3. 网络体系应用层之万维网、http协议

    1.万维网概述 万维网以客户--服务器方式工作,万维网客户程序就是各式各样的浏览器,万维网文档所驻留的主机则运行服务器程序, 因此这个主机也称为万维网服务器.客户程序向服务器程序发出请求,服务器程序向 ...

  4. LOJ 2979 「THUSCH 2017」换桌——多路增广费用流

    题目:https://loj.ac/problem/2979 原来的思路: 优化连边.一看就是同一个桌子相邻座位之间连边.相邻桌子对应座位之间连边. 每个座位向它所属的桌子连边.然后每个人建一个点,向 ...

  5. window使用

    运行命令 regedit #注册表编译器 firewall.cpl #打开防火墙配置 powershell #打开powershell control #打开控制面版 cnpa.cpl #打开网络设置 ...

  6. 前端每日实战:19# 视频演示如何用纯 CSS 创作一种有削铁如泥感觉的菜单导航特效

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/XqYroe 可交互视频教程 此视频 ...

  7. Activator.CreateInstance with parameters

    https://docs.microsoft.com/en-us/dotnet/api/system.activator.createinstance?view=netframework-4.8#Sy ...

  8. MySQL新建数据库时utf8_general_ci编码解释

    utf8_unicode_ci和utf8_general_ci对中英文来说没有实质的差别.utf8_general_ci: 校对速度快,但准确度稍差.utf8_unicode_ci: 准确度高,但校对 ...

  9. 105、TensorFlow的变量(一)

    import tensorflow as tf mammal = tf.Variable("Elephant", tf.string) ignition = tf.Variable ...

  10. vue搭建项目之设置axios

    首先要下载axios: npm install axios -S 要注意的是,axios不支持Vue.use();这种方式,可以改写原型链. 第二步就是新建axios存放位置: 在项目中src中单独建 ...