• SpringMVC


    SpringMVC是围绕DispatcherServlet设计的

    SpringMVC的执行原理

    •  DispatcherServlet表示前置控制器。是整个SpringMVC的控制中心,用户发送请求,DispatcherServlet接收并拦截请求
    • HandlerMapping为处理器映射,DispatcherServlet调用HandlerMa批评,HandlerMapping根据请求的url查找handler
    • HandlerExecution表示具体的handler,主要作用是根据根据url查找控制器。
    • HandlerExecution将解析后的信息传递给DispatcherServlet
    • HandlerAdapter表示处理器适配器,按照特定的规则去执行handler
    • handler让具体的controller执行
    • controller将具体的执行信息返回给HandlerAdapter(如:Model And View)
    • HandlerAdapter将其传递给DispatcherServlet
    • DispatcherServlet调用视图解析器View Resolver来对信息进行解析
    • DispatcherServlet根据视图解析器的解析结构调用具体的视图
    • 将视图呈现给用户

    HelloSpring

    配置版

    导入springMVC依赖

    配置web.xml文件,注册DispatcherServlet,所有的请求都经过DispatcherServlet拦截处理

    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <!--关联一个springMVC配置文件--> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!--/ 匹配所有的请求;(不包括.jsp)--> <!--/* 匹配所有的请求;(包括.jsp)--> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
    </servlet>

    在springmvc-servlet.xml的配置文件中添加处理器映射器和处理器适配器

    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

    添加视图解析器,解析ModelAndView对象

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
            <!--前缀-->
            <property name="prefix" value="/WEB-INF/jsp/"/>
            <!--后缀-->
            <property name="suffix" value=".jsp"/>
    </bean>

    编写业务实现Controller接口,返回一个ModelAndView对象,封装数据与视图

    public class HelloController implements Controller {
        @Override
        public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
            ModelAndView modelAndView=new ModelAndView();
            //封装对象,model
            modelAndView.addObject("msg","HelloSpringMVC");
            //封装要跳转的视图名称
            modelAndView.setViewName("hello");
            return modelAndView;
        }
    }

    将业务类交给spring管理,编写jsp文件并配置Tomcat服务器即可启动

    注解版

    修改springmvc-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:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
                               http://www.springframework.org/schema/beans/spring-beans.xsd
                               http://www.springframework.org/schema/context
                               http://www.springframework.org/schema/context/spring-context.xsd
                               http://www.springframework.org/schema/mvc
                               http://www.springframework.org/schema/mvc/spring-mvc.xsd">
        <context:component-scan base-package="com.deng.controller" />
    
        <context:annotation-config/>
        <mvc:default-servlet-handler/>
        <mvc:annotation-driven/>
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver
    " id="internalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/jsp/"></property>
            <property name="suffix" value=".jsp"/>
        </bean>
    </beans>

    编写Controller

    @Controller
    @RequestMapping("/hello")
    public class HelloController {
        @RequestMapping("/hello")
        public String sayHello(Model model){
            model.addAttribute("msg","hello,SpringMVC");
            return "hello";
        }
    }

    Controller及RestFul

    Controller

    由接口定义和注解定义两种方法实现,负责解析用户的请求并将其转换为一个模型

    实现Controller接口

    Controller接口在org.springframework.web.servlet.mvc包下,接口中只有一个方法

    //实现该接口的类获得控制器功能
    public interface Controller {
        //处理请求且返回一个模型与视图对象
        ModelAndView handleRequest(HttpServletRequest var1,HttpServletResponse var2) throws Exception;
    }

    实现该方法即可获得控制器功能

    ModelAndView mv = new ModelAndView();
    //绑定一个数据model
    mv.addObject("msg","Test1Controller");
    //绑定一个视图
    mv.setViewName("test");

    使用注解@Controller

    @Controller用于声明Spring类的实例是一个控制器

    Spring可以通过包扫描机制来找到应用程序中所有基于注解的控制器类,只需在配置文件中声明:

     <context:component-scan base-package="com.deng.controller"/>

    @RequestMapping

    @RequestMapping用于映射url到控制器类或一个特定的处理程序方法。可用于类或方法上。用于类上表示类中所有响应请求的方法都是以该地址作为父路径

    RestFul风格

    RestFul就是一个资源定位和资源操作的风格。

    传统的方式操作资源:通过不同的参数来实现不同的效果

    http://127.0.0.1/item/queryItem.action?id=1 查询,GET 
    http://127.0.0.1/item/saveItem.action 新增,POST 
    http://127.0.0.1/item/updateItem.action 更新,POST 
    http://127.0.0.1/item/deleteItem.action?id=1 删除,GET或POST

    RestFul操作资源:通过不同的请求方式实现不同的效果,请求地址引用,但是根据不同的请求方式实现的功能不一样

    http://127.0.0.1/item/1 查询,GET 
    http://127.0.0.1/item 新增,POST 
    http://127.0.0.1/item 更新,PUT 
    http://127.0.0.1/item/1 删除,DELETE

    使用@RequestMapping的method属性可以指定请求的类型

    //映射访问路径,必须是POST请求
    @RequestMapping(value = "/hello",method = {RequestMethod.POST})
    public String index2(Model model){
      model.addAttribute("msg", "hello!");
      return "test";
    }

    所有的地址栏请求默认是Get请求

    注解的变体有

    @GetMapping
    @PostMapping
    @PutMapping
    @DeleteMapping
    @PatchMapping

    结果跳转的方式

    ModelAndView

    设置ModelAndView对象,根据view的名称和视图解析器跳转到指定页面

    页面:{视图解析器前缀}+view名称+{视图解析器后缀}

    <!-- 视图解析器 -->
    <bean
    class="org.springframework.web.servlet.view.InternalResourceViewResolver"
    id="internalResourceViewResolver">
    <!-- 前缀 -->
    <property name="prefix" value="/WEB-INF/jsp/" />
    <!-- 后缀 -->
    <property name="suffix" value=".jsp" />
    </bean>
    public class ControllerTest1 implements Controller {
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest,
    HttpServletResponse httpServletResponse) throws Exception {
        //返回一个模型视图对象
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","ControllerTest1");
        mv.setViewName("test");
        return mv;
       }
    }

    ServletAPI

    通过设置ServletAPI进行输出和跳转,就不需要视图解析器

    @Controller
    @RequestMapping("/hello")
    public class HelloController {
        @RequestMapping("/test1")
        public void test1(HttpServletRequest request,HttpServletResponse response) throws IOException {
            response.getWriter().print("Hello,World!");
        }
        //重定向
        @RequestMapping("/test2")
        public void test2(HttpServletRequest request,HttpServletResponse response) throws IOException {
            response.sendRedirect("/hello/test1");
        }
        //请求转发
        @RequestMapping("/test3")
        public void test3(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
            request.getRequestDispatcher("/hello/test1").forward(request,response);
        }
    }

    SpringMVC

    可以通过SpringMVC来实现转发和重定向,也无需视图解析器(配置视图解析器就是指定路径)

    @Controller
    @RequestMapping("/hello")
    public class HelloController {
        @RequestMapping("/test1")
        public  String test1(){
            return "/index.jsp";
        }
        //请求转发
        @RequestMapping("/test2")
        public String test2(){
            return "forward:/index.jsp";
        }
        //重定向
        @RequestMapping("/test3")
        public  String test3(){
            return "redirect:/index.jsp";
        }
    }

    数据处理

    处理提交数据

    提交域名参数和处理方法的参数名一致

        @RequestMapping("/test1")
        public  String test1(String name){
            System.out.println(name);
            return "/index.jsp";
        }

    访问:localhost:8080/hello/test1?name=dengwenxiong,后台获取到参数

    提交域名参数和处理方法不一致

        @RequestMapping("/test1")
        public  String test1(@RequestParam("username") String name){
            System.out.println(name);
            return "/index.jsp";
        }

    访问:localhost:8080/hello/test1?username=dengwenxiong

    提交一个对象

     @RequestMapping("/test1")
        public  String test1(User user){
            System.out.println(user);
            return "/index.jsp";
        }

    访问:localhost:8080/hello/test1?id=1&name=dengwenxiong&age=11

    提交对象的话,前端传递的参数名和对象名必须是一致的,否则参数为null

    数据显示到前端

    通过ModelAndView显示

    public class ControllerTest1 implements Controller {
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest,
    HttpServletResponse httpServletResponse) throws Exception {
         //返回一个模型视图对象
         ModelAndView mv = new ModelAndView();
         mv.addObject("msg","ControllerTest1");
         mv.setViewName("test");
         return mv;
       }
    }

    通过ModelMap

    @RequestMapping("/hello")
    public String hello(@RequestParam("username") String name, ModelMap model){
        //封装要显示到视图中的数据
        //相当于req.setAttribute("name",name);
        model.addAttribute("name",name);
        System.out.println(name);
        return "hello";
    } 

    通过Model

    @RequestMapping("/ct2/hello")
    public String hello(@RequestParam("username") String name, Model model){
        //封装要显示到视图中的数据
        //相当于req.setAttribute("name",name);
        model.addAttribute("msg",name);
        System.out.println(name);
        return "test";
    }

    对比

    • Model只有少量方法适用于存储数据
    • Model Map继承了LinkedMap,除了实现自身的一些方法外,还继承了LinkedMap的方法和特性
    • ModelAndView可以在存储数据的同时设置返回的逻辑视图。

    乱码问题

    在web.xml配置过滤器即可,SpringMVC提供了一个默认的过滤器

     <filter>
         <filter-name>encoding</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>encoding</filter-name>
          <url-pattern>/*</url-pattern>
     </filter-mapping>

     

    JSON

    JSON:js对象标记

    • 对象表现为键值对
    • 花括号保存对象
    • 方括号保存数组

    Json对象转换为JS对象

    var obj = JSON.parse('{"a": "Hello", "b": "World"}');
    //结果是 {a: 'Hello', b: 'World'}

    js对象转换为Json对象

    var json = JSON.stringify({a: 'Hello', b: 'World'});
    //结果是 '{"a": "Hello", "b": "World"}'

    Controller返回JSON字符串

    Jackson是目前较好的json解析工具

    输出json字符串

    导入jar包

    <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
          <version>2.11.4</version>
    </dependency>
    @RequestMapping("/user")
    public class UserController {
        @RequestMapping("/json")
        @ResponseBody
        public String json1() throws JsonProcessingException {
            //创建jackson的对象映射器来解析数据
            ObjectMapper objectMapper=new ObjectMapper();
            User user=new User(1,"dwx",11);
            //将对象解析成json格式
            String string=objectMapper.writeValueAsString(user);
            //@ResponseBody注解,直接返回字符串
            return string;
        }
    }

    如遇到乱码问题可以通过@RequestMapping的produces属性来设置返回类型和编码格式:

    //produces:指定响应体返回类型和编码
    @RequestMapping(value = "/json",produces ="application/json;charset=utf-8")

    @Controller+@ResponseBody=@RestController

    输出时间对象

    jackson默认会把时间日期转换为时间戳的形式输出

    public String json1() throws JsonProcessingException {
            ObjectMapper mapper = new ObjectMapper();
    //不使用时间戳的方式
            mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
    //自定义日期格式对象
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    //指定日期格式
            mapper.setDateFormat(sdf);
            Date date = new Date();
            String str = mapper.writeValueAsString(date);
            return str;
    
        }

    FastJson

    阿里开发的json转换的jar包

    导入

    <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>fastjson</artifactId>
          <version>1.2.28</version>
    </dependency>

    有三个主要的类:

    • JSONObject:代表json对象,实现了map接口
    • JSONArray:代表json数组,实现了List
    • JSON:代表JSONArray和JSONObject的转化

     AJAX

    Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)是一种在无需加载整个网页的情况下,就能更新部分网页的技术。ajax依赖于XMLHttpRequest对象(XHR)

    XMLHttpRequest对象:

    • 用于后台与服务器交互数据是一种api
    • 可以在不重新加载页面的情况下更新网页
    • 可以在页面已加载后重服务器请求和接收数据
    • 可以向服务器发送数据

    ajax请求的五个步骤:

    • 创建XMLHttpRequest对象
    • 连接服务器
    • 发送请求
    • 服务器响应
    • 接收响应数据

    拦截器

    SpringMVC的拦截器类似于Servlet中的过滤器,用于对处理器进行预处理和后处理,拦截器只会拦截控制器方法。

    自定义拦截器必须实现HandlerInterceptor方法

    public class MyInterceptor implements HandlerInterceptor {
        //预处理,返回true就继续执行,返回false不往下执行
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("处理前");
            return false;
        }
        //后处理
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("处理后");
        }
        //dispatcherServlet处理之后执行,完成一些清理工作
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("清理");
        }
    }

    配置文件配置拦截器

    <mvc:interceptors>
            <mvc:interceptor>
                <mvc:mapping path="/*"/>
                <bean class="com.deng.controller.MyInterceptor"></bean>
            </mvc:interceptor>
    </mvc:interceptors>

    可以使用拦截器实现登录拦截

    文件上传,下载

    SpringMVC可以很好的支持文件上传,但是其上下文默认没装配MultipartResolver,因此默认情况下不能处理文件上传工作。需要在上下文配置MultipartResolver才能使用文件上传功能

    对于前端,要上传文件需要将表单的method设置为post,将enctype设置为multipart/form-data,才能将文件以二进制数据发送给服务器

    表单中的enctype属性值:

    • application/x-www=form-urlencoded:默认的方式,只6处理表单域中的value属性,并会把该属性处理成url编码方式
    • multipart/form-data:这种编码方式会以二进制流的形式处理表单数据,会把文件域指定的文件的内容也封装到请求参数中,不会对字符编码
    • text/plain:除了把空格转换成+外,其他字符都不做处理,适合通过表单发送邮件
    <form action="" enctype="multipart/form-data" method="post">
        <input type="file" name="file"/>
        <input type="submit">
    </form>

    CommonsFileUpload实现了一个MulitipartResolver的实现类CommonsMultipartResolver。

    CommonsMultipartFile常用方法:

    • String getOriginalFilename():获取上传文件名
    • InputStream getInputStream():获取上传文件输入流
    • void transferTo(File file):将上传的文件保存到一个目录文件中

    导入文件上传jar包commons-fileupload

    <!--文件上传-->
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.3.3</version>
    </dependency>
    <!--servlet-api导入高版本的-->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
    </dependency>

    配置multipartResolver的bean

    <!--文件上传配置-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <property name="defaultEncoding" value="utf-8"></property>
            <property name="maxUploadSize" value="10485760"></property>
            <property name="maxInMemorySize" value="40960"></property>
    </bean>

    前端

    <form action="/upload" enctype="multipart/form-data" method="post">
       <input type="file" name="file"/>
       <input type="submit" value="upload">
    </form>

    Controller类

    @Controller
    public class FileController {
        //将name=file得到的文件封装成CommonsMultipartFile对象,如果是批量上传将其改成数组即可
        @RequestMapping("/upload")
        public String fileUpload(@RequestParam("file")CommonsMultipartFile file, HttpServletRequest request) throws Exception{
            //获取上传文件原名
            String uploadFileName=file.getOriginalFilename();
            if("".equals(uploadFileName))
                return "redirect:/index.jsp";
            //上传路径保存
           String path= request.getServletContext().getRealPath("/upload");
           //如果路径不存在创建文件路径
            File realPath=new File(path);
            if(!realPath.exists()){
                realPath.mkdir();
            }
            //获取上传文件输入流
            InputStream in=file.getInputStream();
            //创建文件输出流
            OutputStream outputStream=new FileOutputStream(new File(realPath,uploadFileName));
            int len=0;
            byte[] buffer=new byte[1024];
            while((len=in.read())!=-1){
                outputStream.write(buffer,0,len);
                outputStream.flush();
            }
            outputStream.close();
            in.close();
            return "redirect:/index.jsp";
        }
    }

    也可以直接采用transferTo()来保存上传文件

    @Controller
    public class FileController {
        //将name=file得到的文件封装成CommonsMultipartFile对象,如果是批量上传将其改成数组即可
        @RequestMapping("/upload")
        public String fileUpload(@RequestParam("file")CommonsMultipartFile file, HttpServletRequest request) throws Exception{
            //获取上传文件原名
            String uploadFileName=file.getOriginalFilename();
            if("".equals(uploadFileName))
                return "redirect:/index.jsp";
            //上传路径保存
           String path= request.getServletContext().getRealPath("/upload");
           //如果路径不存在创建文件路径
            File realPath=new File(path);
            if(!realPath.exists()){
                realPath.mkdir();
            }
            //上传保存的路径
            File path1=new File(realPath+"/"+uploadFileName);
            System.out.println(path1.toString());
            file.transferTo(path1);
            return "redirect:/index.jsp";
        }
    }

    文件下载

    @RequestMapping("/download")
        public  String downloads(HttpServletRequest request, HttpServletResponse response) throws Exception{
            //下载图片地址
            String path=request.getServletContext().getRealPath("/upload");
            String fileName="2.PNG";
            //设置响应头
            response.reset();//设置页面不缓存
            response.setCharacterEncoding("utf-8");
            response.setContentType("multipart/form-data");
            //设置响应头
            response.setHeader("Content-Disposition",
                    "attachment;fileName="+ URLEncoder.encode(fileName, "UTF-8"));
            File file=new File(path,fileName);
            System.out.println(file.toString());
            //创建读取文件的输入流
            InputStream inputStream=new FileInputStream(file);
            //写出文件输出流
            OutputStream outputStream=response.getOutputStream();
            int len=0;
            byte[] buff=new byte[1024];
            while((len=inputStream.read(buff))!=-1){
                outputStream.write(buff,0,len);
                outputStream.flush();
            }
            outputStream.close();
            inputStream.close();
            return null;
    
        }
  • 相关阅读:
    【转载】关于C#中动态加载AppDomain的问题
    poj2239
    poj2231
    poj2229
    poj2234
    poj2236
    前 路
    只含一个单词的句子
    做人准则
    改变人生的32句励志名言
  • 原文地址:https://www.cnblogs.com/dwx-study/p/14719679.html
Copyright © 2020-2023  润新知