Springmvc中的一些问题解决
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中的一些问题解决的更多相关文章
- 在Springmvc中获取properties属性
一些关键的属性一般都会拿出来作为配置,比如数据库连接等.在springmvc中也提供了获取property的类,比如@Value来获取.我接触spring很浅,基本上都是百度的问题解决方法,百度到@v ...
- SpringMvc中的数据校验
SpringMvc中的数据校验 Hibernate校验框架中提供了很多注解的校验,如下: 注解 运行时检查 @AssertFalse 被注解的元素必须为false @AssertTrue 被注解的元素 ...
- 【Spring】SpringMVC中浅析Date类型数据的传递
在控制器中加入如下代码: @InitBinder public void initBinder(ServletRequestDataBinder bin){ SimpleDateFormat sdf ...
- 详解SpringMVC中GET请求
GET请求概述 GET请求,请求的数据会附加在URL之后,以?分割URL和传输数据,多个参数用&连接.URL的编码格式采用的是ASCII编码,而不是uniclde,所有的非ASCII字符都要编 ...
- SpringMVC中使用Interceptor拦截器
SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那 ...
- 如何在springMVC 中对REST服务使用mockmvc 做测试
如何在springMVC 中对REST服务使用mockmvc 做测试 博客分类: java 基础 springMVCmockMVC单元测试 spring 集成测试中对mock 的集成实在是太棒了!但 ...
- springMVC 返回类型选择 以及 SpringMVC中model,modelMap.request,session取值顺序
springMVC 返回类型选择 以及 SpringMVC中model,modelMap.request,session取值顺序 http://www.360doc.com/content/14/03 ...
- SpringMVC中使用Cron表达式的定时器
SpringMVC中使用Cron表达式的定时器 cron(定时策略)简要说明 顺序: 秒 分 时 日 月 星期 年份 (7个参数,空格隔开各个参数,年份非必须参数) 通配符: , 如果分钟位置为* 1 ...
- SpringMVC中使用Json传数据
在web项目中使用Json进行数据的传输是非常常见且有用的,在这里介绍下在SpringMVC中使用Json传数据的一种方法,在我的使用中,主要包括下面四个部分(我个人喜好使用maven这类型工具进行项 ...
随机推荐
- @PostMapping
@PostMapping映射一个POST请求 Spring MVC新特性 提供了对Restful风格的支持 @GetMapping,处理get请求 @PostMapping,处理post请求 @Put ...
- Redis Bloom Filter
原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11632622.html 背景 比如刷抖音的时候,抖音会不停的推荐新的内容,而它每次推荐时候都要去重,以 ...
- webpack 图片文件处理loader
目录结构: 引用图片: body { /*background: red;*/ /*background: url("../img/test2.jpg"); 小图片*/ backg ...
- Kafka长文总结
Kafka是目前使用较多的消息队列,以高吞吐量得到广泛使用 特点: 1.同时为发布和订阅提供搞吞吐量.Kafka的设计目标是以时间复杂度为O(1)的方式提供消息持久化能力的,即使对TB级别以上数据也能 ...
- SpringMvc返回JSON的工作原理。
一:导入jar包.然后在springmvc.xml中配置上这么一句话 <!-- 能支持springmvc更高级的一些功能,JSR303校验,快捷的ajax,处理JSON数据.映射动态请求 --& ...
- PHPthink 配置目录
系统默认的配置文件目录就是应用目录(APP_PATH),也就是默认的application下面,并分为应用配置(整个应用有效)和模块配置(仅针对该模块有效). ├─application 应用目录 │ ...
- 【LeetCode 75】颜色分类
题目链接 [题解] 维护一个左边界l和一个右边界r 其中0..l-1都是'0' 而 r+1..n-1都是'2' 我们令i=l;i<=r; 枚举每一个a[i]; ①如果a[i]=2.那么把a[i] ...
- LOJ 2721 「NOI2018」屠龙勇士——扩展中国剩余定理
题目:https://loj.ac/problem/2721 1.注意别一输入 p[ i ] 就 a[ i ] %= p[ i ] ,因为在 multiset 里找的时候还需要真实值. 2.注意用 m ...
- [CSP-S模拟测试]:math(裴蜀定理)
题目传送门(内部题22) 输入格式 第一行有$2$个整数$n,k$.第二行有$n$个正整数$a_i$. 输出格式 第一行有一个整数$s$,表示可以生成的非负整数的个数.第二行有$s$个可以生成的非负整 ...
- 杂项-Tmod:常见错误提示
ylbtech-杂项-Tmod:常见错误提示 1.返回顶部 1. The column 'Content' was specified multiple times for 'T'.select a. ...