• java深入探究15-SpringMVC


    测试代码:链接:http://pan.baidu.com/s/1c1QGYIk 密码:q924

    回顾spring+struts

    web.xml配置;struts核心过滤器;spring监听器->配置spring.xml;struts.xml

      <!-- 
      struts核心过滤器
      <filter>
          <filter-name>StrutsPrepareAndExecuteFilter</filter-name>
          <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
      </filter>
      <filter-mapping>
          <filter-name>StrutsPrepareAndExecuteFilter</filter-name>
          <url-pattern>/*</url-pattern>
      </filter-mapping>
      
      spring监听器
      <listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
      <context-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:spring.xml</param-value>
      </context-param>
       -->
    View Code

    1.生命周期

      /hello.action->先访问web.xml->通过springMVC核心核心控制器DispatcherServlet-跳转(可以默认也可以指定)到springmvc.xml配置文件(有4个对象:1.注册Action,我们访问的对象;2.映射器BeanNameUrlHandlerMapping映射Bean name属性url地址,SimpleUrlHandlerMapping映射bean的id属性可以适配多个;3.SimpleControllerHandlerAdapter适配器用于适配继承Control的类;4视图解析器InternalResourceViewResolver通过modelandView视图名找到真正的视图)-》BeanNameUrlHandlerMapping找到action或者通过SimpleControllerHandlerAdapter找到action-》再逻辑处理完后通过视图解析器跳转到目标对象

    工作流:

    1A)客户端发出http请求,只要请求形式符合web.xml
       文件中配置的*.action的话,就由DispatcherServlet
       来处理。
    
    1B)DispatcherServlet再将http请求委托给映射器
       的对象来将http请求交给对应的Action来处理
    
    2)映射器根据客户的http请求,再对比<bean name="/hello.action
       如果匹配正确,再将http请求交给程序员写的Action
    
    3)执行Action中的业务方法,最终返回一个名叫ModelAndView
       的对象,其中封装了向视图发送的数据和视图的逻辑名
    
    4)ModelAndView对象随着响应到到DispatcherServlet中了
    
    
    5)这时DispatcherServlet收到了ModelAndView对象,
       它也不知道视图逻辑名是何意,又得委托一个名叫
       视图解析器的对象去具体解析ModelAndView对象
       中的内容
    
    6)将视图解析器解析后的内容,再次交由DispatcherServlet
       核心控制器,这时核心控制器再将请求转发到具体的
       视图页面,取出数据,再显示给用户
    View Code

    2.spring快速入门 XML版

      1)步一:创建springmvc-day01这么一个web应用

      2)步二:导入springiocspringweb , springmvc相关的jar

      3)步三:在/WEB-INF/下创建web.xml文件

        <!-- 注册springmvc框架核心控制器 -->
        <servlet>
            <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>DispatcherServlet</servlet-name>
            <url-pattern>*.action</url-pattern>
        </servlet-mapping>
    View Code

        其中再web中还可以配置乱码过滤器

          在org.springframework.web.filter.CharacterEncodingFilter

    <!-- 注册spring提供的针对POST请求的中文乱码问题 -->
        <filter>
            <filter-name>CharacterEncodingFilter</filter-name>
            <filter-class>org.springframework.web.filter.CharacterEncodingFilter </filter-class>
            <init-param>
                <param-name>encoding</param-name>
                <param-value>UTF-8</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>CharacterEncodingFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    View Code

      

    过滤器加上这个作用:无论客户段是否有编码都用过滤其中编码解析 
           <init-param>  
                <param-name>forceEncoding</param-name>  
                <param-value>true</param-value>  
            </init-param>
    View Code

      4)创建HelloAction.java控制器类

    /**
     * 控制器
     * @author AdminTC
     */
    public class HelloAction implements Controller{
        /**
         * 业务方法
         */
        public ModelAndView handleRequest(HttpServletRequest requqest,HttpServletResponse response) throws Exception {
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.addObject("message","这是我的第一个springmvc应用程序");
            modelAndView.setViewName("/jsp/success.jsp");
            return modelAndView;
        }
    }
    View Code

      其中:

        1.继承Controller实现接口对ModelAndView对象模块视图对象赋值处理返回结果并跳转页面

          这个对象是单例对象,构造函数只在程序运行的时候执行;之后执行都是handleRequest方法

        2.

      5)/WebRoot/下创建jsp/success.jsp;这里反应结果页面

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <body>
        success.jsp 成功<br>
        ${requestScope.message }<br/>
        姓名:${requestScope.emp.username}<br/>
        性别:${requestScope.emp.gender}<br/>
         入职时间:${requestScope.emp.hiredate}<br/>
        入职时间:<fmt:formatDate 
                    value="${requestScope.emp.hiredate}"
                    type="date"
                    dateStyle="medium"
                />
            <!-- 
            1)fmt:formatDate 来源于 http://java.sun.com/jsp/jstl/fmt
            2)fmt:formatDate作用是格式化日期的显示,例如:2015年5月10日 星期日
            3)value表示需要格式化的值
            4)type表示显示日期,时间,都显示
              type=date表示只显示日期
              type=time表示只显示时间
              type=both表示日期时间均显示
            5)dateStyle表示显示日期的格式:short/medium/default/long/full
        -->
      </body>
    </html>
    View Code

      可以通过requestScope获得对象;日期问题可以通过:

      <%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

        入职时间:<fmt:formatDate 
                    value="${requestScope.emp.hiredate}"
                    type="date"
                    dateStyle="medium"
                />
            <!-- 
            1)fmt:formatDate 来源于 http://java.sun.com/jsp/jstl/fmt
            2)fmt:formatDate作用是格式化日期的显示,例如:2015年5月10日 星期日
            3)value表示需要格式化的值
            4)type表示显示日期,时间,都显示
              type=date表示只显示日期
              type=time表示只显示时间
              type=both表示日期时间均显示
            5)dateStyle表示显示日期的格式:short/medium/default/long/full
        -->
    View Code

      6)/WEB-INF/创建DispatcherServlet-servlet.xml配置文件,xml头部信息与spring.xml相同

           注意:该配置文件的命名规则:web.xml文件中配置的<servlet-name>的值-servlet.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans 
          xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:context="http://www.springframework.org/schema/context"
          xmlns:aop="http://www.springframework.org/schema/aop"
          xmlns:tx="http://www.springframework.org/schema/tx"
          xmlns:mvc="http://www.springframework.org/schema/mvc"
          xsi:schemaLocation="
          
          http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
          
          http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context-3.0.xsd
           
          http://www.springframework.org/schema/aop 
          http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
          
          http://www.springframework.org/schema/tx
          http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        
          http://www.springframework.org/schema/mvc
          http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
            
          ">
          
          
        
        <!-- 控制器(程序员) -->
        <bean name="/hello.action" class="cn.itcast.javaee.springmvc.base.HelloAction"></bean>  
        
        
        <!-- 映射器(框架) -->  
        <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>  
          
          
        <!-- 适配器(框架) -->  
        <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>  
          
          
        <!-- 视图解析器(框架) -->  
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"></bean>  
          
          
    </beans>
    View Code

      其中,配置位置可以自己定义;也可以在包中创建再通过src下的配置文件引用这个配置文件

      配置文件中四个对象

      7)部署web应用到tomcat中,通过浏览器访问如下URL

           http://127.0.0.1:8080/springmvc-day01/hello.action

    3.加载自定义目录下的springmvc.xml配置文件

        <!-- 注册springmvc框架核心控制器 -->
        <servlet>
            <servlet-name>DispatcherServlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:spring.xml</param-value>    
            </init-param>
        </servlet>
        <servlet-mapping>
            <servlet-name>DispatcherServlet</servlet-name>
            <url-pattern>*.action</url-pattern>
        </servlet-mapping>
    View Code

    4.解析视图逻辑名对应的真实路径

        <!-- 视图解析器(框架) -->  
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/jsp/"/>
            <property name="suffix" value=".jsp"/>
        </bean>
    View Code

    5.映射器Mapping

    1) org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping(核心)

          <!-- 注册控制器(程序员) -->
          <bean name="/add.action" class="cn.itcast.javaee.springmvc.mapping.UserAction"></bean>
    
          <!-- 注册映射器(handler包)(框架) -->
          <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
    View Code

    2) org.springframework.web.servlet.handler.SimpleUrlHandlerMapping

          <!-- 注册控制器(程序员) -->
          <bean id="userActionID" class="cn.itcast.javaee.springmvc.mapping.UserAction"></bean>
            
          <!-- 注册映射器(handler包)(框架) -->
          <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
                  <property name="mappings">
                      <props>
                          <prop key="/delete.action">userActionID</prop>
                          <prop key="/update.action">userActionID</prop>
                          <prop key="/find.action">userActionID</prop>
                      </props>
                  </property>
          </bean>
    View Code

    6.控制器Controller

      org.springframework.web.servlet.mvc.ParameterizableViewController

      如果请求是/hello.action的请求路径,则直接跳转到/jsp/success.jsp页面,不经过程序员定义的控制器Action

          <!-- /index.action请求,直接转发到/index.jsp页面 -->
          <bean name="/index.action" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
                  <property name="viewName" value="/index.jsp"/>
          </bean>
          
          
         <!-- 注册视图解析器(view包)(框架) 
          <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                  <property name="prefix" value="/"/>
                  <property name="suffix" value=".jsp"/>
          </bean>
          -->
    View Code

      org.springframework.web.servlet.mvc.AbstractCommandController

      能够以实体的形式,收集客户端参数

    public class AdminAction extends AbstractCommandController{
        public AdminAction(){
            this.setCommandClass(Admin.class);
        }
        @Override
        protected ModelAndView handle(HttpServletRequest request,HttpServletResponse response, Object obj, BindException bindException)throws Exception {
            System.out.println("AdminAction::handle");
            ModelAndView modelAndView = new ModelAndView();
            Admin admin = null;
            if(obj instanceof Admin){
                admin = (Admin) obj;
            }
            modelAndView.addObject("username",admin.getUsername());
            modelAndView.addObject("gender",admin.getGender());
            modelAndView.addObject("hiredate",admin.getHiredate());
            modelAndView.setViewName("/jsp/success.jsp");
            return modelAndView;
        }
    }
    View Code

    7.日期转换和编码过滤器

      1) 在默认情况下,springmvc不能将String类型转成Date类型,必须自定义类型转换器

    public class AdminAction extends AbstractCommandController{
        @Override
        protected void initBinder(HttpServletRequest request,ServletRequestDataBinder binder) throws Exception {
            binder.registerCustomEditor(Date.class,new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));
        }
    View Code

      2spring提供的,专用于解决POST提交中文乱码问题,需要在web.xml文件中配置

        <!-- 编码过滤器 -->
        <filter>
            <filter-name>CharacterEncodingFilter</filter-name>
            <filter-class>
        org.springframework.web.filter.CharacterEncodingFilter
            </filter-class>
            <init-param>
                <param-name>encoding</param-name>
                <param-value>UTF-8</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>CharacterEncodingFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    View Code

    ------------------------------------------------------------------------

    8.springmvc快速入门(注解版本)

       1)一个Action中,可以写多个类似的业务控制方法

    @Controller
    @RequestMapping(value="/user")
    public class UserAction{
        @RequestMapping(value="/add")
        public String add(Model model) throws Exception{
            System.out.println("HelloAction::add()");
            model.addAttribute("message","增加用户");
            return "/success.jsp";
        }
        @RequestMapping(value="/find")
        public String find(Model model) throws Exception{
            System.out.println("HelloAction::find()");
            model.addAttribute("message","查询用户");
            return "/success.jsp";
        }    
    }
    View Code

    http://127.0.0.1:8080/myspringmvc-day02/user/add.action;

    http://127.0.0.1:8080/myspringmvc-day02/user/find.action

      2)在业务控制方法中写入普通变量收集参数

    以参数形式收集客户端参数,springmvc采用方法参数形式的

    @Controller
    @RequestMapping(value="/user")
    public class UserAction{
        @RequestMapping(value="/add")
        public String add(Model model,int id,String name,Double sal) throws Exception{
            System.out.println("HelloAction::add()");
            System.out.println(id + ":" + name + ":" + sal);
            model.addAttribute("message","增加用户");
            return "/success.jsp";
        }    
    }
    View Code

      3)限定某个业务控制方法,只允许GETPOST请求方式访问

    @Controller
    @RequestMapping(value="/user")
    public class UserAction{
        @RequestMapping(value="/add",method=RequestMethod.POST)
        public String add(Model model,int id,String name,double sal) throws Exception{
            System.out.println("HelloAction::add()::POST");
            System.out.println(id + ":" + name + ":" + sal);
            model.addAttribute("message","增加用户");
            return "/success.jsp";
        }    
    }
    View Code

      4)在业务控制方法中写入RequestResponse等传统web参数

    传统web参数,这种方式我们不提倡,耦合了

    @Controller
    @RequestMapping(value="/user")
    public class UserAction{
        @RequestMapping(value="/add",method=RequestMethod.POST)
        public void add(HttpServletRequest request,HttpServletResponse response) throws Exception{
            System.out.println("HelloAction::add()::POST");
            int id = Integer.parseInt(request.getParameter("id"));
            String name = request.getParameter("name");
            double sal = Double.parseDouble(request.getParameter("sal"));
            System.out.println(id + ":" + name + ":" + sal);
            request.getSession().setAttribute("id",id);
            request.getSession().setAttribute("name",name);
            request.getSession().setAttribute("sal",sal);
            response.sendRedirect(request.getContextPath()+"/register.jsp");
        }    
    }
    View Code

      5)在业务控制方法中写入模型变量收集参数,且使用@InitBind来解决字符串转日期类型

        <form action="${pageContext.request.contextPath}/user/add.action" method="POST">
            编号:<input type="text" name="id" value="${id}"/><br/>
            姓名:<input type="text" name="name" value="${name}"/><br/>
            薪水:<input type="text" name="sal" value="${sal}"/><br/>
            入职时间:<input type="text" name="hiredate" value='<fmt:formatDate value="${hiredate}" type="date"/>'/><br/>
            <input type="submit" value="注册"/>
        </form>
    
    @Controller
    @RequestMapping(value = "/user")
    public class UserAction {
        @InitBinder
        protected void initBinder(HttpServletRequest request,ServletRequestDataBinder binder) throws Exception {
            binder.registerCustomEditor(
                    Date.class, 
                    new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));
        }
        @RequestMapping(value = "/add", method = RequestMethod.POST)
        public String add(int id, String name, double sal, Date hiredate,
                Model model) throws Exception {
            System.out.println("HelloAction::add()::POST");
            model.addAttribute("id", id);
            model.addAttribute("name", name);
            model.addAttribute("sal", sal);
            model.addAttribute("hiredate", hiredate);
            return "/register.jsp";
        }
    }
    View Code

      6)务控制方法中写入UserAdmin多个模型收集参数

    @Controller
    @RequestMapping(value = "/user")
    public class UserAction {
        @InitBinder
        protected void initBinder(HttpServletRequest request,ServletRequestDataBinder binder) throws Exception {
            binder.registerCustomEditor(
                    Date.class, 
                    new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));
        }
        @RequestMapping(value = "/add", method = RequestMethod.POST)
        public String add(User user,Model model) throws Exception {
            System.out.println("HelloAction::add()::POST");
            model.addAttribute("user",user);
            return "/register.jsp";
        }
    }
    View Code

      7)在业务控制方法中收集数组参数

    @Controller
    @RequestMapping(value="/user")
    public class UserAction {
        @RequestMapping(value="/delete")
        public String deleteMethod(int[] ids,Model model) throws Exception{
            System.out.println("UserAction::deleteMethod()");
            System.out.println("需要删除的id为:");
            for(int id : ids){
                System.out.print(id+" ");
            }
            model.addAttribute("message","批量删除成功");
            return "/success.jsp";
        }
    }
    View Code

      8)在业务控制方法中收集List<JavaBean>参数

    批量注册用户

    UserAction.java
    @Controller
    @RequestMapping(value="/user")
    public class UserAction {
        @RequestMapping(value="/addAll")
        public String addAll(Bean bean,Model model) throws Exception{
            for(User user : bean.getUserList()){
                System.out.println(user.getName()+":"+user.getGender());
            }
            model.addAttribute("message","批量增加用户成功");
            return "/success.jsp";
        }
    }
    Bean.java
    public class Bean {
        private List<User> userList = new ArrayList<User>();
        public Bean(){}
        public List<User> getUserList() {
            return userList;
        }
        public void setUserList(List<User> userList) {
            this.userList = userList;
        }
    }
     registerAll.jsp
        <form action="${pageContext.request.contextPath}/user/addAll.action" method="POST"> 
             
            姓名:<input type="text" name="userList[0].name" value="哈哈"/>
            性别:<input type="text" name="userList[0].gender" value=""/>
            <hr/>
            
            姓名:<input type="text" name="userList[1].name" value="呵呵"/>
            性别:<input type="text" name="userList[1].gender" value=""/>
            <hr/>
    
            姓名:<input type="text" name="userList[2].name" value="嘻嘻"/>
            性别:<input type="text" name="userList[2].gender" value=""/>
            <hr/>
            
            <input type="submit" value="批量注册"/>
            
        </form>
    View Code

      9)结果的转发和重定向

    在转发情况下,共享request域对象,会将参数从第一个业务控制方法传入第二个业务控制方法,反之,重定向则不行

    @Controller
    @RequestMapping(value="/user")
    public class UserAction {
    
        @RequestMapping(value="/delete")
        public String delete(int id) throws Exception{
            System.out.println("删除用户->" + id);
            //转发到find()
            return "forward:/user/find.action";
            //重定向到find()
            //return "redirect:/user/find.action";
        }
        
        @RequestMapping(value="/find")
        public String find(int id) throws Exception{
            System.out.println("查询用户->" + id);
            return "/success.jsp";
        }
        
    }
    View Code

      10)异步发送表单数据到JavaBean,并响应JSON文本返回

    @ResponseBody

    @Controller
    @RequestMapping(value="/user")
    public class UserAction {
    
        @RequestMapping(value="/add")
        public @ResponseBody User add(User user) throws Exception{
            System.out.println(user.getId()+":"+user.getName()+":"+user.getSal());
            return user;
        }
        
    }
    View Code

    ------------------------------------需要注意的点-----------------------------------------

    1.@restController 和@Controller区别

      @restController是包含@Controller和@ResponseBody的,这里不能配合视图解析器InternalResourceViewResolver,返回jsp页面

      @Controller会配合InternalResourceViewResolver返回jsp页面

      建议:@Controller和@ResponseBody组合使用

  • 相关阅读:
    Spring——注解代替XML配置文件,Spring与JUnit整合
    Spring——基本概念(IOC,DI思想),Spring配置文件(XML),属性注入,Spring与Web项目结合
    Struts——自定义拦截器
    Struts——OGNL表达式与Struts2结合
    Struts2——结果跳转方式配置(重定向,转发<默认>,重定向到方法,重定向到转发),获取servlet的内些API(request,servletcontext...),获取参数
    Struts2——基本使用与配置文件
    基于中间件的RBAC权限控制
    Django
    Django
    Django 中 admin 的执行流程
  • 原文地址:https://www.cnblogs.com/xiaoping1993/p/6951521.html
Copyright © 2020-2023  润新知