前端提醒注意:
<input type="file" name="icon" />
<form method="post" enctype="multipart/form-data">
后台取上传的文件,首先要做好准备:
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.2</version> </dependency>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 最大允许上传大小5MB --> <property name="maxUploadSize" value="5242880" /> <property name="defaultEncoding" value="UTF-8" /> </bean>
然后在controller中:
public ModelAndView input(MultipartFile icon
if (!icon.isEmpty()) {
String fileName = icon.getOriginalFilename();
System.out.println(icon.getContentType());
icon.transferTo(filePath);
因为存储文件需要文件路径而不是URL路径,通常需要一个映射,获取文件存储路径(绝对路径):
String path = request.getServletContext().getRealPath("/WEB-INF/icons/");
注意:为了后面开发调试时,通过(HTML的)src属性获取文件方便,这里最好修改eclipse中tomcat的server locations为:
其他就涉及到I/O操作等,比如
File filePath = new File(path + fileName);
if (!filePath.getParentFile().exists()) { filePath.getParentFile().mkdirs(); }
因为要由url调用,所以首先,还是要有Controller和Handler Method。
但是,这时候我们不能再返回ModelAndView或者String了,可以直接返回BufferedImage对象:
@RequestMapping public BufferedImage Show() {
return image; }演示运行效果:找不到view……
说明SpringMVC仍然将这个handler method当做之前一样的东东,采用一样的流程,找template合成view呢!
我们给handler method添加一个@ResponseBody注解
@ResponseBody public BufferedImage Show() {告诉SpringMVC:这个handler method,不要再搞什么view resolver之类的玩意儿,直接将其作为响应主体使用。
演示运行效果:找不到Converter……
因为不使用view resolver,就需要Converter把handler method的返回值,转换成可以发送给客户端的格式。
所以,在springmvc-servlet.xml中配置:
<mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter" />
PS:<mvc:annotation-driven>是默认包含在springmvc-servlet.xml中,为SpringMVC的:
配置Bean的。一般不用更改……
演示:
<img alt="" src="/17bang/captcha">
最后,BufferedImageHttpMessageConverter默认将image转换成png格式。我们还可以通过注解:
@RequestMapping(produces = MediaType.IMAGE_JPEG_VALUE )将其转换成其他格式(以上是.jpg格式)
在Controller中声明一个方法,添加该注解,所有该Controller中抛出的未处理异常都会被该方法处理
@ExceptionHandler({ IllegalArgumentException.class, NullPointerException.class }) public String error(HttpServletResponse response) { response.addHeader("level", "error"); return URLMapping.Error._500; }
说明:
public static class Error{ public final static String _500 = Redirect +"/exception.html";@想一想@:500前面为什么要加_(下划线)?
PS:要想能够访问静态页面,需要在springmvc-servlet.xml中添加:
<mvc:resources mapping="/images/**"location="/images/"/>
如果@ExceptionHandler不指定异常属性,还可以在方法参数中指定,比如:
@ExceptionHandler public String error(MessagingException me, HttpServletResponse response) { System.out.println(me.getMessage());这样还能获得一个额外的好处:可以拿到exception对象,调用其属性方法等……
额外声明一个类,给予该注解,可以全局的处理所有Controller中的未处理异常:
@ControllerAdvice public class ErrorHandle { @ExceptionHandler public String error(MessagingException me, HttpServletResponse response) {
PS:也可以放置@ModelAttribute注解方法用于全局赋值等……
对异常进行处理,通常就是进行log,可以使用之前学习过的log4j完成:
StackTraceElement[] stackTrace = me.getStackTrace(); for (int i = 0; i < stackTrace.length; i++) { //可以缩短堆栈深度 Logger.getLogger(getClass()).info(stackTrace[i]); }
注意这个logger是:
import org.jboss.logging.Logger;这样才有更大的灵活性:当项目不再使用log4j做为日志工具的时候,可以通过jboss无缝切换到其他log工具。
演示:log文件中出现了异常记录……
public void Rollback() { // TODO Auto-generated method stub try { if (transaction.isActive()) { Logger.getLogger(ErrorHandle.class).info("事务回滚……"); transaction.rollback(); }//else... } catch (Exception e) { //log 这时候不能再往外抛异常了 } finally { em.close(); //这是最关键的
F3演示:该接口下已有的实现类,以及抽象类AbstractHandlerExceptionResolver
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <!-- 默认错误页面 --> <property name="defaultErrorView" value="/exception.html" /> <property name="exceptionMappings"> <props> <!-- 在异常类型和错位页面之间建立关联 --> <prop key="javax.mail.MessagingException">/email/failed.html</prop> </props> </property> <!-- ex为异常对象,一般供jsp页面使用 --> <property name="exceptionAttribute" value="ex" /> </bean>不同的异常匹配不同的页面
@ResponseStatus(value = HttpStatus.FORBIDDEN,reason = "用户名或密码错误") public class UserNameNotMatchPasswordException extends RuntimeException{@ResponseStatus还可以直接用于hanler method,改变其response status:
@ResponseStatus(code = HttpStatus.BAD_GATEWAY, reason = "网关出错……") public ModelAndView on(Model model ) {
多快好省!前端后端,线上线下,名师精讲
更多了解 加: