@RequestBody+日期转换+异常处理+图片上传

@RequestBody注解

1、@requestBody注解常用来处理content-type不是默认的application/x-www-form-urlcoded编码的内容,比如说:application/json或者是application/xml等。一般情况下来说常用其来处理application/json类型。

2、通过@requestBody可以将请求体中的JSON字符串绑定到相应的bean上,当然,也可以将其分别绑定到对应的字符串上。

@RequestBody String rebody可以接收参数,但是不方便处理

@ResponseBody
	@RequestMapping("/demo01.do")
	public String demo1(@RequestBody String rebody,HttpServletRequest req) throws UnsupportedEncodingException {
		String contentType = req.getContentType();
		System.out.println(contentType);
		System.out.println(rebody);
		return "/jsp/index.jsp";
	}
<form action="<c:url  value='/demo01.do' />" method="POST">
		学号:<input  type="text" name="sid" value="" /><br>
		姓名:<input type="text" name="sname" value=""><br>
		<input type="button" value="确认"  id="btn"/>
	</form>

运行结果为:

rebody:sid=1&sname=zhangsan

@RequestBody Student student

请求体的JSON数据转换成对象

需要注意的是,JSON字符串中的key必须对应Student实体类中的属性名,否则是请求不过去的。

$.ajax({
			url:"<c:url  value='/demo02.do' />",
			contentType:"application/json;charset=utf-8",
			type:"post",
			data:'{"sid":"1","sname":"aa","sage":"18","ssex":"女","cid":"2"}',
			success:function(data){
				alert(data);
			}
		})
@ResponseBody
	@RequestMapping("/demo02.do")
	public String demo2(@RequestBody Student student){	
		System.out.println(student);
		return "ok";
	}

运行结果为:

Student [sid=1, sname=aa, sage=18, ssex=女, cid=2]

日期转换

Structs,SpringMVC这些MVC的框架都不会自己实现日期转换,日期格式无法统一

自定义日期转换器

自定义日期转换类实现Converter接口

/*类型转换器引入
	为什么页面上输入”12”,可以赋值给Handler方法对应的参数?
	这是因为框架内部帮我们做了类型转换的工作。将String转换成int
 	但默认类型转换器并不是可以将用户提交的String,转换为用户需要的所有类型。此时 ,就需要自定义类型转换器了
	案例:自定义日期类型转换器
	要求日期格式为:yyyy/MM/dd
 */
public class DateConverter implements Converter<String, Date>{

	@Override
	public Date convert(String source) {
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		//判断传过来的参数数据有效性
		if(source!=null && !source.isEmpty()) {
			try {
				//将String转换成对应格式的Date类型
				Date date = df.parse(source);
				return date;
			} catch (ParseException e) {
				e.printStackTrace();
				//将受查异常转换成非受查异常
				throw new  RuntimeException(e);
			}
		}
		return null;
	}
}

springmvc.xml配置

<!-- 日期转换 -->
		<!-- 注册转换器 -->
		<bean id="dateConverter" class="com.woniu.converter.DateConverter"></bean>
		<!-- 配置自定义的转换服务ConversionServiceFactoryBean -->
		<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
			<property name="converters">
				<set>
					<ref bean="dateConverter"/>
				</set>
			</property>
		</bean>
		<!-- 装配自定义的转换器 -->
		<mvc:annotation-driven conversion-service="conversionService"/>

异常处理

配置统一异常处理

SimpleMappingExceptionResolver

​ spring的简单异常处理类,当然也可以自己去实现HandlerExceptionResolver接口作为异常处理类,利用spring的异常处理机制,就可以在代码中不去捕获异常而是向上层抛出,再显示层再去处理,同时也可以计入日志文件。以下是简单的异常处理配置

springmvc.xml配置

<!-- spring统一异常处理:SimpleMappingExceptionResolver -->
		<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
			<!-- 统一异常处理页面 -->
			<property name="defaultErrorView" value="/jsp/error.jsp" />
			<!-- 定义异常页面用来获取异常信息的变量名,如果不设置,默认的变量名为exception -->
			<property name="exceptionAttribute" value="ex" />
			<!-- 定义需要特殊处理的异常,用类名或类全名作为key,页面作为值 -->
			<property name="exceptionMappings">
				<props>
					<prop key="java.lang.NullPointerException">/jsp/npe.jsp</prop>
				</props>
			</property>
		</bean>	

spring会将异常信息存在request域中

缺点:

​ 发生异常以后只能实现页面跳转,不能执行业务操作(记录异常日志信息到文件或者数据)

自定义异常处理器

//自定义异常处理器,实现HandlerExceptionResolver接口
@Component
public class MyExceptionHandlerResolver implements HandlerExceptionResolver{

	@Override
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
			Exception ex) {
		ModelAndView mv = new ModelAndView();
		if(ex instanceof NullPointerException) {
			System.out.println("NullPointerException:"+ex);
			mv.setViewName("/jsp/npe.jsp");
		}else if(ex instanceof RuntimeException) {
			System.out.println("runtimeexception:"+ex);
			mv.setViewName("/jsp/error.jsp");
		}else {
			System.out.println("exception:"+ex);
			mv.setViewName("/jsp/error.jsp");
		}
		return mv;
	}
}

配置springmvc.xml扫描器要保证扫描到@Component注解

<context:component-scan base-package="com.woniu"></context:component-scan>

在每个Controller中指定针对当前Controller的异常处理

不是同一配置,当前Controller的异常处理只管自己

@ExceptionHandler

@Controller
public class MyControllerDemo {
	
	//当前异常处理只管当前Controller
	@ExceptionHandler
	public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
			Exception ex) {
		ModelAndView mv = new ModelAndView();
		if(ex instanceof NullPointerException) {
			System.out.println("NullPointerException:"+ex);
			mv.setViewName("/jsp/npe.jsp");
		}else if(ex instanceof RuntimeException) {
			System.out.println("runtimeexception:"+ex);
			mv.setViewName("/jsp/error.jsp");
		}else {
			System.out.println("exception:"+ex);
			mv.setViewName("/jsp/error.jsp");
		}
		return mv;
	}
	
	//每种异常对应一个处理方法
	@ExceptionHandler(NullPointerException.class)
	public ModelAndView resolveNpeException(Exception ex) {
		ModelAndView mv = new ModelAndView();
		System.out.println("NullPointException空指针:"+ex);
		mv.setViewName("/jsp/npe.jsp");
		return mv;
	}
}	

所有的Controller统一处理

@ControllerAdvice

对于@ControllerAdvice,我们比较熟知的用法是结合@ExceptionHandler用于全局异常的处理,但其作用不仅限于此。ControllerAdvice拆分开来就是Controller Advice,关于Advice,前面我们讲解Spring Aop时讲到,其是用于封装一个切面所有属性的,包括切入点和需要织入的切面逻辑。这里ContrllerAdvice也可以这么理解,其抽象级别应该是用于对Controller进行“切面”环绕的,而具体的业务织入方式则是通过结合其他的注解来实现的。@ControllerAdvice是在类上声明的注解,其用法主要有三点:

· 结合方法型注解@ExceptionHandler,用于捕获Controller中抛出的指定类型的异常,从而达到不同类型的异常区别处理的目的;

· 结合方法型注解@InitBinder,用于request中自定义参数解析方式进行注册,从而达到自定义指定格式参数的目的;

· 结合方法型注解@ModelAttribute,表示其标注的方法将会在目标Controller方法执行之前执行。

从上面的讲解可以看出,@ControllerAdvice的用法基本是将其声明在某个bean上,然后在该bean的方法上使用其他的注解来指定不同的织入逻辑。不过这里@ControllerAdvice并不是使用AOP的方式来织入业务逻辑的,而是Spring内置对其各个逻辑的织入方式进行了内置支持。

@ControllerAdvice与@EXceptionHandler结合使用

@ControllerAdvice
public class ControllerExceptionResolver {
	
	@ExceptionHandler(NullPointerException.class)
	public ModelAndView resolveNpeException(Exception ex) {
		ModelAndView mv = new ModelAndView();
		System.out.println(123);
		System.out.println("NullPointException空指针:"+ex);
		mv.setViewName("/jsp/npe.jsp");
		return mv;
	}
	
	@ExceptionHandler(RuntimeException.class)
	public ModelAndView resolveRuntimeException(Exception ex) {
		ModelAndView mv = new ModelAndView();
		System.out.println("RuntimeException:"+ex);
		mv.setViewName("/jsp/npe.jsp");
		return mv;
	}
}

图片上传

Servlet2.5

​ apatche的commons公共组件包: io.jar fileuplaod.jar

Servlet3.0

​ 需要添加额外jar包

Struct:

​ io.jar fileuplaod.jar

SpringMVC

​ io.jar fileuplaod.jar

在这里插入图片描述

文件上传对表单的要求:

​ method=”post”

​ enctype=”multipart/form-data”(就是前面ajax里面的contentType,

默认值application/x-www-form-urlencoded)

表单

<form action="<c:url  value='/demo04.do' />" method="POST"
			enctype="multipart/form-data">
		图片上传:<input  type="file" name="img" /><br>
		<input type="submit" value="确认"  />
	</form>
//文件上传
	//multipartFile是接口,真正使用的是实现类,变量名必须与表单中的input的name值一样
	@RequestMapping("/demo04.do")
	public String demo4(HttpServletRequest req,MultipartFile img) throws IllegalStateException, IOException{	
		//获取服务器图片文件夹的真实路径
		//虚拟路径  http://localhost:8080/images
		//真实路径  C:\Program Files\Apache Software Foundation\Tomcat 8.0\webapps\aspring08-time-requestbody-exception\images
		//将虚拟路径转换为绝对路径
		String path = req.getServletContext().getRealPath("/images");
		//获取文件名,uuid可以解决文件重名的问题
		String fileName = UUID.randomUUID()+img.getOriginalFilename();
		File file = new File(path,fileName);
        //上传文件
		img.transferTo(file);
		return "/jsp/index.jsp";
	}

springmvc.xml配置多部件解析器CommonsMultipartResolver

<!-- 配置多部件解析器,id不能乱写,是由DispactcherServlet规定 -->
		<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>	

<mvc:annotation-driven/>

配置多部件解析器,id不能乱写,是由DispactcherServlet规定的
在这里插入图片描述

以上面这种方式传到服务器的图片隔一会就回被删除,可以配置一个虚拟资源服务器
在这里插入图片描述
然后将上面的获取真实路径改为String path = D:\images

@RequestMapping("/demo04.do")
	public String demo4(HttpServletRequest req,MultipartFile img) throws IllegalStateException, IOException{	
		//获取服务器图片文件夹的真实路径
		//虚拟路径  http://localhost:8080/images
		//真实路径  C:\Program Files\Apache Software Foundation\Tomcat 8.0\webapps\aspring08-time-requestbody-exception\images
		//将虚拟路径转换为绝对路径
//		String path = req.getServletContext().getRealPath("/images");
		String path = "D:\\images";
		//获取文件名,uuid可以解决文件重名的问题
		String fileName = UUID.randomUUID()+img.getOriginalFilename();
		File file = new File(path,fileName);
		img.transferTo(file);
		return "/jsp/index.jsp";
	}
	
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值