ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

SpringMVC-01-第一个SpringMVC程序,注解开发,Restful风格等

2021-07-11 23:01:08  阅读:187  来源: 互联网

标签:控制器 01 SpringMVC 视图 Controller User Restful public


SpringMVC官网文档链接:https://docs.spring.io/spring-framework/docs/current/reference/html/web.html

一:什么是MVC

  1. MVC是模型(Model),视图(View),控制器(Controller)的简写,是一种软件设计规范。主要作用是降低了试图与业务逻辑间的双向耦合。MVC是一种架构模式。
  • Model(模型):数据模型,提供要展示的数据(包含数据和行为)
  • View(视图):负责进行模型的展示,一般就是我们见到的用户界面,客户想看到的东西
  • Controller(控制器):接受用户请求,委托给模型进行处理,处理完毕后把返回的模型数据返回给试图,由视图负责展示,也就是说控制器做了个调度员的工作。

二:回顾Servlet

  1. 新建maven项目,导入依赖
<!--父工程所需要依赖-->
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>jsp-api</artifactId>
    <version>2.2.1-b03</version>
    <scope>provided</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
  1. Maven项目添加web框架支持,编写Servlet类,处理用户请求,简单的进行传参展示信息功能。
public class HelloServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1. 获取前端参数
        String method = req.getParameter("method");
        if (method.equals("add")){
            req.getSession().setAttribute("msg","执行了add方法");
        }
        if (method.equals("delete")){
            req.getSession().setAttribute("msg","执行了delete方法");
        }
        //2. 调用业务层

        //3. 试图转发或者重定向
        req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
  1. 在web.xml文件中注册Servlet
<!--注册Servlet-->
<servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>com.chelsea.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello</url-pattern>
</servlet-mapping>

<!--设置session默认时常-->
<session-config>
    <session-timeout>15</session-timeout>
</session-config>

<!--欢迎页面-->
<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>
  1. 启动tomcat运行即可,url为:http://localhost:8080/hello?method=add

三:SpringMVC

  1. Spring简介
  • SpringMVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架。简单易学,与Spring兼容性好,约定大于配置,功能强大(RESTful风格,数据验证,格式化本地化等功能)
  • Spring的web框架围绕DispatcherServlet设计,DispatcherServlet的作用是将请求分发到不同的处理器,且可以使用注解进行开发,十分简洁好学
  • 使用SpringMVC的公司和个人用户非常多,不得不学
  • SpringMVC大致原理:发起请求后被前置的控制器拦截,根据请求参数生成代理请求,找到此请求实际对应的控制器。控制器进而处理请求,创建数据模型,访问数据库,将模型响应给中心控制器,控制器使用模型与视图渲染视图结果,将结果返回给中心控制器,再将结果返回给请求者。
    SpringMVC原理
  1. SpringMVC的执行原理
    SpringMVC的执行原理
  • 框1:处理器,根据url解析控制器,并将解析后的数据传给FispatcherServlet
  • 框2:适配器,按照特定的规则去执行Handler,让具体的Handler去执行,并将视图逻辑或模型传递给DispatcherServlet
  • 框3:视图解析器(真实开发时,只有这个需要手动配置),解析传递过来的逻辑视图的名称(一般情况下为要展示的页面名称),根据视图解析器的试图结果,调用具体的试图

四:第一个MVC程序

  1. 导入依赖,添加web框架支持,配置web.xml,注册DispatcherServlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <!--注册DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--关联一个springmvc的配置文件:【servlet-name】:servlet.xml-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <!--启动级别 设置为1-->
        <!--服务器初始启动可能会有部分请求需要处理,所以此处设置为1,服务器启动时,此分发器就启动-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!--/匹配所有的请求(不包括.jsp)-->
    <!--/*为匹配所有的请求(包括.jsp)-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
</web-app>
  1. 配置SpringMVC配置文件,其中前两个,处理器和适配器不用显示配置,此处为了配合上图执行原理三部分,显示配置了出来,一般来说只需要配置视图解析器即可,视图解析器根据控制器返回的字符串进行拼接字符串,查找视图资源进行显示。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--配置以下三个东西,前两个根本不需要配置-->
    <!--配置一个处理器-->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    <!--配置一个适配器-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

    <!--配置一个视图解析器:解析DispatcherServlet给他的ModelAndView
    1. 获取了ModelAndView的数据
    2. 解析了ModelAndView的试图名字
    3. 拼接试图名字,找到对应的视图
    4. 将试图渲染到界面
    -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
	
	<!--未使用注解开发时,写一个控制器就得在这配置一下bean-->
    <bean id="/hello" class="com.chelsea.controller.HelloController"/>

</beans>
  1. 编写控制器,进行业务处理,此处使用接口开发,具有同样的效果,后期都使用注解开发,更为方便。
/*首先实现SpringMVC的Controller接口*/
public class HelloController implements Controller {

    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        /*modelAndView*/
        ModelAndView mv = new ModelAndView();
        //封装对象,放到ModelAndView种
        mv.addObject("msg","HelloSpringMVC!");
        //封装要跳转的试图,放到ModelAndView中
        //WEB-INF/jsp/hello.jsp
        mv.setViewName("hello");
        return mv;
    }
}
  1. 编写前端页面进行展示即可
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${msg}
</body>
</html>
  1. 可能出现的问题:查看是否缺少jar包等,记得在项目中添加lib依赖

五:注解开发

  1. 在web.xml中配置DispacherServlet,和上述一样,此处不展示。
  2. 添加springmvc-servlet.xml配置文件(此名字也可随便起,在web.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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        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 base-package="com.chelsea.controller"/>

    <!--配置Springmvc视图解析器不处理静态资源 .css .js .html .mp3 .mp4-->
    <mvc:default-servlet-handler/>

    <!--
        支持mvc注解驱动
        在spring一般采用@RequestMapping注解来完成映射关系
        要想使@RequestMapping注解生效,必须向上下文中注册DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter实例
        这两个实例分别在类级别和方法级别处理,而annotation-driver配置帮助我们自动完成上述两个实例的注入。
        就代替了之前自己配的这两个bean对象
    -->
    <mvc:annotation-driven/>

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

</beans>
  1. 创建Controller控制器进行逻辑控制,注解开发方法只需要返回对应视图的字符串即可,类和方法级别都可以添加RequestMapping进行url映射
/*配置此注解,则不会被视图解析器解析,用于返回json格式的字符串*/
/*@RestController*/
@Controller
public class HelloController {
    @RequestMapping("/hello")
    public String Hello(Model model){
        //封装数据
        model.addAttribute("msg","HelloServlet!");
        /*这个返回的字符串会被视图解析器处理*/
        return "hello";
    }
}
  1. 开发前端运行即可。

六:RestFule风格传参与乱码解决

  1. 前情回顾:由上面可以看出,Controller有两种开发风格,一种是集成SpringMVC饿Controller接口来实现控制器功能,一种是使用@Controller接口实现Controller功能,推荐使用注解开发而已。
  2. Rest风格
  • Restful是一种url的风格,不是标准也不是协议。使用后更加简洁更加安全而已
  • 传统的url(get为主):http://127.0.0.1/item/queryItem.action?id=1
  • Restful风格:http://127.0.0.1/item/1
  1. 开发实例:就是将参数显式配置在url中,尽量使形参和url中参数名顺序和名称保持一致,否则会报错。更安全一点做法是使用@PathVariable参数进行显示声明。
@Controller
public class RestFulController {

    //使用RestFul风格,目前主要是@PathVaruable注解
    //还可以指定这个注解,指定post方法 @PostMapping
    //还可以指定这个注解,指定Get方法 @GetMapping
    @PostMapping(value = "/add/{a}/{b}")
    public String test1(@PathVariable int a, @PathVariable int b, Model model){
        int res = a+b;
        model.addAttribute("msg","结果1为:"+res);
        return "demo1";
    }

    //通过这种方式,根据访问方式不同,来进行不同逻辑控制
    @GetMapping(value = "/add/{a}/{b}")
    public String test2(@PathVariable int a, @PathVariable int b, Model model){
        int res = a+b;
        model.addAttribute("msg","结果2为:"+res);
        return "demo1";
    }
}
  1. 前端传递信息给控制器,使用@RequestParam来固定前端传递的参数名进行绑定,如果是对象类型会自动进行匹配(一定要保证前端参数名称和对象属性名称一致)
@Controller
@RequestMapping("/user")
public class UserController {

    //@RequsetParam注解用来固定前端传参的对象名,来绑定到形参上,如果名称一样可省略,个人建议加上
    @RequestMapping("/t1")
    public String test1(@RequestParam("username") String name, Model model){
        //接收前端参数
        System.out.println("接收到的前端数据为:"+name);
        //将返回的结果返回到前端
        model.addAttribute("name",name);
        //跳转视图
        return "demo1";
    }

    /*
    * 1.接受前端用户传递的参数,判断参数的名字,假设名字直接在方法上,可以直接使用
    * 2.假设传递的是一个User对象,则会自动匹配User对象中的字段名,如果一样则ok,否则为null
    * 实例:url=localhost/user/t1?id=3&username=chelsea&age=20----------------------->结果=User{id=3,name=null,age=20}
    *
    * */
    //假如前端接受的是对象,可以直接将参数设置为对象,会自动匹配
    //前端url为:localhost/user/t2?id=1&name=chelsea&age=19
    @RequestMapping("/t2")
    public String test2(User user){
        System.out.println(user);
        return "demo1";
    }
    
}
  1. 乱码问题(一种是自己手写过滤器进行编码转换,一种是使用SpringMVC自带的过滤器)
  • 乱码问题首先想到的解决方案是写一个过滤器进行过滤如下,简单的给request和response配置编码即可
public class EncodingFilter extends HttpFilter {

    /*此处继承HttpFilter,也可以实现Filter接口,重写三个方法,init doFilter destory*/
    /*记得在webxml文件中配置filter*/
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        //进行处理
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        //处理后将请求继续转发
        chain.doFilter(request,response);
    }

}
  • 配置完成后记得在web.xml文件中进行注册,一般情况下乱码问题都会解决
<!--配置手写字符过滤filter,配置所有路径-->
<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>com.chelsea.filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
  • 一般情况下编码问题都可解决,或者使用SpringMVC自带的过滤器进行编码转换,更加全面,在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>
  1. 转发和重定向
  • 视图解析器默认使用的是请求转发(因为处理一个请求,url没有变换)
  • 如果需要进行重定向,返回的字符串加上redirect即可,例如:return “redirect:/index.jsp”;后面的视图地址为全路径地址

七:Json处理

  1. Json(JavaScript Object Notation)是一种轻量级的数据交换格式,是js的对象的字符串表示方法,本质是一个字符串,通过键值对来保存属性信息
  2. JSON和JS对象相互转换
var obj = {a: 'Hello', b: 'World'}; //这是一个对象,注意键名也是可以使用引号包裹的
var json = '{"a": "Hello", "b": "World"}'; //这是一个 JSON 字符串,本质是一个字符串

//将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"}'
  1. Controller控制器返回JSON数据,使用Jackson解析工具,当然还有阿里的fastjson等,首先导入包
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.12.3</version>
</dependency>
  • 编写控制器,必须绕开视图解析器,不然会乱拼接字符串出错。使用RestController注解或者ResponseBody注解。使用jackson包下的ObjectMapper将对象转换为Json字符串返回即可。可以根据自己需求封装多个对象
//此处只展示了这两个包,其他的未展示而已
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

@Controller
/*此注解作用:使本类下的所有方法都绕开视图解析器,返回字符串*/
@RestController
public class UserController {

    /*@Responsebody配置后,就不会走视图解析器,会直接返回一个字符串*/
    @ResponseBody
    @RequestMapping(value = "/j1",produces = "application/json;charset=utf-8")
    public String json1(){
        /*使用jackson,转为json对象*/
        ObjectMapper mapper = new ObjectMapper();
        User user = new User(1,"韩信",14);
        String str = null;
        try {
            str = mapper.writeValueAsString(user);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        /*
        * 如果不适用json,则返回的user对象为:User(id=1, name=chelsea, age=14)
        * 使用json后,返回的json类型的对象为:{"id":1,"name":"chelsea","age":14}
        *
        * */
        return str;
    }
    
    /*@Responsebody配置后,就不会走视图解析器,会直接返回一个字符串*/
    @ResponseBody
    @RequestMapping(value = "/j2",produces = "application/json;charset=utf-8")
    public String json2(){
        /*使用jackson,转为json对象*/
        ObjectMapper mapper = new ObjectMapper();
        List<User> userList = new ArrayList<User>();
        User user = new User(1,"韩信",14);
        User user1 = new User(1,"韩信",14);
        User user2 = new User(1,"韩信",14);
        User user3 = new User(1,"韩信",14);
        userList.add(user);
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
        String str = null;
        try {
            str = mapper.writeValueAsString(userList);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return str;
    }
}

后续还有Ajax和拦截器,SSM整合等,未完待续!

标签:控制器,01,SpringMVC,视图,Controller,User,Restful,public
来源: https://blog.csdn.net/qq_38869493/article/details/118659457

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有