springmvc的进阶

Springmvc进阶:

Springmvc的文件上传:

Springmvc作为一个mvc框架,当然少不了的是在页面上进行文件的上传功能,在springmvc中的文件上传,是配置一个文件上传解析器并引入文件上传的common-fileupload相关工具来接收文件。

首先、导入依赖管理

<!-- 文件上传组件 -->
<dependency>
   <groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>

然后、编写实现类

@Controller
@RequestMapping("file")
public class UploadController {
 
    /**
     * file:上传文件参数名。
     * @param multipartFile:上传文件对象
     * @return String:返回视图名称,简写方式返回视图名称。
     * @throws IllegalStateException
     * @throws Exception
     */
    @RequestMapping("/upload")
    public String upload(@RequestParam("file") MultipartFile multipartFile) throws Exception{
            
            if (multipartFile != null) {
                    //将上传的文件保存文件到指定路径
                    multipartFile.transferTo(new File("C:\\tmp\\" + multipartFile.getOriginalFilename()));
            }
            return "redirect:/success.jsp";
    }
}

最后、在springmvc-servlet.xml中配置视图解析器

<!-- 定义文件上传解析器 -->
<bean id="multipartResolver”	class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置默认字符编码 -->
<property name="defaultEncoding" value="uft-8"></property>
<!-- 设置最大上传文件大小(单位B)5*1024*1024=5242880B=5MB -->
<property name="maxUploadSize" value="5242880"></property>
</bean>

在页面上也是一样,需要有一个input标签typefilenamefile,注意的是form表单的为multipart/form-data和post方式提交

 

springmvc下载:

springmvc中下载文件,需要几步。不仅要定制实现类继承AbstractView,还需要定义具体的视图解析器,在视图中获取模型数据然后在返回响应。

①、实现类

②、定义视图解析器

 

除了定义普通的下载视图,还能定义excel的下载视图。

首先、导入依赖管理

<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.9</version>
</dependency>

然后、定义实现类继承AbstractExcelView

@Controller
@RequestMapping("excel")
public class ExcelController {
 
    @RequestMapping("/export")
    public ModelAndView exportExcel(){
        ModelAndView mv = new ModelAndView();
        //设置视图名称
        mv.setViewName("excelView");
        
        //到service查询用户列表数据
        List<User> userList = new ArrayList<User>();
        for(long i = 1; i <= 10; i ++){
                User user = new User();
                user.setId(i);
                user.setName("黑马程序员" + i);
                user.setSex(i%2==0?1:0);
                user.setAge(Integer.parseInt(i+""));
                user.setBirthday(new Date());
                userList.add(user);
        }
        
        //添加模型数据
        mv.addObject("userList", userList);
        return mv;      
    }
}

public class UserExcelView extends AbstractExcelView {
 
@Override
protected void buildExcelDocument(Map<String, Object> model, HSSFWorkbook workbook, HttpServletRequest request, HttpServletResponse response) throws Exception {
//创建工作表
HSSFSheet sheet = workbook.createSheet("用户列表");
//设置Excel的头标题行
HSSFRow row1 = sheet.createRow(0);
String[] titles = {"用户名称","年龄","性别","生日"};
for(int i = 0; i < titles.length; i++){
HSSFCell cell = row1.createCell(i);
cell.setCellValue(titles[i]);
}
//获取数据列表并填写数据
List<User> userList = (List<User>)model.get("userList");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
for(int j = 0; j < userList.size(); j++){
HSSFRow row = sheet.createRow(j+1);
row.createCell(0).setCellValue(userList.get(j).getName());
row.createCell(1).setCellValue(userList.get(j).getAge());
row.createCell(2).setCellValue(userList.get(j).getSex()==1?"男":"女");
row.createCell(3).setCellValue(sdf.format(userList.get(j).getBirthday()));
}
//设置响应中 下载文件的名称
response.setHeader("Content-Disposition", "attachment;filename=" + new String("用户列表.xls".getBytes(), "ISO-8859-1"));
}
}

最后,是定义自定义的视图解析器

<!-- 定义视图 -->
<bean name="excelView" class="mjf.haihan.springmvc.view.UserExcelView"></bean>
<!-- 定义视图解析器 -->
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
<!-- 设置视图解析器的顺序;order 越小越先执行 -->
<property name="order" value="1"></property>
</bean>



需要注意的是:在配置视图解析器的时,已经配置了InternalResourceViewResolver,在配置视图解析器时,如果不指定解析器的order属性,那么会按照配置顺序先执行InternalResourceViewResolver而导致后续的视图无执行机会;另外,在多个视图解析器的执行顺序,取决于视图解析器的order属性。而且,在定义自己的视图时,需要连续写下定义类和定义的视图解析器。

Order的值越小越先执行,最小为0。也需要将原配置的视图解析器设置order属性,其值应该比BeanNameViewResolver的值小。

<!-- 定义视图解释器 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- Example: prefix="/WEB-INF/jsp/", suffix=".jsp", viewname="test" ->
"/WEB-INF/jsp/test.jsp" -->
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
<property name="order" value="2"/>
</bean>


 

Springmvc拦截器:

Springmvc的处理拦截器有执行具体方法时的前、后、完成时三个点进行拦截处理。

执行链:

HandlerExecutionChain执行链,从HandlerMapping返回给DispatcherServlet,其中包含了Handler对象和Interceptor对象。Handler是实现了Controller接口或者使用了@Controller注解的对象,而Interceptor则是实现了HandlerInterceptor接口的对象。

springmvc中的拦截器接口定义了三个方法:

PreHandler:调用Handler之前执行。

PostHandler:调用Handler之后执行(如果没有调用执行handler将不执行此方法,如果preHandler方法返回false的话,postHandler方法就不执行)。

AfterCompletion:视图渲染完之后并且preHandler方法返回true执行。

 

执行流程

 

 

当有多个拦截器的时候,每个拦截器中的三个方法执行的顺序:PreHandler按顺序执行,PostHandlerAfterHandler都是逆序执行的。

 

定义拦截器

(一)单个拦截器的设置

首先、实现拦截器类

public class MyHandlerInterceptor1 implements HandlerInterceptor {
 
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("MyHandlerInterceptor1的前置方法(preHandle)执行了");
        return false;
    }
 
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("MyHandlerInterceptor1的后置方法(postHandle)执行了");
    }
 
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
            Exception ex) throws Exception {
        System.out.println("MyHandlerInterceptor1的完成方法(afterCompletion)执行了");
    }
 
}


然后、添加拦截器配置

<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 配置进入拦截器的web路径规则 -->
<mvc:mapping path="/**/*.action"/>
<!-- 拦截器 -->
<bean class="mjf.haihan.springmvc.interceptor.MyHandlerInterceptor1"/>
</mvc:interceptor>
</mvc:interceptors>
如果想要比较简洁的写法:
<!-- 配置拦截器 -->
<mvc:interceptors>
<bean class="mjf.haihan.springmvc.interceptor.MyHandlerInterceptor1"/>
</mvc:interceptors>

(二)多个拦截器的设置

只需要在配置里面添加拦截器即可

<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 配置进入拦截器的web路径规则 -->
<mvc:mapping path="/**/*.action"/>
<!-- 拦截器 -->
<bean class="mjf.haihan.springmvc.interceptor.MyHandlerInterceptor1"/>
</mvc:interceptor>
<mvc:interceptor>
<!-- 配置进入拦截器的web路径规则 -->
<mvc:mapping path="/**/*.action"/>
<!-- 拦截器 -->
<bean class="mjf.haihan.springmvc.interceptor.MyHandlerInterceptor2"/>
</mvc:interceptor>
<mvc:interceptor>
<!-- 配置进入拦截器的web路径规则 -->
<mvc:mapping path="/**/*.action"/>
<!-- 拦截器 -->
<bean class="mjf.haihan.springmvc.interceptor.MyHandlerInterceptor3"/>
</mvc:interceptor>
</mvc:interceptors>


拦截器的总结:

①、拦截器的执行过程和Struts2的拦截器执行过程类似

②、拦截器的preHandle方法是顺序执行,如果其中一个返回false则请求返回;拦截器的PostHandle方法是倒序执行,postHandle方法只有在preHandle方法全部执行后并且处理器也执行了才能被执行。

③、拦截器的afterCompletion方法是倒序执行,afterCompletion方法不仅是在最后执行,而且如果有多个拦截器时再前面的拦截器的preHandle返回是true时,后面的拦截器即使返回false,那么前面的拦截器的afterCompletion也会执行。

 

静态资源404和日期问题:

静态资源404

当配置的DispatcherServleturl-pattern为“/”时,意思是匹配所有的资源,那么就包含了系统所有的htmlcssimages等这些静态的资源文件,而后台的Handler是无法处理静态资源的,导致找不到资源404

springmvc中可以在配置文件中添加<mvc:defalut-servlet-handler />解决此问题。意思是将静态资源转交给服务器处理;这样spring会默认用Servlet来响应静态文件,DefaultServletHttpRequestHandler在容器启动时会使用主流web容器默认Servlet的名称列表自动查找容器的默认Servlet

 

解决字符转日期问题

在表单中输入日期后提交到后台,如果接收的对象对应的属性类型为日期的那么会提交失败,原因是转换类型失败。需要在属性上添加@DateTimeFormat注解进行转换即可。

例:

@DateTimeFormat(pattern=“yyyy-MM-dd”)
Private Date birthday;



 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值