07-SpringMVC01

今日知识

1. SpringMVC入门
2. SpringMVC的注解开发

SpringMVC入门

1. 简介:
    * Spring MVC是Spring提供的一个强大而灵活的web框架。借助于注解,Spring MVC提供了几乎是POJO的开发模式,使得控制器的开发和测试更加简单。这些控制器一般不直接处理请求,而是将其委托给Spring上下文中的其他bean,通过Spring的依赖注入功能,这些bean被注入到控制器中。
    * Sping MVC 主要由DispatcherServlet,处理器映射【找控制器】、适配器【调用控制器的方法】、控制器【业务】、视图解析器、视图组成。
2. 入门案例
    1. 导包:
        * spring-webmvc.jar和log4j.jar和servlet.jar
    2. web.xml配置DispatchServlet
        *  <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
    3. 配置WEB-INF/DispatcherServlet-servlet.xml
        * <!--配置处理器映射
     BeanNameUrlHandlerMapping:根据bean的name属性的url去找handlerController
    -->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    <!--配置适配器执行Controller-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
    <!--配置一个控制器-->
    <bean name="/user.do" class="com.rqy.controller.UserController"/>
    <!--配置springmvc视图解析器
            视图解析器解析的视频路径为:前缀 + 后缀
            spring会自动拼接路径
    -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    4. UserController处理页面请求com.rqy.controller.UserController
        * public class UserController implements Controller {
        @Override
        public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
            //返回jsp视图
            ModelAndView mv = new ModelAndView("user/userList");
            //设置数据,让jsp页面获取
            mv.addObject("name","任清阳");
            return mv;
        }
    }
    5. 视图层配置WEB-INF/views/user/userList.jsp
        * ${name}

Url处理器映射

1. BeanNameUrlHandlerMapping
    * 功能:寻找Controller
    * 根据url请求去匹配bean的name属性,从而获取Controller
    * 案例
    * <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    <!--配置处理器适配器执行Controller-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
    <!--配置一个控制器-->
    <bean name="/user.do" class="com.rqy.controller.UserController"/
2. SimpleUrlHandlerMapping
    * 功能:寻找Controller
    * 根据浏览器url匹配简单url的key,key就是Controller的id找到Controller
    * 案例
    * <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="/user1.do">userController</prop>
            </props>
        </property>
    </bean>
    <!--配置处理器适配器执行Controller-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
    <!--配置一个控制器-->
    <bean id="userController" class="com.rqy.controller.UserController"/>
    * 测试路径
    * http://localhost/user1.do
3. ControllerClassNameHandlerMapping
    * 功能:寻找Controller
    * 根据类名(MyController)类名.do来访问,类名首字母小写
    * 类名全部小写也可以,写一半也可以
    * 案例
    * 
    * 测试路径
    * http://localhost/userController.do
    *

处理器适配器

1. SimpleControllerHandlerAdapter 
    * 功能:执行controller
    * 调用controller里面方法,返回modelAndView
    *   <!--配置处理器适配器执行Controller-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
    * <!--配置一个控制器-->
    <bean  name="/user.do" class="com.rqy.controller.UserController"/>
    * UserController实现Controller接口
    * public class UserController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //返回jsp视图
        ModelAndView mv = new ModelAndView("user/userList");
        //设置数据,让jsp页面获取
        mv.addObject("name","任清阳");
        return mv;
    }
}

2. HttpRequestHandlerAdapter
    * 功能:执行controller
    * 负责调用实现HttpRequestHandler接口的控制器
    *  <bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"/>
    *  <bean name="/http.do" class="com.rqy.controller.HttpController"/>
    *  HttpController应该实现HttpRequestHandler接口
    *  public class HttpController implements HttpRequestHandler {
    @Override
    public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setAttribute("name","任清阳11");
        request.getRequestDispatcher("/WEB-INF/views/user/userList.jsp").forward(request,response);
    }
}
    *  注意:两个处理器适配器可以共存

命令控制器

1. springMVC通过设计模式接收页面的参数
2. Command控制器
    1. 创建useradd.JSP   from表单提交给commend.do处理
    2. xml配置
        * <bean name="/command.do" class="com.rqy.controller.CommandController"/>
    3. CommandController类创建
        * public class CommandController extends AbstractCommandController {
        public CommandController(){
            //指定bean来接收参数
            this.setCommandClass(User.class);
        }
        @Override
        protected ModelAndView handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, BindException e) throws Exception {
            //装换为用户对象
            User user= (User) o;
            //打印参数
            System.out.println(user);
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.addObject("user",user);
            //返回jsp页面
            modelAndView.setViewName("user/info");
            return modelAndView;
        }
    }
    4. info.jsp用于数据显示

SpringMVC注解开发

1. xml配置
    * web.xml配置(指定接收请求的url的配置文件)
    *  <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:application2.xml</param-value>
        </init-param>
    * application.xml配置
    *  <mvc:annotation-driven/>代替了处理器和适配器
    <!--设置注解扫面范围-->
    <context:component-scan base-package="com.rqy.controller"/>
    <!--配置springmvc视图解析器
            视图解析器解析的视频路径为:前缀 + 后缀
            spring会自动拼接路径
    -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
2. 控制器的类需要声明
    1. @Controller
    * //相当于在xml配置控制器路径,<bean  name="/useradd.do" class="com.rqy.controller.UserController"/>
    2. @RequestMapping("/user"),代表资源路径
3. 方法还可以指定资源路径,访问的之后需要将类名和方法名上面的资源路径拼接访问
    * @RequestMapping("/list")
4. 访问路径=/user/list
5. 注解的多种方式
@RequestMapping(value="list",params={"username","password"})
@RequestMapping(“/list”)
@RequestMapping(value={“list”,"list1"})//多个请求映射到同一个方法
//一个Url映射到不同的方法上:通过请求方法的限定来实现的:
    @GetMapping("uniqueUrl")
    @PostMapping("uniqueUrl")
@RequestMapping(“/list.do”)
@RequestMapping(value=”/list.do”)
@RequestMapping(value = "/list3",method=RequestMethod.POST) 只能使用POST方法
@RequestMapping(value = "/list3",method=RequestMethod.Get) 只能使用GET方法

接收请求参数的方法

1. 接收int,String,Date,数组类型
    * 直接在对应的方法中用参数来接收
2. 接收pojo类型
    * 表单name标签正常写,与类对象属性名保持一致
    * 参数用对象接收 :login(User user)
    * 自动封装
3. 接收包装类型参数
    * 把User写成(UserExt)属性类:User user
    * 参数用对象接收 :login(UserExt user)
    * 表单写法user.username
4. 接收集合List类型参数
    * 在UserExt扩展中添加一个集合:List<User> userList
    * 参数用对象接收 :login(UserExt user)
    * 表单写法name=userList[0].username,userList[0].password
    * 可以同时注册两个用户:userList[1].username
5. 接收集合Map类型参数
    * 在UserExt扩展中添加一个Map:Map<String,Object> map
    * 参数用对象接收 :login(UserExt user)
    * 表单写法name=map['username'],name=map['password']
6. Date数据的处理,配置之后,默认所有的提交的Date数据,都会被格式化
    1. 格式化方法类
    public class StringDateConverter  implements Converter<String,Date>{
    @Override
    public Date convert(String value) {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");

        try {
            //将字符串格式化为时间类型
            Date parse = sdf.parse(value);
            return parse;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
}   
    2. xml的配置
      <!--注册的转化工具类-->
    <mvc:annotation-driven conversion-service="MyConversionService"/>
    <!--注册转换工具类-->
    <bean id="myStringDateConverter" class="com.rqy.converter.StringDateConverter"/>
    <bean id="MyConversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters">
            <set>
                <!--<bean id="myStringDateConverter" class="com.rqy.converter.StringDateConverter"/>
   -->
                <ref bean="myStringDateConverter"/>
            </set>
        </property>
    </bean>
    3. jsp页面
    <h1>时间类型的处理</h1>
    <form action="${pageContext.request.contextPath}/user/submitDate" method="post">
        生日:<input type="text" name="birthday"><br>
        <input type="submit">
    </form>
    4. 接收请求的方法的 
    //时间类型转换
    @RequestMapping("/submitDate")
    public String submitDate(Date birthday){
        System.out.println(birthday);
        return "stu/success";
    }

SpringMVC与Struts的区别(面试题)

1. 实现机制
    * Struts2基于过滤器实现
    * SpringMVC基于servlet实现
2. 运行速度
    * servlet比过滤器块
    * Struts是多例的
    * 每一次请求,都会创建一个Action对象
    请求来了以后,struts2创建多少个对象:ActionContext,valuestack,UAction,ActionSuport,  
    * SpringMVC是单例的: 同一个Controller请求,只会创建一个Controller
    * 
3. 参数封装
    * Struts基于属性进行封装,Action有参数属性
    * SpringMVC基于方法封装,参数写在Controller的方法

页面回显

1. 将集合赋值,同时方法里面加入参数Model model
2.  model.addAttribute("userList",list);
3. return "user/info";转发到页面进行EL表达式进行展示

URL模板映射

1. url模版映射可以restfull软件架构
2.     <a href="${pageContext.request.contextPath}/rest/user/edit1/${user.id}">编辑</a>
3.  {}:匹配接受页面Url路径参数
    * @RequestMapping("/edit1/{id}")
    public String list3(@PathVariable  Integer id,@RequestHeader("Aspect") String aspect, Model model){
        //{id} == id
        System.out.println(id);
        return "user/info";
    }
4. @RequestHeader("Aspect"):获取请求头的参数信息

转发和重定向(转发到指定方法中)

1. 转发
    * 转发到同一个容器(user容器)
    * return "forward:list.do"
    * 转发到不同的容器(stu容器)
    * return "forward:/user/list.do"
2. 重定向,只需要把forward改成redirect
    * return "redirect:/user/list.do"
3. 代表直接转发到某个页面:return "user/userList";
4. 转发到某个页面时候:/user 代表相对于webapp的资源路径,
不加/, user,代表相对于注解的资源路径(会自动把注解路径拼接上导致报错)
5. 实例
单级url:
forward和direct:访问(不)同一个容器资源加或不加“/”都可以
多级url中:
1. 访问同一个容器资源
    forward:不包含“/”,访问同一个容器资源ok
    forward:包含“/”,访问同一个容器资源出错404
    direct:加“/”,访问同一个容器资源,根目录路径会消失,变成localhost/hello,期望的是localhost/user/hello
    direct:不加“/”,访问同一个容器资源,ok,与期望值一样:localhost/user/hello
    总结:访问同一个容器的时候,无论forward或者direct,都不要加“/”
    举例:  return "forward:hello";
    	return "redirect:hello";

2. 访问不同一个容器资源
    forward:包含“/”,访问不同一个容器资源ok
    forward:不包含“/”,访问不同一个容器资源出错404
    direct:不加“/”,访问不同一个容器资源,根目录路径会消失,变成localhost/user/stu/hello,期望的是localhost/stu/hello
    direct:加“/”,访问不同一个容器资源,ok,与期望值一样:localhost/stu/hello
    总结:访问不同一个容器的时候,无论forward或者direct,都要加“/”
    举例:	return "redirect:/stu/register";
    	return "forward:/stu/register";

RequestParam

1. RequestParam参数描述
    * value:参数名称
	* defaultValue:默认值
	* required:参数是否必须有值,如果为true,参数又为空,会报错
	* 举例;
	*  public String list3(@RequestParam(value = "uid",required = true,defaultValue ="1")Integer uid)
posted @ 2019-07-31 17:43  励志前行  阅读(135)  评论(0编辑  收藏  举报