SpringMVC

如果你不相信努力和时光,那么成果就会是第一个选择辜负你的。不要去否定你自己的过去,也不要用你的过去牵扯你现在的努力和对未来的展望。不是因为拥有希望你才去努力,而是去努力了,你才有可能看到希望的光芒。SpringMVC,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

SpringMVC

Spring集成web环境

集成步骤

  1. 导入相关的坐标,spring的和web的

      <dependencies>
          <!--        spring-->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>5.3.6</version>
        </dependency>
        <dependency>
          <!--            mysql-->
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>5.1.32</version>
        </dependency>
        <!--        数据源一:c3p0-->
        <dependency>
          <groupId>c3p0</groupId>
          <artifactId>c3p0</artifactId>
          <version>0.9.1.2</version>
        </dependency>
        <!--        数据源二:druid-->
        <dependency>
          <groupId>cn.6tail</groupId>
          <artifactId>nlf-mini-plugin-druid</artifactId>
          <version>1.0.0</version>
        </dependency>
          <!--       junit-->
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.12</version>
          <scope>test</scope>
        </dependency>
        <!--        spring集成junit坐标:-->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-test</artifactId>
          <version>5.3.6</version>
        </dependency>
        <dependency>
          <groupId>org.junit.jupiter</groupId>
          <artifactId>junit-jupiter</artifactId>
          <version>RELEASE</version>
          <scope>compile</scope>
        </dependency>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>RELEASE</version>
          <scope>compile</scope>
        </dependency>
       <!--  servlet-->
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>4.0.1</version>
        </dependency>
       <!--  jsp-->
        <dependency>
          <groupId>javax.servlet.jsp</groupId>
          <artifactId>javax.servlet.jsp-api</artifactId>
          <version>2.3.3</version>
        </dependency>
      </dependencies>
    
  2. spring相关配置

  3. 添加一个web包,用来写javaweb

  4. 在web.xml配置相关类

  5. 配置tomcat,部署项目运行

ApplicationContext应用上下文的获取方式

之前每次我们都是通过new的方式创建的应用上下文,这样的弊端是在大项目中配置文件会加载多次,应用上下文被创建多次,繁琐且不节省资源

所以我们运用监听器来只创建一次,所有的用这一个容器,所以:

SpringMVC

创建一个实现ServletContext监听器的类:

public class ContextLoader implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        //将这个应用上下文对象存储在servletContext域中
        ServletContext servletContext = sce.getServletContext();
        servletContext.setAttribute("app",app);
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
    }
}

web层中:

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = req.getServletContext();
        ApplicationContext app = (ApplicationContext) servletContext.getAttribute("app");
        UserService userService= app.getBean(UserService.class);
        userService.save();
    }

web.xml:

<!--配置监听器-->
<listener>
  <listener-class>com.myspring.listener.ContextLoader</listener-class>
</listener>
<!--配置全局参数-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>

Spring提供的获得应用上下文的工具

没错,上面又白写了。。。

上面的不用手动实现。Spring提供了一个监听器ContextLoaderListener就是对该功能的封装

我们只需要做两件事:

  1. 在web.xml中配置ContextLoaderListener监听器(需要先导入spring-web坐标)

    pom.xml:

    <!-- spring-web-->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-web</artifactId>
          <version>5.3.6</version>
        </dependency>
    

    web.xml:

    <!--配置监听器-->
    <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
  2. 通过WebApplicationCintextUtils(一个客户端工具)获得应用上下文对象ApplicationContext

    web层中:

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
        ServletContext servletContext = req.getServletContext();
    //关键
        WebApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);
        UserService userService= app.getBean(UserService.class);
        userService.save();
    }
    

SpringMVC简介

  • SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,属于SpringFrameWork的后续产品,已经融合在 Spring Web Flow 中。 SpringMVC已经成为目前最主流的MVC框架之一。

  • SpringMVC的作用:作为前端控制器,控制请求的共有行为,在传统的JavaEE技术中,只使用Servlet作为控制器,当每个功能都需要一个servlet程序相似功能也无法分开封装,另外,传统的开发模式也存在其它使用不便利的做法。

    SpringMVC解决了V-C交互的问题,即V(View:视图)和C(Controller:控制器)之间的交互问题,具体表现在:用户可以通过视图将请求数据提交给服务器端的控制器,而控制器可以接收到相关数据后进行处理,最终,给予客户端某个视图,使得客户端得到响应结果。当然springMVC作为控制器还是需要servlet

    SpringMVC

SpringMVC开发步骤

  1. 导入SpringMVC

    <!--    spring-mvc-->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>5.3.6</version>
        </dependency>
    
  2. 配置servlet在web.xml

      <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-mvc.xml</param-value>
        </init-param>
    <!--    服务器加载时就启动本servlet-->
    <!--    当值为0或者大于0时,表示容器在应用启动时就加载这个servlet;-->
    <!--    当是一个负数时或者没有指定时,则指示容器在该servlet被选择时才加载。-->
    <!--    正数的值越小,启动该servlet的优先级越高。-->
        <load-on-startup></load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
    <!--    所有请求都会经过servlet-->
        <url-pattern>/</url-pattern>
      </servlet-mapping>
    
  3. 编写pojo(controller)

  4. 将controller使用注解(@Controller)配置到Spring容器中

    //表明是一个控制类bean实例
    @Controller
    public class UserController {
        //地址映射,当跳转/quick,访问此方法
        @RequestMapping("/quick")
        public  String save(){
            System.out.println("Controller save running");
    //        要跳转的视图
            return "success.jsp";
        }
    }
    
  5. 配置组件扫描(配置到Spring-mvc.xml:springmvc的配置文件,需要自己在resources创建)

    <!--    组件扫描:扫描controller-->
        <context:component-scan base-package="com.myspring.controller"/>
    
  6. 发送请求测试

    SpringMVC

流程:

SpringMVC

SpringMVC的组件解析

SpringMVC内部执行流程

SpringMVC

SpringMVC

SpringMVC注解解析

@RequestMapping(“”):地址映射

常用参数:value:就是路径

​ method:可以指定请求方式。值为枚举方式在RequestMethod

​ params:指定请求参数条件,例如:

SpringMVC

@Controller
@RequestMapping("/user")
public class UserController {
    //当地址为localhost:8080/user/quick时访问该方法
    @RequestMapping("/quick")
    public  String save(){
        System.out.println("Controller save running");
//        要跳转的视图:localhost:8080/user/success.jsp,当前的前一级目录下的该资源(/success.jsp.就代表当前web应用下,即webapp目录下)
        return "success.jsp";
    }
}

SpringMVC配置解析

在上面的代码中,最后我们renturn了jsp页面

return "success.jsp";
//实际上本句为
return "forword:success.jsp";
//forword在本处意思为转发(不改变url地址访问资源),默认为forword
return "redirect:/success.jsp"
//redirect:代表重定向

我们还可以在springmvc中配置视图解析器,来避免写前缀后缀

<!--    配置视图解析器-->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--        前缀-->
        <property name="prefix" value="/jsp/"></property>
<!--        后缀-->
        <property name="suffix" value=".jsp"></property>
    </bean>

这样一来我们可以这样写:
return "/success"
代表:/jsp/success.jsp

总结:

SpringMVC

SpringMVC的数据响应

SpringMVC的数据响应方式:

  1. 页面跳转
    • 直接返回字符串
    • 通过ModelAndView对象返回
  2. 回写数据
    • 直接返回字符串
    • 返回对象或集合

页面跳转

  1. 直接返回字符串:此种方式会将返回的字符串与视图解析器的前后缀拼接后跳转:不多说,上面例子就是用的这种

  2. 通过ModelAndView对象返回

        @RequestMapping("/quick2")
        public ModelAndView save2(){
            ModelAndView modelAndView = new ModelAndView();
    //        设置模型数据:可以在jsp中通过el表达式获得
          modelAndView.addObject("username","lihua");
    //        设置视图名称
            modelAndView.setViewName("index.jsp");
            return modelAndView;
        }
    
    
    //这种也可以,和上面一样只不过是springmvc为你注入了一个bean实例
        @RequestMapping("/quick2")
        public ModelAndView save2(ModelAndView modelAndView){
    //        设置模型数据
            modelAndView.addObject("username","lihua");
    //        设置视图名称
            modelAndView.setViewName("index");
            return modelAndView;
        }
    

​ 返回字符串的形式也可以传递参数:

    @RequestMapping("/quick")
    public  String save(Model model){
        model.addAttribute("username","lihua");
//        要跳转的视图
        return "success";
    }

//另外代替Model,还可以传HttpServletRequest等作为参数

​ 在index.jsp中

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
这个isELIgnored="false"表示el表达式可用
<html>
<body>
<h2>Hello World!${username}</h2>
</body>
</html>

回写数据

  1. 直接返回字符串

    在web阶段我们需要回写字符串直接response.getWriter().print(“hello world”),在Controller直接通过参数注入response对象,但是还有更加简单的方法:返回字符串

    @RequestMapping("/quick")
    //告知springmvc返回的用于回写数据的字符串,不要进行页面跳转
    @ResponseBody
    public  String save(HttpServletResponse response){
        return "helloworld";
    }
    
  2. 返回对象或集合

    当我们需要传递一个对象或者集合时,可以先转成json格式字符串再return

        @RequestMapping("/quick")
    //    还是要写这个注解,因为还是返回的字符串数据
        @ResponseBody
        public  String save(HttpServletResponse response) throws IOException {
            UserServiceImpl userService = new UserServiceImpl();
            userService.setAge(10);
            userService.setName("lihua");
    //        使用json转换工具将对象转换为json格式字符串再返回
            ObjectMapper objectMapper = new ObjectMapper();
            String string = objectMapper.writeValueAsString(userService);
            return string;
    

    需要导入的json转换工具坐标:

    <!--    json工具核心-->
        <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-core</artifactId>
          <version>2.11.4</version>
        </dependency>
    <!--    json数据绑定-->
        <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
          <version>2.11.4</version>
        </dependency>
    <!--    json和注解相关-->
        <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-annotations</artifactId>
          <version>2.11.4</version>
        </dependency>
    

​ springmvc不需要我们自己来转json字符串,有更加简便的方式:

​ 返回对象和集合。

​ 首先需要我们在spring配置文件中进行一些配置(配置处理器映射器):

<!--    配置处理器映射器-->
    <bean  class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                </bean>
            </list>
        </property>
    </bean>

​ 控制类中:

    @RequestMapping("/quick")
//    还是要写这个注解,因为还是返回的字符串数据
    @ResponseBody
    public UserServiceImpl save(HttpServletResponse response) throws IOException {
        UserServiceImpl userService = new UserServiceImpl();
        userService.setAge(10);
        userService.setName("lihua");
        return userService;
    }

配置太麻烦了,可以通过mvc的注解驱动代替上述配置,没错,又又又有更加简便的操作:

SpringMVC

在springmvc的配置文件中:

<!--        mvc注解驱动-->
        <mvc:annotation-driven/>
        
注意:注解驱动对应的命名空间必须是
xmlns:mvc="http://www.springframework.org/schema/mvc"
其他两个不行

SpringMVC获取请求数据

获取请求参数

SpringMVC

  1. 获取基本类型参数:直接通过参数获得:

    @RequestMapping("/quick")
    @ResponseBody
    public void save(String username,int age) throws IOException {
        System.out.println(username);
        System.out.println(age);
    }
    

    url:

    SpringMVC

    结果:

    SpringMVC

  2. 获得pojo类型参数:pojo参数的属性名和请求参数的name一致,参数值会自动映射匹配

    @Controller
    public class UserController {
        private int age;
        private String name;
    //    还需要getter和setter
    
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @RequestMapping("/quick")
        @ResponseBody
        public void save(UserController userController) throws IOException {
            System.out.println(userController.getAge());
            System.out.println(userController.getName());
        }
    
    }
    

    输入与结果:

    SpringMVC

SpringMVC

  1. 获得数组类型参数:和基本数据类型完全一致,函数参数和请求的参数一致就可以

SpringMVC

  1. 获得集合类型参数:需要被包装到一个pojo类中才可以

    public class VO {
        public List<String> getStringList() {
            return stringList;
        }
    
        public void setStringList(List<String> stringList) {
            this.stringList = stringList;
        }
    
        private List<String> stringList;
    }
    
@RequestMapping("/quick")
@ResponseBody
public void save(VO vo) throws IOException {
    System.out.println(vo.getStringList());
}

当请求为Ajax可以通过指定contenttype为json格式,通过注解直接获取集合数据:

ajax:

SpringMVC

@RequestMapping("/quick")
@ResponseBody
public void save(@RequestBody List<String> userList) throws IOException {
    System.out.println(userList);
}

开放静态资源;

无法访问的js文件等静态资源是配置
<!--    开放资源的访问权限:请求为mapping时开放location的静态资源-->
    <mvc:resources mapping="js/**" location="/js/"></mvc:resources>

这样也可以:在springmvc找不到资源是交给tomcat处理

<mvc:default-servlet-handler/>

解决低版本tomcat请求数据为中文乱码问题

如果tomcat版本较低,当配置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>

参数绑定注解@requestParam

当请求的参数名称和controller方法参数不一致时,就需要通过@requestParam注解显示

@RequestMapping("/quick")
@ResponseBody
//当我在url中输入的是name
public void save(@RequestParam("name") String username) throws IOException {
    System.out.println(username);
}

@requestParam注解的参数:

SpringMVC

获得Restful风格的参数

Restful是一种软件架构风格、设计风格,而不是标准,只是提供一组设计原则和约束条件。主要用于客户端和服务器交互类的软件,基于这个风格设计的软件可以更加简洁,更有层次等

HTTP协议中四个表示操作方式的动词:

SpringMVC

具体实例:

SpringMVC

自定义类型转换器

SpringMVC实际上已经具备了一些常用的类型转换器,例如客户端提交的字符串被转换成int型进行参数设置

但是可能并不完全满足我们的需求,所以我可以自定义类型转换器:
开发步骤:

  1. 定义转换器实现Converter接口

    public class DataConverter implements Converter<String,Date> {
        public Date convert(String dateStr) {
            //将日期字符串转换为日期对象
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            Date date = null;
            try {
                date = format.parse(dateStr);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return date;
        }
    }
    
  2. 在配置文件中声明转换器

    <!--    声明这个转换器-->
        <bean id="ConversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
            <property name="converters">
                <list>
                    <bean class="com.myspring.converter.DataConverter"></bean>
                </list>
            </property>
        </bean>
    
  3. 中引用转换器

    <!--    配置处理器映射器-->
        <mvc:annotation-driven conversion-service="ConversionService"/>
    

    结果:

    SpringMVC

    SpringMVC

获得Servlet的相关API

前面说过,直接在相关方法参数位置注入,就不在赘述

SpringMVC

获取请求头

  1. 使用@RequestHeader

    SpringMVC

        @RequestMapping("/quick")
        @ResponseBody
    //    将请求头的user-agent一行赋值给参数
        public void save(@RequestHeader(value = "User-Agent") String userAgent) throws IOException {
            System.out.println(userAgent);
        }
    
  2. @CookieValue获得Cookie的值:

    SpringMVC

    @RequestMapping("/quick")
    @ResponseBody
//    通过cookie的id获得cookie的值
    public void save(@CookieValue(value = "JSESSIONID") String cookie) throws IOException {
        System.out.println(cookie);
    }

文件上传

文件上传客户端要求:

SpringMVC

单文件上传步骤:

  1. 导入fileupload和io坐标

    <!--    fileupload-->
        <dependency>
          <groupId>commons-fileupload</groupId>
          <artifactId>commons-fileupload</artifactId>
          <version>1.3.1</version>
        </dependency>
    <!--    commons-io-->
        <dependency>
          <groupId>commons-io</groupId>
          <artifactId>commons-io</artifactId>
          <version>2.5</version>
        </dependency>
    
  2. 配置文件上传解析器

        <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!--        上传文件总大小最大-->
            <property name="maxUploadSize" value="5242800"/>
    <!--        上传单个文件大小最大-->
            <property name="maxUploadSizePerFile" value="5242800"/>
    <!--            生成文件编码类型-->
            <property name="defaultEncoding" value="UTF-8"/>
        </bean>
    
  3. 编写文件上传代码

        @RequestMapping("/quick")
        @ResponseBody
        //参数名必须与上传文件表单的各项name相同
        public void save(String username, MultipartFile uploadFile) throws IOException {
    //        获得文件名称
            String originalFilename = uploadFile.getOriginalFilename();
    //        保存文件到
            uploadFile.transferTo(new File("D:\\"+originalFilename));
    

我在创建multipartResolver 实例时报500错误,后来发现是tomcat中没有commons-fileupload和commons-io的jar包,需要向tomcat下的lib目录手动导入上面那个两个坐标的包,另外可能jsp不识别el表达式需要在开头设置 isELIgnored=”false”

多文件上传同理:

    @RequestMapping("/quick")
    @ResponseBody
    //参数名必须与上传文件表单的各项name相同
    public void save(String username, MultipartFile uploadFile1,MultipartFile uploadFile2) throws IOException {
//        获得文件名称
        String originalFilename = uploadFile1.getOriginalFilename();

        String originalFilename2 = uploadFile2.getOriginalFilename();
//        保存文件到
        uploadFile2.transferTo(new File("D:\\"+originalFilename));
        uploadFile1.transferTo(new File("D:\\"+originalFilename));
    }

当然也可以把参数换成一个数组

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/195246.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!