您的位置:首页 > 编程语言 > Java开发

SpringMvc入门到开发(四)之自定义异常处理,上传,自定义的参数类型转化【附详细截图】

2017-07-22 10:14 686 查看
所有资料打包下载:有需要的可以下载

http://download.csdn.net/download/xiaozhegaa/9907441

【分享资料】在注解那一篇说道,绑定数据(收集V传递到C的数据):绑定数组,绑定list,map,绑定podo等Springmvc的各种类型参数绑定 案例下载,里面有开发步骤跟截图,有需要的下载:

http://download.csdn.net/detail/xiaozhegaa/9906508



【总结:】在前面的SpringMvc入门到开发过程三篇文章中,我们已经学会了如何去配置核心配置文件(springmvc-config.xml)、如何配置前端控制器(DispatcherSevlet)、前端控制器的底层原理、如何去映射一个方法的路径(注解)、如何去获取页面传过来的数据(参数绑定)、如何去跨页面传递数据(Model,ModelMap,ModelAndView)、页面跳转(ModelAndView,记得没有讲过重定向,稍后把剩下没讲到杂七杂八的一并总结一篇咯)、如何获取数据(el表达式,老知识)等知识,就算不学习这一篇的文章,也可以去开发。写这一篇文章的目的,是介绍一下springmvc还提供一些其他的便捷的操作。在框架中一般会有提供“文件上传”,“验证码”,“异常处理”,“数据交互”等封装技术,接下来就来了解一下

一、自定义的参数类型转化

1、问题的描述:在收集数据的时候需要对数据进行一些特殊的处理。这个问题最常见的就是发生在,字符串到日期的一个转化问题。由于日期数据有很多种格式,springmvc没办法把字符串转换成日期类型。所以需要自定义参数绑定。【】当然不止日期这个转换,例如还有在收集数据前先对字符串进行去头尾空串处理,也算是转换的一种。这里以字符串转化成日期为例:

2:开发步骤如下

//1.首先在springmvc-config.xml中把
//<mvc:annotation-driven/>
//改成
<mvc:annotation-driven conversion-service="conversionService"/>
//注意conversionSercvice是自己定义的bean名称。


//2.自己写一个conversionService的Bean
<!-- 配置Conveter转换器 转换工厂(日期) -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<!-- 自定义转换器的类(由我来写) -->
<bean class="dgut.xiaozheng.hander.conversion.DateConveter" />
<!-- 自定义去除字符串转换器-->
<!--<bean class="...."-->
<!--......这里可以写多个转换器-->
</set>
</property>
</bean>




//3.自己去写一个DateConveter的类
/*
* 日期转换的数据类
* S:页面传递过来的类型
* T:转化后的类型
* */
public class DateConveter implements Converter<String, Date>{

@Override
public Date convert(String source) {
try {
// 把字符串转换为日期类型
if(null!=source) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//转化成功后把结果返回。这里可以通过debug调试查看,或者在控制台打印输出
return simpleDateFormat.parse(source);
}

} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (java.text.ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 如果转换异常则返回空
return null;
}
}


//测试案例
假设一个添加商品的表单,有一个输入时间的表单项name=createTime,使用User收集数据,有个Date类型的成员变量createTime。
若没有写自定义转换器的时候,就会出错。因为String类型不能转化成Date类型
若写了自定义转化器的时候,输入2071-07-22 10:57:06,就会成功。测试打印数据ok




【注意:】在写DateConveter类的时候,定义了字符串的格式为yyyy-MM-dd HH:mm:ss ,所以你的格式一定要是2071-07-22 10:57:06,如果你是自己的格式,修改一下就可以了。那么…………至此,自定义参数类型转化就没问题了

二、 异常处理器

1、问题的描述:springmvc在处理请求过程中出现异常信息交由异常处理器进行处理,自定义异常处理器可以实现一个系统的异常处理逻辑。

2、底层原理:



3、开发步骤

3.1、自定义异常类:需要继承异常处理类的接口

3.2、按照提示实例化接口的方法

//【注意这里的HandlerExceptionResolver 包不要导错了】
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
/**
* 异常处理器的自定义的实现类
* @author xiaozheng
*/
public class CustomerExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception e) {
//以下两句是打印异常日记。在eclipse可以通过控制台看出,但是在linux上一定要打印出来,这里我就不写日志代码
//日志    1.发布 tomcat war  Eclipse
//2.发布Tomcat  服务器上  Linux  Log4j

/*
* 分析:返回值为ModelAndView ,故实例化一个ModelAndView。并且设置返回的视图。
* 为了测试:在ModelAndView中,添加一个错误提示
*/
ModelAndView mav = new ModelAndView();
mav.addObject("error", "测试异常处理");
mav.setViewName("error");
return mav;
}


3.3、需要在核心配置文件中去配置该bean

//class根据自己的异常处理类路径来修改
<bean class="dgut.xiaozheng.hander.Exception.CustomerExceptionResolver"></bean>


3.4、测试

//测试步骤1:写一个注册的表单页面,提交到"/register"方法
//测试步骤2:在“/register”故意出错,int i = 10 / 0 ;




//测试步骤3:写一个error.jsp页面。获取数据就可以了
${error }


结果显示:【可见我们的配置是生效了】



接下来,演示一下自定义异常处理类。开发步骤是一样的,核心代码截图给大家。

//修改更改的地方

//1:在CustomerExceptionResolver 中,使用 instanceof 判断是哪种异常
ModelAndView mav = new ModelAndView();
//判断异常为类型,MessageException是我们定义的。e表示我们抛出去的异常
if(e instanceof MessageException){
//预期异常
MessageException me = (MessageException)e;
mav.addObject("error", me.getMsg());
}else{
mav.addObject("error", "未知异常");
}
mav.setViewName("error");
return mav;

//2: 新建一个自己的异常处理类MessageException
public class MessageException extends Exception{
private String msg;

public MessageException(String msg) {
super();
this.msg = msg;
}

public String getMsg() {
return msg;
}

public void setMsg(String msg) {
this.msg = msg;
}
}

//3:在“/register”中把Message抛出
//假设这里去查找用户列表
List<User> userList = new ArrayList<User>();
//这里写的是userList == null才会抛出错误,但是这只是为了演示,直接把userList看成是空的,故写null == null,让它一定会抛出该错误
if(null == null) {
throw new MessageException("用户列表不能为空");

}


结果显示:



【扩展】这样子,你就可以定义任意多个异常处理类,在异常处理类中写错误信息,然后在异常控制器类中通过判断抛出的错误类型,调用视图查看错误信息。【值得注意的是:】异常处理器类跟异常处理类是不一样的的。前者是需要时间处理器类接口,在核心配置文件中配置,后者只是我们写的普通的异常类而已,那么………………自此我们就学会了自定义异常处理器类

三:文件上传

问题引入:如果说,直接在项目的WEB-INF下面建立一个upload文件夹,上传的文件实际是存储在tomcat里面的upload,而非项目的upload文件夹,可以项目中的upload在本机是可以看到里面的文件。但是一旦把项目打包发给别人的时候,就会出现缺少图片的错误。因为你的图片并没有打包过去。所以这里推荐是在自己的电脑上新建一个虚拟目录,上传到虚拟目录上,然后再一起打包给别人

1、先扩展一个虚拟目录的知识。

【what】什么是虚拟目录?建立虚拟目录之后,可以通过某个地址在浏览器访问得到。可以理解成站点

【how】 有两种方式,第一种是在tomcat上配置虚拟站点

//在tomcat上配置图片虚拟目录,在tomcat下conf/server.xml中添加:
< Context docBase="D:\develop\upload\temp" path="/pic" reloadable="false"/>


第二种方式在eclipse里面配置。具体步骤截图如下。





复制一张图片到存放图片的文件夹,使用浏览器访问

测试效果,如下图:



【注意】有些人做了以上的操作之后会访问不到文件,原因是你没有保存,你应该把文件关闭,关闭的时候提示你是否保存,你保存后,再重启服务器就可以了。上述无关上传的事情,等会做显示的时候有可能会用到。接下来讲真正上传

开发步骤:

1、加入jar包

//上传必备包,稍后会一起打包发给大家的
commons-fileupload-1.2.2.jar
commons-io-2.4.jar


2、在springmvc.xml中配置文件上传解析器

<!-- 文件上传,id必须设置为multipartResolver -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置文件上传大小 5M = 5 * 1024 * 1024 具体值自己算-->
<property name="maxUploadSize" value="5000000" />
</bean>


3、写一个上传的jsp表单,并且修改以二进制的方式提交数据

//核心代码
enctype="multipart/form-data"
<input type="file" name="pictureFile">




4、图片上传方法中,

总结MultipartFile(文件上传类常用的方法)

byte[] getBytes():获取文件数据

String getContentType():获取文件MIME类型,如image/jpg\

InputStream getInputStream():获取文件流

String getName():获取上传组件中name的名字

String getOriginalFilename():获取文件上传的原名

long getSize():获取文件大小,单位字节

Boolean isEmpty():是否上传文件

void transferTo(File dest):将上传的文件保存到一个目标文件中

/*上传的文件会自动绑定到MultipartFile中*/
public String myUpload(MultipartFile pictureFile,ModelMap model) throws IllegalStateException, IOException{
if(!pictureFile.isEmpty()){
//生成UUID,并且把-去掉
String name = UUID.randomUUID().toString().replaceAll("-", "");
//获取文件的真实名称
//pictureFile.getOriginalFilename()
//获得文件的后缀名FilenameUtils.getExtension()是上传工具包方法
//FilenameUtils.getExtension(pictureFile.getOriginalFilename());

//根据你的要求来选择,这里保存的是图片的uuid+具体名称
//获得图片的名称
String realName =  pictureFile.getOriginalFilename();
//transferTo的函数,就是保存函数的方法
pictureFile.transferTo(new File("D:\\upload\\"+name+ext));

//这里可以做一些其他的操作
//例如保存路径到数据库。设置items的image值,然后进行更新
//vo.getItems().setImage(name + "." + ext);
//itemService.updateItemsById(vo.getItems());

model.addAttribute("message", "上传图片成功");
return "content/upload";
}else{
/*没有上传文件*/
throw new NoUploadPictureException("没有文件");
}

}


5、显示图片这一块。模拟从数据库中查找出imageUrl

//在上传的时候,把url存到域对象中
pictureFile.transferTo(new File("D:\\upload\\"+name+ext));
//以下这句话是模拟从数据库里面查找,找到之后存储到Model中
model.addAttribute("message", name+ext);


在jsp页面上:

<!--注意,这里实际上,src访问的路径是 http://localhost:8080/pic/${requestScope.message}路径哦 也就是我之前配置的虚拟站点起了作用-->
<div>显示图片</div>
<img src="/pic/${requestScope.message }">


6、显示结果



那么那么…………………自此我们已经学会了文件上传
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  异常处理 spring mvc
相关文章推荐