Spring MVC

Spring MVC

官方文档:https://docs.spring.io/spring/docs/5.3.0-SNAPSHOT/spring-framework-reference/web.html#spring-web

MVC

Model (javabean)

View (jsp,freemaker,thymeleaf)

Controller (servlet controller)

Servlet实现Web应用:

IDEA开发:

新建普通项目-->右键添加框架支持 -->选择WebApplication-->编辑配置文件-->+ Tomcat配置

HelloServlet.java:

public class HelloServlet  extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getParameter("method");
        if(method.equals("add")){
            req.getSession().setAttribute("msg","执行了add方法");
        }else if(method.equals("delete")){
            req.getSession().setAttribute("msg","执行了delete方法");

        }
        System.out.println("doGet");
        //转发
        req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

web.xml

<?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">
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.yan.servlet.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>15</session-timeout>
    </session-config>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

/WEB-INF/jsp/test.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  $END$
  </body>
</html>

SpringMVC运行原理图

官方:

详细原理:

初步使用SpringMVC

IDEA配置 :

新建maven项目-->添加框架支持 -->选择 WebApplication-->web.xml中配置dispatcherServlet(SpringMVC配置文件位置)-->建立spring-mvc-servlet.xml文件 -->配置处理器映射器,处理器适配器,视图解析器-->编写Controller-->配置 Controller bean-->编辑项目结构-->到Artifacts下,在WEB-INF 下新建lib目录并导入依赖包

web.xml

<?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">
    <!--    配置 前端控制器 -->
    <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-servlet.xml</param-value>
        </init-param>
         <!--    启动级别  -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

spring-mvc-servlet.xml

<!--    配置处理器映射器-->
    <bean id="handlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!--    配置处理器适配器-->
    <bean id="handlerAdapter" class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!--    配置视图解析器-->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
<!--配置Controller-->
    <bean id="/hello" class="com.yan.controller.HelloController"/>

HelloController.java

public class HelloController implements Controller {

    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        ModelAndView modelAndView=new ModelAndView();
        modelAndView.addObject("msg","helloSpringMVC");
        modelAndView.setViewName("hello");
        return modelAndView;
    }
}

hello.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${msg}
</body>
</html>

小问题

其中/和/*的区别:
< url-pattern >/</ url-pattern >  不会匹配到*.jsp,即:*.jsp不会进入spring的 DispatcherServlet类 。
< url-pattern > /*</ url-pattern > 会匹配*.jsp,会出现返回jsp视图时再次进入spring的DispatcherServlet 类,导致找不到对应的controller所以报404错。

使用注解Controller

改动:

spring-mvc-servlet.xml

<!--扫描 注解包-->
    <context:component-scan base-package="com.yan.controller"/>
<!--    让Spring不处理静态资源 -->
    <mvc:default-servlet-handler/>
<!--    MVC注解驱动-->
    <mvc:annotation-driven/>
<!--    处理器映射器-->
    <bean id="handlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!--    处理器适配器-->
    <bean id="handlerAdapter" class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!--    配置视图解析器-->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp"/>
        <property name="suffix" value=".jsp"/>
    </bean>
<!--配置Controller-->
    <bean id="/hello" class="com.yan.controller.HelloController"/>

AnnotationController.java

@Controller
public class AnnotationController {
    @RequestMapping("/annotation")
    public String hello(Model model){
        model.addAttribute("msg","AnnotationController.hello");
        System.out.println("AnnotationController.hello");
        return "hello";
    }
}

细节问题

@PathVariable

例子:

@RequestMapping("/count/{a}/{b}")
    public String add(@PathVariable Integer a,@PathVariable Integer  b,Model model){
        model.addAttribute("result",a+b);
        return "result";
    }

请求 :

http://localhost:8080/count/1/2

路径参数可以绑定到方法变量上

转发,重定向:

1.使用HttpServletRequest和HttpServletResponse

 @RequestMapping("/origin")
    public void origin(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        request.setAttribute("msg","origin");
//        request.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(request,response);
        response.sendRedirect("http://www.baidu.com");
    }

2.使用SpringMVC转发和重定向(无需视图解析器)

 @RequestMapping("/mvc")
    public String mvc(Model model) throws ServletException, IOException {
        model.addAttribute("result",3);
        //转发1
        //return "/WEB-INF/jsp/result.jsp";
        //转发2
        //return "forward:/WEB-INF/jsp/result.jsp";
        //重定向
        return "redirect:http://www.baidu.com";
    }

配置视图解析器后 转发1 会被拼接前后缀

参数绑定 :

参数名对应请求方法上的参数名,直接绑定

 @RequestMapping("/param")
    public String  param(String name){
        System.out.println(name);
        return "hello";
    }

请求:

http://localhost:8080/param?name=yan

参数名对应请求方法上的参数但名字不同,用@RequestParam重命名

 @RequestMapping("/param")
    public String  param(@RequestParam("username") String name){
        System.out.println(name);
        return "hello";
    }

请求:

http://localhost:8080/param?username=yan

对象:

 @RequestMapping("/param")
    public String  param(User user){
        System.out.println(user);
        return "hello";
    }

User.java

public class User {
    private String name;
    private int age;

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

请求:

http://localhost:8080/param?name=yan&age=1

编码问题 :

配置SpringMVC编码过滤器:

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

posted @ 2020-05-23 21:02  天涯屐痕  阅读(168)  评论(0)    收藏  举报