SpringMVC内容汇总

0. 简介

       本文用于记录本人的SpringMVC学习内容以及部分自己的理解,参考资料源自以下:
       狂神说Java——SpringMVC
       fastjson常用方法_authority39的博客-CSDN博客_fastjson常用方法
       可能有部分理解不到位的地方,不喜勿喷。

1. Spring MVC与常规开发

常规开发流程

  • 研究相关jsp文件和js文件(有可能有ajax请求)中是否发送了http请求,如果是,根据请求需要返回的数据做业务实现;
  • 先从Dao层的代码开始编写,实现相应功能的部分返回值要求,也可能是全部,如添加功能只需要一个方法就可以实现,而用户管理功能需要搜索和分页多个功能,此时Dao层需要根据需求编写多个方法;
  • 完成Dao层代码编写,接着开始完成Service层的代码,一般都是一些比较模板化的代码,但是在像动态搜索这种功能的实现中,可能需要判断传递过来的参数;
  • 完成Service层代码编写,可以写控制层代码,即Servlet,根据功能实现的需求进行设置相应的参数,并选择使用重定向或者请求转发的方式将相应的参数返回,如果是ajax请求则是json格式的数据,另外,在ajax中重定向和请求转发的代码是不会生效的;
  • 注册Servlet,运行查看代码效果,如果有bug就debug,没有就进行下一个模块的开发;

使用Spring MVC的开发:

  • 只需要注册一个DispatcherServlet,而不需要反复去注册Servlet;
  • 通过添加@Controller标签实现控制器的编写,同时可以在一个Controller中编写多个不同url请求,极大地简化了反复自定义Servlet类的过程;
  • 可以实现GET,POST等方法;

2. SpringMVC的特点:

  • RESTful风格,支持数据验证
  • 简洁灵活

3. SpringMVC的执行流程

  • 确定导入了SpringMVC的相关包

  • 配置web.xml,注册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>
        <!--启动级别:1-->
    	<load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <!--
    		/ :匹配所有的请求,不包括jsp
    		/*:匹配所有的请求,包括jsp
    	-->
    	<servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
  • 设置springmvc-servlet.xml配置文件:

    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
    <!--设置处理器映射器-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
    <!--设置处理器适配器-->
    <bean clss="org.springframework.web.servlet.view.InternalResourceViewResolver" 
          id="InternalResourceViewResolver">
        <!--跳转视图前缀-->
    	<property name="prefix" value="/WEB-INF/jsp/" />
        <!--跳转试图后缀-->
        <property name="suffix" value=".jsp" />
    </bean>
    <!--设置视图解析器-->
    
  • 编写相关控制器代码:

    public class HelloController implements Controller{
        
        //重写方法
        public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)throws Exception{
            ModelAndView modelAndView= new ModelAndView();
            
            //封装信息,放在ModelAndView中
            modelAndView.addObject("msg","HelloSpringMVC");
            //设置跳转视图
            modelAndView.setViewName("hello");
            //返回给视图解析器
            return modelAndView;
        }
    }
    
  • 将写好的控制器类配置到springmvc-servlet.xml中

    <bean id="/hello" class="xxx.xxx.xxx.HelloController" />
    
  • 工作流程:启动Tomcat后,因为设置了DispatcherServlet收到所有带 “/” 前缀的请求,所以请求发给了DispatcherServlet,DispatcherServlet再发给处理器映射器,经过处理后发回给DispatcherServlet,然后DispatcherServlet再发给处理器适配器,发现匹配上了springmvc-servlet.xml中的id为 “/hello” 的bean,于是执行其中重写的handleRequest()方法,返回一个ModelAndView,由DispatcherServlet转交给视图解析器,同时携带信息msg以及要跳转到的视图 “hello” ,由视图解析器加上前后缀,拿到资源/WEB-INF/jsp/hello.jsp,同时将携带的信息传递给jsp,渲染完成后返回给DispatcherServlet再返回给前端。(看狂神的图是这样的)

  • 可能存在的问题:缺少JAR包,需要在IDEA的项目中导入。(添加lib目录导入所有需求包)

DispatcherServlet运行流程

  • SpringMVC执行流程(查资料版):DispatcherServlet执行流程_wzs535131的博客-CSDN博客

    • 用户发送请求给前端控制器DispatcherServlet;
    • DispatcherServlet收到请求调用HandlerMapping处理器映射器;
    • 处理器映射器找到具体的处理器(一般通过注解),生成处理器对象及处理器拦截器(如果有的话)并一起返回给DispatcherServlet;
    • DispatcherServlet调用HandlerAdapter处理器适配器;
    • HandlerAdapter经过适配调用具体的处理器(即Controller);
    • Controller执行完成后返回ModelAndView;
    • HandlerAdapter将controller执行结果ModelAndView传给DispatcherServlet;
    • DispatcherServlet将ModelAndView传给视图解析器;
    • ViewReslover解析后返回具体View;
    • DispatcherServlet根据View进行渲染视图(数据填充);
    • DispatcherServlet响应用户。

4. SpringMVC注解实现:

  • 在web.xml中配置DispatcherServlet,这一点仍旧不变;

  • 配置DispatchherServlet的配置文件,改动如下:

    <beans xmlns="……………………………………"
           xmlns:xsi="……………………………………"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="……………………………………
                               http://www.springframework.org/schema/context
                               https://www.springframework.org/schema/context/spring-context.xsd
                               http://www.springframework.org/schema/mvc
                               https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    
        <!--自动扫描包,让指定包下的注解生效,由IOC容器统一管理-->
        <context:component-scan bean-package="xxx.xxx.xxx" />
        <!--让SpringMVC不处理静态资源   .css .html .js-->
        <mvc:default-servlet-handler />
        <!--支持mvc注解驱动-->
        <mvc:annotation-driven />
        
        ……………………………………
        <!--配置视图解析器-->
        
    </beans>
    
  • 编写Controller层

    @Controller
    //表示这是一个Controller
    //这里也可以给类添加注解@RequestMapping("/HelloController")
    //这样的话只有"localhost:8080/HelloController"的请求才能到达这个Controller
    public class HelloController{
        @RequestMapping("/hello")
        //url映射地址
        public String hello(Model model){
            model.addAttribute("msg","Hello,SpringMVCAnnotation!");
            return "hello";
            //返回给视图解析器的内容,即目标jsp文件名
        }
    }
    
  • 如果想要使用重定向或者转发,需要将视图解析器注销掉,在return的时候,默认是实现转发,也可以加上关键字 “forward” 或者 “redirect” 实现转发和重定向:

    return "redirect:WEB-INF/jsp/index.jsp";
    return "forward:WEB-INF/jsp/index.jsp";
    //但是这种情况下需要写上全名,因为没有了视图解析器
    
  • 实现前后端的参数传递:

    @RequestMapping("/add")
    public String add(@RequestParam("numFir")int a,@RequestParam("numSec")int b){
        ……………………………………
        return "add";
    }
    

    通过这种方式,前端在访问 “localhost:8080/add?numFir=1&numSec=2” 的情况下就会跳转到该方法下执行相关操作。在这里,注解 “@RequestParam(”……")" 起到的作用是绑定前端传过来的参数。如果是使用自定义类来接收参数,则需要保证自定义类中的属性字段名与参数名一致,否则会出现异常。

5. RestFul风格编程:

  • 针对于传统url访问下,泄露传递参数名的情况,RestFul风格编程可以有效保护信息:

    localhost:8080/index?method=add&num1=1&num2=2 (传统编程风格下的访问方式)

    localhost:8080/index/add/1/2 (Restful编程风格下的访问方式)

  • 可以使用POST,DELETE,PUT,GET,不同的方法对相同资源进行操作,获得不同的结果;

  • 实现前后端分离:返回给前端以JSON的形式的数据

    • 当类注解为@Controller时,在相应的方法上添加注解@ResponseBody,这样子return的结果就不会走视图解析器,而是直接返回给前端的String结果;

    • 当类注解为@RestController,该类中的所有方法的返回值都会直接给到前端,而不会走视图解析器;

    • 使用jackson返回Json格式数据:

      • 导入jackson相关的依赖:

        <dependency>
        	<gorupId>com.fasterxml.jackson.core</gorupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.8</version>
        </dependency>
        
      • 使用方法:

        ObjectMapper mapper = new ObjectMapper();
        Object object = new Object();
        //这里模拟的只是获取前端所需要参数的过程
        //假设object是目标对象
        String str = mapper.writeValueAsString(object);
        return str;
        //通过这种方式返回的String字符串其实会出现中文乱码的情况
        //可以在Spring中配置一个处理器解决这个问题
        //重复性的代码可以写成工具类实现复用
        //对于时间戳对象的处理
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.format(date);//这个方法的返回值类型是String
        //也可以采用设置ObjectMapper的format方法实现
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
        mapper.setDateFormat(sdf);
        
      • 解决Json中文乱码问题:

        <mvc:annotation-driven>
        	<mvc:message-converters register-defaults="true">
            	<bean class="org.springframework.http.converter.StringHttpMessageConverter">
                	<constructor-arg value="UTF-8" />
                </bean>
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                    <property name="objectMapper">
                    	<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                        	<property name="failOnEmptyBeans" value="false" />
                        </bean>
                    </property>
                </bean>
            </mvc:message-converters>
        </mvc:annotation-driven>
        
    • 使用alibaba的Fastjson包返回Json格式数据:

      • 导入fastjson的相关依赖

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.66</version>
        </dependency>
        
      • 常用方法:

        //直接解析为对象:
        T t = JSON.parseObject(jsonstr,T,class);
        List<T> list = JSON.parseArray(jsonstr,T.class);
        //解析为JSON对象:
        Object obj = JSON.parse(jsonstr);
        JSONObject objJSON = JSON.parseObject(jsonstr);
        JSONArray arrJSON = JSON.parseArray(jsonstr);
        
        //获取JSONArray对象中的数据:
        JSONObject objJSON = arrJSON.get(i);
        T t = arrJSON.getObject(i,T.class);
        
        //获取JSONObject对象中的数据:
        Integer integer = objJSON.getInteger(key);
        String string = objJSON.getString(key);
        JOSNObject tar = objJSON.getJSONObject(key);
        JSONArray arrJSON = objJSON.getJSONArray(key);
        
        //格式化对象为json字符串
        JSON.toJSONString(object);
        //上面的方法虽然看可以达成目标,但仍然存在部分问题,推荐使用以下方式:
        SerializerFeature quotefieldnames = SerializerFeature.QuoteFieldNames;               
        // 输出的结果不带双引号
        SerializerFeature writemapnullvalue = SerializerFeature.WriteMapNullValue;           
        // 打印出null值的字段
        SerializerFeature writenullstringasempty = SerializerFeature.WriteNullStringAsEmpty; 
        // null值字段显示为""
        SerializerFeature writenulllistasempty = SerializerFeature.WriteNullListAsEmpty;     
        // null值数组显示为[]
        JSON.toJSONString(obj, quotefieldnames, writemapnullvalue, writenullstringasempty, writenulllistasempty);
        //可以将这部分代码封装实现复用
        
  • 使用方式:

    • 需要在相关方法中的参数上添加注解"@PathVariable",并修改相应的@RequestMapping

      @Controller
      public class RestFulController{
          
          @RequestMapping(path="/add/{a}/{b}")
          public String add(@PathVariable int a,@PathVariable int b,Model model){
              ……………………………………
              return "add";
          }
      }
      
    • 实现多方法响应需要在RequestMapping中新增属性method,或者使用组合注解

      @RequestMapping(path="……",method=RequestMethod.GET)
      @GetMapping("path值")
      

6. 乱码问题解决:注册过滤器(可以使用Spring自带的)

<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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值