zoukankan      html  css  js  c++  java
  • springmvc快速入门

    关于三层架构:

    springmvc是spring框架的一个模块,springmvc和spring无需通过中间整合层进行整合。

    springmvc是一个基于mvc模式的web架构。

    springmvc用于前后端的数据交互。


    SpringMvc工作流程

    第一步:发送请求到前端控制器(DispatcherServlet)

    第二步:前端控制器请求处理器映射器(HandlerMapping)查找Handler

    第三步:处理器映射器返回Handler到前端控制器

    第四步:前端控制器调用处理器适配器去执行Handler

    第五步:处理器适配器去执行Handler

    第六步:Handler执行完成给适配器返回ModelAndView

    第七步:处理器适配器向前端控制器返回ModelAndView

    ModelAndView是springmvc框架的一个底层对象,包括 Model和view

    第八步:前端控制器请求视图解析器去进行视图解析

    根据逻辑视图名解析成真正的视图(jsp)

    第九步:视图解析器向前端控制器返回View

    第十步:前端控制器进行视图渲染

    视图渲染将模型数据(在ModelAndView对象中)填充到request域

    第十一步:前端控制器向用户响应结果


    SpringMvc快速上手

    一.SpringMvc的相关配置

    1.所需的jar的引入
    <dependencies>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>4.2.4.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>4.2.4.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-web</artifactId>
          <version>4.2.4.RELEASE</version>
        </dependency>
      </dependencies>
    
    2.web.xml中的配置

    在web.xml中主要配置的是前端控制器,前端控制器的作用是:通过用户的url请求路径查找到匹配该请求的handler,在将用户的请求交由相应的handler处理。

    <!-- 配置前端控制器 -->
      <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:springmvc.xml</param-value>//指定配置文件所在位置,默认在WEB-INF下
        </init-param>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>*.action</url-pattern>			//指定拦截的路径
      </servlet-mapping>
    
    3.springmvc.xml的配置
        <!-- 配置视图解析器:解析转向页面,prefix:前缀,suffix:后缀
            将controller层的返回值进行解析,加上前缀和后缀,就解析成了一个jsp页面,跳转到该页面
            -->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/jsp/"/>
            <property name="suffix" value=".jsp"/>
        </bean>
    	
        <!-- 注解扫描:将扫描配置的包,将符合要求的纳入spring容器 -->
        <context:component-scan base-package="cn.fzkj.controller"/>
            
        <!-- 开启注解支持 -->
        <mvc:annotation-driven/>
    

    二.RequestMapping注解

    使用 @RequestMapping注解映射请求路径,就是将前端的请求交给具体的方法去执行。例如:

    前端请求:

    <a href="user/login.action">登录</a>
    

    Controller层:

    @Controller
    @RequestMapping("/user")
    public class userController {
        @RequestMapping("/login.action")
        public String testLogin(){
            System.out.println("登录成功");
            return "success";
        }
    }
    

    @RequestMapping("/user")是请求的前缀,主要用于对项目进行划分模块。@RequestMapping("/login.action")是请求的具体映射。SpringMvc会拦截所有请求(不准确),并在Controller对应的类中找符合的映射,交由该方法去处理。

    RequestMapping注解的属性

    1.value:用于指定请求的url,和path属性的作用相同

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

    2.method:用于指定请求的方式(GET、POST)

    @RequestMapping(value="",method={RequestMethod.GET})
    

    3.params:用于指定请求的参数,要求请求的key和value要和配置的相同

    @RequestMapping(value="",method={},params={"username"})//必须传username参数
    

    三.请求参数的绑定

    就是前端给后端传递参数

    • 第一种:基本类型

    前端页面代码

     <a href="user/login.action?username=mr">登录</a>
    

    后端代码

     @RequestMapping("/login.action")
        public String testLogin(String username){  //参数名要和前端传递的参数名保持一致
            System.out.println("登录成功");
            System.out.println("用户名:"+username);
            return "success";
        }
    
    • 第二种:实体类型(javabean)

    前端页面代码

        <form action="user/user.action" method="POST">
            姓名:<input type="text" name="username" /><br>
            年龄:<input type="text" name="age" /><br>
            账户名:<input type="text" name="account.name" /><br>
            金额:<input type="text" name="account.money" /><br>
            <input type="submit" value="提交"/>
        </form>
    

    name属性要和JavaBean的属性名称一致

    后端页面代码

        @RequestMapping("/user.action")
        public String testuser(User user){ //自动封装成JavaBean
            System.out.println(user);
            return "success";
        }
    

    四.注解

    1.RequestParam注解

    之前说控制层接收的参数名要和表现层传递的参数名保持一致,那如果不一致要怎么办呢?

    <a href="user/login.action?username=mr">登录</a>
    
        @RequestMapping("/login.action")
        public String testLogin(String name){
            System.out.println("登录成功");
            System.out.println("用户名:"+username);
            return "success";
        }
    

    前端传一个名为username的参数,而后端接收的却是name参数,按照之前讲的这样肯定是接收不到的。

    RequstParam注解就是解决这个问题的

    修改之后的代码

        @RequestMapping("/login.action")
        public String testLogin(@RequestParam("username") String name){
            System.out.println("登录成功");
            System.out.println("用户名:"+name);
            return "success";
        }
    

    RequestParam的参数就是前端传递的参数名,该注解会将接收到的参数保存到后面的变量中(即name中)

    要赋值的变量必须紧跟着RequestParam注解且在其后面

    2.RequestBody注解

    @RequestBody注解用来接收请求体的内容,请求方式必须是POST,GET请求无请求体。

       <form action="user/user.action" method="POST">
            姓名:<input type="text" name="username" /><br><br>
            年龄:<input type="text" name="age" /><br><br>
            <input type="submit" value="提交"/>
        </form>
    
        @RequestMapping("/user.action")
        public String testuser(@RequestBody String body){
            System.out.println(body);
            return "success";
        }
    

    运行结果:

    username=mr&age=20
    
    3.PathVariable注解

    用于接收url中占位符的值

     <a href="/user/testPathVariable/22">testPathVariable</a>
    
        @RequestMapping("/testPathVariable/{id}")
        public String testPathVariable(@PathVariable("id") String id){
            System.out.println(id);
            return "success";
        }
    

    运行结果

    22
    

    五.响应的返回值

    1.String类型
        @RequestMapping("/login.action")
        public String testLogin(@RequestParam("username") String name){
            System.out.println("登录成功");
            System.out.println("用户名:"+name);
            return "success";
        }
    

    返回值类型为String,返回值会经过视图解析器解析成为jsp页面,最终显示。

    2.void类型

    返回值是void类型的方法有三种跳转页面的方式

    • 请求转发

    • 请求重定向

    • 输出流

        @RequestMapping("/testVoid.action")
        public void testVoid(HttpServletRequest request, HttpServletResponse response) throws Exception {
            System.out.println("testVoid方法执行了....");
            //1.请求转发(一次请求)
    //       request.getRequestDispatcher("/WEBINF/jsp/success.jsp").forward(request,response);
            //2.请求重定向(两次请求)
    //        response.sendRedirect(request.getContextPath()+"/index.jsp");
            //3.直接向浏览器输出
            response.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");
            response.getWriter().print("mr");
           return;
        }
    
    3.ModelAndView对象类型
    @RequestMapping("/testModelAndView.action")
        public ModelAndView testModelAndView(){
            //创建ModelAndView对象
            ModelAndView mv = new ModelAndView();
            System.out.println("testModelAndView执行了...");
            Account a =new Account();
            a.setMoney(1000.0);
            a.setName("123");
            User user = new User();
            user.setUsername(456");
            user.setAccount(a);
            user.setAge(20);
            
            //把user对象存放到mv对象中,同时也会保存到request域中
            mv.addObject("user",user);
            //设置要跳转的页面,默认经过试图解析器
            mv.setViewName("success");
            
            return mv;
        }
    
    4.使用forward和redirect关键字进行页面跳转
        @RequestMapping("/testGuanjianzi.action")
        public String testGuanjianzi() throws IOException {
            System.out.println("登录成功1");
            //使用forward请求转发
    //        return "forward:/WEB-INF/jsp/success.jsp";
            //redirect重定向
            return "redirect:/index.jsp";
        }
    

    六.json格式的数据传递

    ​ 所需的jar包:

        <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-core</artifactId>
          <version>2.9.0</version>
        </dependency>
        <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
          <version>2.9.0</version>
        </dependency>
        <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-annotations</artifactId>
          <version>2.9.0</version>
        </dependency>
    

    使用ajax进行异步交互

        <script src="js/jquery-3.4.1.min.js"></script>
        <script>
            $(document).ready(function(){
                $("#btn").click(function(){
                    // alert("lala");
                    $.ajax({
                        cache:false,
                        url:"user/testAjax.action",
                        contentType:"application/json;charset=utf-8",
                        data:'{"username":"lj","age":20}',
                        dataType:"json",
                        success:function(data){	//接收服务器端的响应数据
                            //data:服务器端响应的数据,json格式的
                            alert(data.username);
                            alert(data.age);
                        },
                        type:"post"
                    });
                });
            });
        </script>
    

    Controler层的接收方法:

        @ResponseBody   //将返回值转换为json格式
        @RequestMapping("/testAjax.action")
        public User testJson(@RequestBody User user){	//接收请求体
            System.out.println(user);
            //重新赋值
            user.setAge(21);
            user.setUsername("xlj");
            return user;
        }
    

    七.springmvc文件上传

    1.springmvc文件上传
        <h3>springmvc文件上传</h3>
        <form action="user/fileupload.action" method="post" enctype="multipart/form-data">
            选择文件:<input type="file" name="upload" />
            <input type="submit" value="上传"/>
        </form>
    
        @RequestMapping("/fileupload.action")
        public String testFileUpLoad(HttpServletRequest request, MultipartFile upload) throws IOException {
            System.out.println("springmvc文件上传");
            //确定上传的路径
            String path = request.getSession().getServletContext().getRealPath("/uploads/");
            //判断该路径是否存在
            File file = new File(path);
            if(!file.exists()){
                //创建文件夹
                file.mkdirs();
            }
            //获取上传文件的名称
            String filename = upload.getOriginalFilename();
            //设置名称为唯一值
            String uuid = UUID.randomUUID().toString().replace("-","");
            filename = uuid +"_"+ filename;
            //文件上传
            upload.transferTo(new File(path,filename));
            return "success";
        }
    
    2.springmvc跨服务器文件上传
        @RequestMapping("/fileupload1.action")
        public String testFileUpLoad1(MultipartFile upload) throws IOException {
            System.out.println("跨服务器文件上传");
            //定义上传的服务器路径
            String path = "http://localhost:9090/uploads/";
            //获取上传文件的名称
            String filename = upload.getOriginalFilename();
            //设置名称为唯一值
            String uuid = UUID.randomUUID().toString().replace("-","");
            filename = uuid +"_"+ filename;
            //创建客户端对象
            Client client = Client.create();
            //与图片服务器进行连接
            WebResource webResource = client.resource(path+filename);
            //上传文件
            webResource.put(upload.getBytes());
            return "success";
        }
    

    八.异常处理

    定义异常类:

    public class SysException extends Exception {
        //提示信息
        private String message;
        public SysException(String message) {
            this.message = message;
        }
        @Override
        public String getMessage() {
            return message;
        }
        public void setMessage(String message) {
            this.message = message;
        }
    }
    

    定义异常处理类:

    //异常处理器类
    public class SysExceptionResolver implements HandlerExceptionResolver {
        /**
         * 处理异常
         * @param request
         * @param response
         * @param handler
         * @param ex:抛出的异常对象
         * @return
         */
        @Override
        public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
            //获取到异常对象
            SysException e = null;
            if(ex instanceof SysException){
                e = (SysException)ex;
            }else{
                e = new SysException("系统错误");
            }
            //创建ModelAndView对象
            ModelAndView mv = new ModelAndView();
            mv.addObject("errorMsg",e.getMessage());
            mv.setViewName("error");
            return mv;
        }
    }
    

    controller层:

        @RequestMapping("/testException.action")
        public String testException() throws SysException {
            System.out.println("exception执行了...");
            try{
                int a = 1/0;
            }catch (Exception e){
                e.printStackTrace();
                //向上抛出异常
                throw new SysException("捕获到异常");
            }
            return "success";
        }
    

    springmvc.xml配置

     <!-- 配置异常处理器 -->
        <bean id="sysExceptionResolver" class="cn.fzkj.exception.SysExceptionResolver" />
    

    捕获到的异常都是交由异常处理类(SysExceptionResolver)处理的


    九.拦截器

    SpringMVC的处理器拦截器类似于Servlet中的过滤器(Filter),用于对处理器进行预处理和后处理。

    过滤器和拦截器的区别:

    过滤器:是servlet规范中的一部分,任何java web工程都能使用。在url-pattern中配置了/*之后,对所有的访问资源都会拦截。

    拦截器:是SpringMvc自己的,只有使用SpringMvc框架的工程才能使用。且只会拦截访问的控制器中的方法。

    要自定义拦截器,必须要实现HandlerInterceptor接口。

    1.编写拦截器类

    2.配置拦截器

    拦截器类:

    //自定义的拦截器
    public class DiyInterceptor implements HandlerInterceptor {
        /**
         * 预处理
         * @param request
         * @param response
         * @param handler
         * @return true:放行
         * @throws Exception
         */
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("预处理执行了...");
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        }
    }
    

    配置:

        <!-- 配置拦截器 -->
        <mvc:interceptors>
            <mvc:interceptor>
                <!-- 配置拦截的方法-->
                <mvc:mapping path="/user/*"/>
                <!--配置不拦截的方法
                <mvc:exclude-mapping path=""/>
                -->
                <!-- 注册拦截器-->
                <bean class="cn.fzkj.interceptor.DiyInterceptor"/>
            </mvc:interceptor>
        </mvc:interceptors>
    

    持续更新~~~

  • 相关阅读:
    洛谷P2146 [NOI2015]软件包管理器
    洛谷P3038 [USACO11DEC]牧草种植Grass Planting
    洛谷P2831 愤怒的小鸟
    洛谷P1084 疫情控制
    洛谷P3258 [JLOI]2014松鼠的新家
    洛谷P1084 运输计划
    洛谷P2051 [AHOI2009]中国象棋
    洛谷P1438 无聊的数列
    洛谷P1312 Mayan游戏
    luogu P1038 神经网络
  • 原文地址:https://www.cnblogs.com/mrjkl/p/13051572.html
Copyright © 2011-2022 走看看