• springMVC-入门


    springMVC(替代struts)(就是通过配置servlet,使普通的类通过注释被扫描变成控制器)的基本使用方法
    
        1.加入对应的jar包
            commons-logging-1.2.jar
            spring-aop-4.0.0.RELEASE.jar
            spring-beans-4.0.0.RELEASE.jar
            spring-context-4.0.0.RELEASE.jar
            spring-core-4.0.0.RELEASE.jar
            spring-expression-4.0.0.RELEASE.jar
            spring-web-4.0.0.RELEASE.jar
            spring-webmvc-4.0.0.RELEASE.jar
            
        2.在web.xml中直接alt+/,选择#dispatcherservlet
            <servlet>
                <servlet-name>springDispatcherServlet</servlet-name>
                <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
                <!-- 
                    <init-param>也可以不配置,那么将使用默认的路径,为/WEB-INF/<servlet-name>-servlet.xml
                 -->
                <init-param>
                    <param-name>contextConfigLocation</param-name>
                    <!-- spring配置文件的位置 -->
                    <param-value>classpath:springmvc.xml</param-value>
                </init-param>
                <!-- 代表在web应用初始化时创建servlet -->
                <load-on-startup>1</load-on-startup>
            </servlet>
        
            <servlet-mapping>
                <servlet-name>springDispatcherServlet</servlet-name>
                <!-- 
                    开头的/代表web应用的根目录
                    该servlet处理的请求
                    会使用servletPath,即/nihao来匹配
                    
                    /*和/都是匹配所有请求,
                        > /是缺省匹配,优先级最低,也是默认的匹配项
                        > /*是路径匹配,优先级高于扩展名匹配仅次于精准匹配,会覆盖掉优先级低的匹配
                            若使用/*会覆盖默认的缺省匹配,那么在刚开始请求index.jsp页面时就匹配了,但找不到对应的响应所以会报404
                 -->
                <url-pattern>/</url-pattern>
            </servlet-mapping>
            
        3.可以看出springMVC是使用了servlet,这是与struts的区别
        
        4.在spring配置文件中
                <context:component-scan base-package="handlers"></context:component-scan>
        
                <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                    <!-- 
                        prefix的value中开头的/代表web应用根目录。
                        若写了开头的/
                            >那么响应的页面会是正常的/springMVC-helloworld/WEB-INF/view/success.jsp
                        若不写开头的/
                            >@RequestMapping("/QQ")加在类前了,那么响应的页面是/springMVC-helloworld/QQ/WEB-INF/view/success.jsp
                            >@RequestMapping("/QQ")没有加在类前,那么还是正常的/springMVC-helloworld/WEB-INF/view/success.jsp
                     -->
                    <property name="prefix" value="/WEB-INF/view/"></property>
                    <property name="suffix" value=".jsp"></property>
                </bean>
                
        5.编写控制类handler(就是普通的类,通过注释成为了控制器,类似与Action类)
            @RequestMapping("/QQ")
            @Controller
            public class myHandler {
                /**
                 * @RequestMapping 中value代表会响应的contextPath
                 * 根据spring中的配置,会到prefix+returnValue+suffix。即WEB-INF/view/success.jsp
                 * 
                 * 
                 * nihao和/nihao其实是一样的,响应是随机选一个,但在初始化时就确定响应哪一个方法了
                 * 
                 * @RequestMapping("/QQ") 若写在类上面,则请求映射信息变为/QQ/nihao
                 * */
            //    @RequestMapping(value="/nihao")
            //    public String hello2(){
            //        System.out.println("To Success2");
            //        return "success2";
            //    }
                @RequestMapping(value="nihao")
                public String hello(){
                    System.out.println("To Success");
                    return "success";
                }
            }
    1.@RequestMapping(value="nihao"),其中的value支持ant风格匹配
        Ant风格 资源地址支持 源地址支持 3?匹文件名中一个字
        *匹文件名中任意字
        **匹多层路径
        /user/*/createUser: 匹配/user/aaa/createUser、/user/bbb/createUser  URL
        /user/**/createUser: 匹配/user/createUser、/user/aaa/bbb/createUser  URL
        /user/createUser??: 匹配/user/createUseraa、/user/createUserbb  URL
    
    2.@PathVariable注解:用于得到URL中的值信息。
        在请求映射中添加占位符,在方法形参前加@PathVariable(value="id")注解就可以得到id
            @RequestMapping("/**/testVariable/{id}")
            public String testPathVariable(@PathVariable(value="id") int id){}
            
    3.REST风格:表现层状态转化
        REST风格的增删改查,分别对应POST,DELETE,PUT,GET请求
        
    4.如何使用PUT,DELETE请求
        1.先在web.xml中配置HiddenHttpMethodFilter拦截器
        2.必须是POST请求
        3.且携带参数_method,它的值就是发出请求的方式
        例:
            <form action="QQ/order/1" method="post">
                <input type="hidden" name="_method" value="put">
                <input type="submit" value="更新">
            </form>
            <form action="QQ/order/1" method="post">
                <input type="hidden" name="_method" value="delete">
                <input type="submit" value="删除">
            </form>
    
    5.@RequestParam注解(放在形参之前):获取请求的参数,放入形参中
        @RequestParam(value="username",required=true,defaultValue="ji")
        value="username":请求参数的名字
        required=true:是否必须携带该请求参数
        defaultValue="ji":(一旦设置了defaultValue,required就失效了)当请求不带有该参数时就将其设置为ji
                            注意:testRequestParam和testRequestParam?username不一样
                                前者username为ji,是为不带;后者username为"",是为带了
                                testRequestParam?username&age : username为""。age为null,所以age不能为int而是Integer
    
    6.@CookieValue,@RequestHeader和@RequestParam使用方法相同
    
    7.Pojo作为参数
        可以直接将请求的参数封装到方法的形参对象中,而且在表单上可以写级联属性,不需要配置什么
        该形参是自定义的普通的java类(Pojo),其中的属性名和表单上<input>的name属性相同
    
    8.Servlet原生的API作为参数
        可以直接在方法的形参中写Servlet原生的类对象在方法中使用
        支持写ServletRequest,ServletResponse,HttpSession,Principal,Locale,
        InputStream,Reader,OutputStream,Writer。
        原理如下:
                if (ServletRequest.class.isAssignableFrom(parameterType) ||
                        MultipartRequest.class.isAssignableFrom(parameterType)) {
                    Object nativeRequest = webRequest.getNativeRequest(parameterType);
                    if (nativeRequest == null) {
                        throw new IllegalStateException(
                                "Current request is not of type [" + parameterType.getName() + "]: " + request);
                    }
                    return nativeRequest;
                }
                else if (ServletResponse.class.isAssignableFrom(parameterType)) {
                    this.responseArgumentUsed = true;
                    Object nativeResponse = webRequest.getNativeResponse(parameterType);
                    if (nativeResponse == null) {
                        throw new IllegalStateException(
                                "Current response is not of type [" + parameterType.getName() + "]: " + response);
                    }
                    return nativeResponse;
                }
                else if (HttpSession.class.isAssignableFrom(parameterType)) {
                    return request.getSession();
                }
                else if (Principal.class.isAssignableFrom(parameterType)) {
                    return request.getUserPrincipal();
                }
                else if (Locale.class.equals(parameterType)) {
                    return RequestContextUtils.getLocale(request);
                }
                else if (InputStream.class.isAssignableFrom(parameterType)) {
                    return request.getInputStream();
                }
                else if (Reader.class.isAssignableFrom(parameterType)) {
                    return request.getReader();
                }
                else if (OutputStream.class.isAssignableFrom(parameterType)) {
                    this.responseArgumentUsed = true;
                    return response.getOutputStream();
                }
                else if (Writer.class.isAssignableFrom(parameterType)) {
                    this.responseArgumentUsed = true;
                    return response.getWriter();
                }
    
    9.ModelAndView的使用(是一种向域对象中添加属性的方式)
        实际上,目标方法返回的字符串最终是被封装成了一个ModelAndView对象。也可以直接返回一个ModelAndView对象。
        原来返回的字符串被封装在modelAndView作为view的部分存在;addObject添加的对象作为model部分存在。
        model部分在页面上作为request的属性存在。
            @RequestMapping("/testModelAndView")
            public ModelAndView testModelAndView(){
                String viewName = "success";
                ModelAndView modelAndView = new ModelAndView(viewName);
                modelAndView.addObject("time", new Date());//此处添加的对象在requestScope的域中
                return modelAndView;
            }
            
    10.使用Map,ModelMap,Model作为目标方法的形参
        则这些形参中添加的对象 在页面上作为request的属性存在。
            @RequestMapping("/testMap")
            public String testMap(Map<String,Object> names,ModelMap time,Model add,HttpServletRequest request){
                names.put("names", Arrays.asList("Ji","Yun","Fei"));
                time.put("time", new Date());
                add.addAttribute("add", new Address("HeNan", "JiaoZuo"));
                request.setAttribute("age", 12);
                return "success";
            }        
        <!-- 
            href中的开头的/代表站点的根目录。不写则代表当前文件所在目录
            所以此强求为http://localhost:8080/springMVC-helloworld/QQ/nihao
         -->
        <a href="QQ/nihao">To Success</a>
        <!-- 以下这种方式若什么都不输入就提交和 QQ/testRequestParam?username&age GET请求相同 -->
        <form action="QQ/testRequestParam" method="post">
            <input type="hidden" name="_method" value="get">
            <input type="text" name="username">
            <input type="text" name="age">
            <input type="submit" value="TestReuqestParam">
        </form>

    Web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
        id="WebApp_ID" version="3.1">
        
        <servlet>
            <servlet-name>springDispatcherServlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <!-- 
                <init-param>也可以不配置,那么将使用默认的路径,为/WEB-INF/<servlet-name>-servlet.xml
             -->
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <!-- spring配置文件的位置 -->
                <param-value>classpath:springmvc.xml</param-value>
            </init-param>
            <!-- 代表在web应用初始化时创建servlet -->
            <load-on-startup>1</load-on-startup>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>springDispatcherServlet</servlet-name>
            <!-- 
                开头的/代表web应用的根目录
                该servlet处理的请求
                会使用servletPath,即/nihao来匹配
                
                /*和/都是匹配所有请求,
                    > /是缺省匹配,优先级最低,也是默认的匹配项
                    > /*是路径匹配,优先级高于扩展名匹配仅次于精准匹配,会覆盖掉优先级低的匹配
                        若使用/*会覆盖默认的缺省匹配,那么在刚开始请求index.jsp页面时就匹配了,但找不到对应的响应所以会报404
             -->
            <url-pattern>/</url-pattern>
        </servlet-mapping>
        
        <filter>
            <filter-name>MethodFilter</filter-name>
            <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>MethodFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
        
    </web-app>

    spring配置文件

    <?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:aop="http://www.springframework.org/schema/aop"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    
        
        <context:component-scan base-package="handlers"></context:component-scan>
        
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <!-- 
                prefix的value中开头的/代表web应用根目录。
                若写了开头的/
                    >那么响应的页面会是正常的/springMVC-helloworld/WEB-INF/view/success.jsp
                若不写开头的/
                    >@RequestMapping("/QQ")加在类前了,那么响应的页面是/springMVC-helloworld/QQ/WEB-INF/view/success.jsp
                    >@RequestMapping("/QQ")没有加在类前,那么还是正常的/springMVC-helloworld/WEB-INF/view/success.jsp
             -->
            <property name="prefix" value="/WEB-INF/view/"></property>
            <property name="suffix" value=".jsp"></property>
        </bean>
        
    </beans>

    控制器MyHandler.java

    package handlers;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    
    @RequestMapping("/QQ")
    @Controller
    public class MyHandler {
        /**
         * @RequestMapping 中value代表会响应的contextPath
         * 根据spring中的配置,会到prefix+returnValue+suffix。即WEB-INF/view/success.jsp
         * 
         * 
         * nihao和/nihao其实是一样的,响应是随机选一个,但在初始化时就确定响应哪一个方法了
         * 
         * @RequestMapping("/QQ") 若写在类上面,则请求映射信息变为/QQ/nihao
         * */
    //    @RequestMapping(value="/nihao")
    //    public String hello2(){
    //        System.out.println("To Success2");
    //        return "success2";
    //    }
        @RequestMapping(value="nihao")
        public String hello(){
            System.out.println("To Success");
            return "success";
        }
        /**
         * 此外RequestMapping注释还可以使请求更加精准,例如
         * 
         * method=RequestMethod.POST,只映射post方式的testRequestMapping请求
         * 
         * params={"username=ji","age!=10","!password"}:只映射参数符合条件的请求.
         *         有username且=ji,有age且!=10",没有password
         * 
         * headers={""},对请求的头的要求,书写方式和params方式类似
         * */
        @RequestMapping(value="/testRequestMapping",method=RequestMethod.POST,
                params={"username=ji","age!=10","!password"})
        public String testRequestMapping(){
            System.out.println("To Success");
            return "success";
        }
        
        @RequestMapping("/**/testVariable/{id}")
        public String testPathVariable(@PathVariable(value="id") int id){
            System.out.println("PathVariable"+id);
            return "success";
        }
        
        @RequestMapping(value="/**/order/{id}",method=RequestMethod.GET)
        public String testMethodFilterGET(@PathVariable(value="id") int id){
            System.out.println("GET"+id);
            return "success";
        }
        @RequestMapping(value="/**/order",method=RequestMethod.POST)
        public String testMethodFilterPOST(){
            System.out.println("POST");
            return "success";
        }
        @RequestMapping(value="/**/order/{id}",method=RequestMethod.PUT)
        public String testMethodFilterPUT(@PathVariable(value="id") int id){
            System.out.println("PUT"+id);
            return "success";
        }
        @RequestMapping(value="/**/order/{id}",method=RequestMethod.DELETE)
        public String testMethodFilterDELETE(@PathVariable(value="id") int id){
            System.out.println("DELETE"+id);
            return "success";
        }
        
        @RequestMapping(value="/testRequestParam",method=RequestMethod.GET)
        public String testRequestParam(@RequestParam(value="username",required=true,defaultValue="ji") String username,
                @RequestParam(value="age",required=false,defaultValue="0") Integer age){
            System.out.println(username+":"+age);
            return "success";
        }
    }

    控制器2MyHandler.java

    package handlers;
    
    import java.util.Arrays;
    import java.util.Date;
    import java.util.Map;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.ui.ModelMap;
    import org.springframework.web.bind.annotation.CookieValue;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.servlet.ModelAndView;
    
    import model.Address;
    import model.User;
    
    @Controller
    public class MyHandler2 {
        
        @RequestMapping("/testMap")
        public String testMap(Map<String,Object> names,ModelMap time,Model add,HttpServletRequest request){
            names.put("names", Arrays.asList("Ji","Yun","Fei"));
            time.put("time", new Date());
            add.addAttribute("add", new Address("HeNan", "JiaoZuo"));
            request.setAttribute("age", 12);
            return "success";
        }
        
        @RequestMapping("/testModelAndView")
        public ModelAndView testModelAndView(){
            String viewName = "success";
            ModelAndView modelAndView = new ModelAndView(viewName);
            modelAndView.addObject("time", new Date());//此处添加的对象在requestScope的域中
            return modelAndView;
        }
        
        @RequestMapping("testCookieValue")
        public String testCookieValue(@CookieValue("JSESSIONID")String jsessionid){
            System.out.println(jsessionid);
            return "success";
        }
        
        /**
         * 可以直接将请求的参数封装到方法的形参对象中,而且在表单上可以写级联属性,不需要配置什么
         * 该形参是自定义的普通的java类(Pojo),其中的属性名和表单上<input>的name属性相同
         * */
        @RequestMapping("testPojo")
        public String testPojo(User user,HttpServletRequest req){
            System.out.println(user);
            System.out.println(req);
            return "success";
        }
        
    }
  • 相关阅读:
    openssl 生成pfx
    webpack 编译时,提示 Unexpected token: keyword «const»
    .net core 使用 Serilog 作为日志提供者
    k近邻算法
    vscode 无法自动补全第三方库
    centos 7 安装 RabbitMQ
    .net core 发布程序命令(自带运行环境)
    安装node-sass
    .net core 拦截socket
    SDN第三次作业
  • 原文地址:https://www.cnblogs.com/feifeiyun/p/6606562.html
Copyright © 2020-2023  润新知