• SpringMVC——高级参数绑定(数组、集合),@RequestMapper 的使用,Controller方法的三种返回值类型,异常处理器,上传图片,JSON数据交互,配置拦截器


    一.高级参数绑定

    1、将前端传来的参数绑定数组/集合中

    1)数组直接接收

    @RequestMapping(value = "/arrayTest.action")
    public void arrayTest(Integer[] ids){
        System.out.println(Arrays.toString(ids));
    }
    

    2)POJO中的数组接收

    @RequestMapping(value = "/arrayTest.action")
    public void arrayTest(QueryVo vo){
        System.out.println(Arrays.toString(vo.getIds()));
    }
    

    3)集合直接接收(报错,无法直接接收)

    @RequestMapping(value = "/arrayTest.action")
    public void arrayTest(List<Integer> ids){
        System.out.println(ids);
    }

    4)POJO中的集合接收

    @RequestMapping(value = "/arrayTest.action")
    public void arrayTest(QueryVo vo){
        System.out.println(vo.getIds());
    }
    

    2、将前端传来的所有参数保存到集合中

    JSP页面样式

    <form action="${pageContext.request.contextPath }/arrayTest.action" method="post">
    	商品列表:
    	<table width="100%" border=1>
    		<tr>
    			<td>选择</td>
    			<td>商品名称</td>
    			<td>商品价格</td>
    			<td>生产日期</td>
    			<td>商品描述</td>
    			<td>操作</td>
    		</tr>
    		<c:forEach items="${itemList }" var="item" varStatus="s">
    			<tr>
    				<td><input type="checkbox" name="ids" value="${item.id }"></td>
    				<td><input type="text" name="itemsList[${s.index}].name" value="${item.name }"></td>
    				<td><input type="text" name="itemsList[${s.index }].price" value="${item.price }"></td>
    				<td><fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/></td>
    				<td>${item.detail }</td>
    
    				<td><a href="${pageContext.request.contextPath }/itemEdit.action?id=${item.id}">修改</a></td>
    
    			</tr>
    		</c:forEach>
    
    	</table>
    
    	<input type="submit"/>
    </form>

     QueryVO.java

    public class QueryVo {
    
        List<Item> itemsList;
    
        public List<Item> getItemsList() {
            return itemsList;
        }
    
        public void setItemsList(List<Item> itemsList) {
            this.itemsList = itemsList;
        }
    }

    测试类

    @RequestMapping(value = "/arrayTest.action")
    public void arrayTest(QueryVo vo){
        System.out.println(vo.getItemsList());
    }
    

    二.@RequestMapper 

    1、URL路由映射

    @RequestMapping(value = "/xxx.action")

    2、在类上加

    // 简化请求路径  /itemList ==> /item/itemList
    @RequestMapping("/item")
    public class ItemsController {

    3、方法限定

    限定GET方法:@RequestMapping(method = RequestMethod.GET)

    限定POST方法:@RequestMapping(method = RequestMethod.POST)

    GETPOST都可以:@RequestMapping(method = {RequestMethod.GET,RequestMethod.POST})

    4、多个URL映射到同一方法

    @RequestMapping(value = "{/itemList.action,/item123.action}")

    三.Controller方法返回值

    1、返回ModelAndView

    controller方法中定义ModelAndView对象并返回,对象中可添加model数据、指定view。(一般用于异常处理器中)

    // 配置请求的url
    @RequestMapping(value = "/itemList.action")
    public ModelAndView queryItemList(){
    
        // 创建页面需要显示的商品数据
        List<Item> items = itemService.selectItemsList();
    
        ModelAndView modelAndView = new ModelAndView();
    
        // 放到request域中
        modelAndView.addObject("itemList",items);
        //modelAndView.setViewName("/WEB-INF/jsp/itemList.jsp");
        modelAndView.setViewName("itemList");
    
        return modelAndView;
    }
    

    2、返回String

    优点:解耦,返回视图路径,model带数据,官方推荐此种方式。解耦,数据,视图,分离,MVC 。

    // 配置请求的url
    @RequestMapping(value = "/itemList.action")
    public String queryItemList(Model model){
    
        // 创建页面需要显示的商品数据
        List<Item> items = itemService.selectItemsList();
    
        // 放到request域中
        model.addAttribute("itemList",items);
    
        //return "itemList";    // 直接返回一个视图文件(jsp)
        //return "redirect:/itemEdit.action?itemId=1";  // 重定向到其他URL
        return "forward: /itemEdit.action?itemId=1";  // 转发到其他URL
    }

    3、返回Void(常用于ajax)

    / 配置请求的url
    @RequestMapping(value = "/itemList.action")
    public void queryItemList(HttpServletRequest request, HttpServletResponse response, HttpSession session, Model model,...其他自定义的类) throws ServletException, IOException {
    
        // 创建页面需要显示的商品数据
        List<Item> items = itemService.selectItemsList();
    
        request.setAttribute("itemList",items);
    
        // 请求转发
        request.getRequestDispatcher("/WEB-INF/jsp/itemList.jsp").forward(request,response);
    }
    

    四.异常处理器

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

    系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发、测试通过手段减少运行时异常的发生。

    系统的dao、service、controller出现都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,如下图:

    自定义异常处理器

    1)自定义一个异常MyException.java

    public class MyException extends Exception {
    
        private String msg;
    
        public MyException(String msg) {
            this.msg = msg;
        }
    
        public MyException() {
        }
    
        public String getMsg() {
            return msg;
        }
    
        public void setMsg(String msg) {
            this.msg = msg;
        }
    }
    

    2)在程序中手动抛出这个异常

    // 配置请求的url
    @RequestMapping(value = "/itemList.action")
    public void queryItemList(HttpServletRequest request, HttpServletResponse response, HttpSession session, Model model) throws Exception {
    
        if (1==1) {
            throw new MyException("啦啦啦");
        }
    
        // 创建页面需要显示的商品数据
        List<Item> items = itemService.selectItemsList();
    
        request.setAttribute("itemList",items);
    
        // 请求转发
        request.getRequestDispatcher("/WEB-INF/jsp/itemList.jsp").forward(request,response);
    }

    3)在applicationContext.xml中配置全局异常处理器

    <!-- *****************配置全局异常处理器***************** -->
    
    <bean class="cn.x5456.exception.CustomExceptionResolver"/>

    4)书写异常处理器

    import org.springframework.web.servlet.HandlerExceptionResolver;    // 别导错包
    
    public class CustomExceptionResolver implements HandlerExceptionResolver {
    
        @Override
        public ModelAndView resolveException(HttpServletRequest httpServletRequest,
                                             HttpServletResponse httpServletResponse,
                                             Object o,  // 发生异常的地方 Serivce层  方法  包名+类名+方法名(形参) 字符串
                                             Exception e) {
    
            ModelAndView mav = new ModelAndView();
    
            String msg = "未知异常";
    
            if (e instanceof MyException){
                MyException myex = (MyException) e;
                msg = myex.getMsg();
            }
    
            mav.addObject("msg",msg);
            mav.setViewName("error");
    
            return mav;
        }
    }
    

    五.上传图片

    1)配置上传文件夹的url访问路径

    2)配置applicationContext.xml

    <!-- *************配置文件上传的实现类,id必须设置为multipartResolver*************-->
    
    <bean id="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 设置文件上传大小 -->
        <property name="maxUploadSize" value="5000000" />
    </bean>
    <!-- 文件上传 -->
        <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    
            <!-- 设置上传文件的最大尺寸位30M -->
            <property name="maxUploadSize" value="31457280" />
            <property name="defaultEncoding" value="UTF-8" />
            <!-- 是否延迟加载,在需要的时候才进行上传文件的解析 -->
            <property name="resolveLazily" value="true" />
            <!-- 文件上传的临时路径,文件上传完成后,临时目录中的临时文件会被自动清除 -->
            <property name="uploadTempDir" value="upload/temp" />
        </bean>
    

    3)修改form标签

    <form id="itemForm" action="${pageContext.request.contextPath }/updateitem.action" method="post" enctype="multipart/form-data">

    4)书写Controller

    @RequestMapping(value = "/updateitem.action")
    public String arrayTest(Item itemPOJO, MultipartFile pictureFile) throws IOException {  // 接收前端传来的pic文件对象
        // 1.保存图片
            // 为避免重复,使用uuid
        String picName = UUID.randomUUID().toString().replaceAll("-", "");
            // 获取文件名的后缀
        String ext = FilenameUtils.getExtension(pictureFile.getOriginalFilename());
            // 保存文件
        pictureFile.transferTo(new File("D:\upload\"+picName+"."+ext));
    
        // 2.更新商品信息
        itemPOJO.setPic(picName+"."+ext);
    
        itemService.updateItem(itemPOJO);
    
        return "redict:/itemEdit.action?id="+itemPOJO.getId();
    }

    六.JSON数据交互

    前端 

    <script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-1.4.4.min.js"></script>
    <script type="text/javascript">
        $(function () {
    
            // 不能使用
            // $.post(url,params,
            // 	function(data){
            //     回调
            // 	},
            // 	"json");	因为这个jasn指的是响应是json格式的数据
    
            var params = '{"id": 1,"name": "测试商品","price": 99.9,"detail": "测试商品描述","pic": "123456.jpg"}';	// 字典+引号==json字符串
    
            $.ajax({
                url : "${pageContext.request.contextPath }/json.action",
                data : params,
                contentType : "application/json;charset=UTF-8",//发送数据的格式
                type : "post",
                dataType : "json",//回调
                success : function(data){
                    alert(data.name);
                }
            })
    
        })
    </script>

    后端

    @RequestMapping(value = "/json.action")
    public @ResponseBody Item jsonTest(@RequestBody Item item){
    
        System.out.println(item);
    
        return item;
    
    }

    七.拦截器

    Spring Web MVC 的处理器拦截器类似于Servlet 开发中的过滤器Filter,用于对处理器进行预处理和后处理。

    配置拦截器 

    applicationContext.xml

    <!-- *************配置拦截器************* -->
    
    <mvc:interceptors>
        <mvc:interceptor>
            <!-- 所有的请求都进入拦截器 -->
            <mvc:mapping path="/**" />
            <!-- 配置具体的拦截器 -->
            <bean class="cn.x5456.interceptor.HandlerInterceptor1" />
        </mvc:interceptor>
        <mvc:interceptor>
            <!-- 所有的请求都进入拦截器 -->
            <mvc:mapping path="/**" />
            <!-- 配置具体的拦截器 -->
            <bean class="cn.x5456.interceptor.HandlerInterceptor2" />
        </mvc:interceptor>
    </mvc:interceptors>
    

    HandlerInterceptor1.java

    package cn.x5456.interceptor;
    
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.portlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class HandlerInterceptor1 implements HandlerInterceptor {
        // controller执行后且视图返回后调用此方法
        // 这里可得到执行controller时的异常信息
        // 这里可记录操作日志
        @Override
        public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
                throws Exception {
            System.out.println("HandlerInterceptor1....afterCompletion");
        }
    
        // controller执行后但未返回视图前调用此方法
        // 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示
        @Override
        public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, org.springframework.web.servlet.ModelAndView modelAndView) throws Exception {
            System.out.println("HandlerInterceptor1....postHandle");
        }
    
    
        // Controller执行前调用此方法
        // 返回true表示继续执行,返回false中止执行
        // 这里可以加入登录校验、权限拦截等
        @Override
        public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
    		// 获取session  
    		// HttpSession session =request.getSession();  
    		
            System.out.println("HandlerInterceptor1....preHandle");
            // 设置为true,测试使用
            return true;
        }
        
    }

    结果

    控制台打印:

    HandlerInterceptor1..preHandle..

    HandlerInterceptor2..preHandle..

    HandlerInterceptor2..postHandle..

    HandlerInterceptor1..postHandle..

    HandlerInterceptor2..afterCompletion..

    HandlerInterceptor1..afterCompletion..

    处理流程

    preHandle按拦截器定义顺序调用

    postHandler按拦截器定义逆序调用

    • postHandler在拦截器链内所有拦截器返成功调用

    afterCompletion按拦截器定义逆序调用

    • afterCompletion只有preHandle返回true才调用

    SpringMVC与Struts2拦截器的区别

    他们的拦截器都是继承servlet的filter;且都能传递了request和response作用域。spring过滤后是去找controller,struts过滤后是去struts的配置文件找action。 

     

    // 获取应用的url
    request.getScheme() +"://" + request.getServerName() + ":" +request.getServerPort() +request.getContextPath();

    // 获取应用的绝对路径
    request.getServletContext().getRealPath("/")
  • 相关阅读:
    expandafter
    又回到了kde
    朗读软件
    tex bookmarks
    vim命令执行时间
    vim,tex的编译
    utorrent
    火狐的扩展
    linux 无线指示灯闪
    tex溢出报警
  • 原文地址:https://www.cnblogs.com/x54256/p/8545360.html
Copyright © 2020-2023  润新知