添加依赖

  • 添加spring-mvc和servlet,jsp的依赖
  • jstl好像是jsp的扩展功能包,也加上吧 ```xml org.springframework spring-webmvc 5.1.9.RELEASE javax.servlet servlet-api 2.5 javax.servlet.jsp jsp-api 2.2 javax.servlet jstl 1.2
  1. <a name="zMkzq"></a>
  2. # 添加Web app支持
  3. - 右击项目,`Add Framework Support... ` 以添加web-app支持,添加后生成web文件夹,文件夹内用于存放静态页面和web配置文件
  4. - 这里选择`4.0`版本
  5. 项目结构:![image.png](https://cdn.nlark.com/yuque/0/2020/png/2319994/1604478889176-5411490e-2178-49a1-8a71-e7e6e9dc6268.png#crop=0&crop=0&crop=1&crop=1&height=98&id=p6FjG&margin=%5Bobject%20Object%5D&name=image.png&originHeight=426&originWidth=461&originalType=binary&ratio=1&rotation=0&showTitle=false&size=21534&status=done&style=none&title=&width=106)<br />**另外还有一个沙雕才犯的错误:业务什么的写在model里,web.xml又也在项目里...要么没有model,就都写在项目里。要么就都写model里!但是还是尽量使用model,项目的src什么的文件夹都删除,给model添加环境就好了**
  6. <a name="vyDUP"></a>
  7. ## 编写web.xml文件(4.0版本)
  8. - **xml文件主要做两件事:注册**`**DispatcherServlet**`**,还有绑定springmvc配置文件**
  9. - **springmvc配置文件的命名规则:**`**项目名-servlet.xml**`
  10. - **web.xml基本是固定的配置,就是关联配置文件才进行变动**
  11. ```xml
  12. <!--1.注册DispatcherServlet-->
  13. <servlet>
  14. <servlet-name>springmvc</servlet-name>
  15. <servlet-class>org.springframework.web.servlet.DispatcherServlet
  16. </servlet-class>
  17. <!--关联一个springmvc的配置文件-->
  18. <init-param>
  19. <param-name>contextConfigLocation</param-name>
  20. <param-value>classpath:springmvc-servlet.xml</param-value>
  21. </init-param>
  22. <!--启动级别-1 启动级别为1表示服务器一启动立刻让webapp也跟着启动 数字越小,启动越早 -->
  23. <load-on-startup>1</load-on-startup>
  24. </servlet>
  25. <!--所有请求被springmvc拦截,即请求必须由springmvc来处理-->
  26. <!--/ 匹配所有的请求;(不包括.jsp)-->
  27. <!--/* 匹配所有的请求;(包括.jsp) /*会导致404找不到-->
  28. <servlet-mapping>
  29. <servlet-name>springmvc</servlet-name>
  30. <url-pattern>/</url-pattern>
  31. </servlet-mapping>

编写springmvc配置文件

  • Springmvc也是一个spring子项目,所以springmvc的配置文件就是一个spring配置文件

主要做三件事:配置处理器映射器,处理器适配器,还有一个视图解析器
以下是官方的配置文件头,固定的

<?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
       http://www.springframework.org/schema/beans/spring-beans.xsd">
   .................................
</beans>
  • 中间的重点部分 ```xml

处理器映射:HandlerMapping 这个处理器映射比较low,后面会学更好的,但是它适合讲原理

处理器适配器:HandlerAdapter 视图解析器:ViewResolve 前缀为jsp文件的路径(不包括jsp文件本身) 后缀为jsp文件的后缀 前缀后缀后面要拼接起来形成完整路径

上面处理器映射那里HandlerMapping前还有一个BeanNameUrl,说明处理器映射是根据一个bean的属性来获取url从而寻找Controller的,所以我们要为每个页面都创建一个bean

id为/+jsp文件名 class为页面对应的控制器类路径

id有无/都可以

<a name="cR2C6"></a>
# 编写业务类(Controller)

- **业务类除了要编写业务代码,还要将传输给表现层的数据封装在模型视图对象里,即**创建`ModelAndView(模型和视图)`返回给HandlerAdapter,展示的业务数据封装在`ModelAndView`
   - `模型和视图`指的是一种对象,不是两个对象。。
```java
//实现的控制器接口会提示有2个接口,一个spring-context的,一个spring-web-servlet。这里是web-servlet的控制器接口
public class HelloController implements Controller {
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
String result="HelloSpringMVC";
        //ModelAndView 模型和视图
        ModelAndView mv = new ModelAndView();

        //封装对象,放在ModelAndView中。
        mv.addObject("msg","HelloSpringMVC!");  第一个参数叫“属性名”,第二个是第一个参数的值,相当于定义了一个变量供jsp获取

       //封装要跳转的视图,放在ModelAndView中
        mv.setViewName("/hello"); 
前缀后缀拼接在加上传递的参数(jsp文件名)构成完整路径 /WEB-INF/jsp/hello.jsp
        return mv;    }
}

创建视图层

jsp中获取数据自定义的变量数据是**${?}**

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

可以看到我们真正只做ViewResolver和Controller,springmvc执行原理的其他模块我们要么没做,要么只是提供了一些配置信息而已,**DispatcherServlet**作为HTTPServlet的一个间接子类/实现类,帮助我们封装完成了非常多的Servlet工作。所有web程序都是Servlet程序

运行(Tomcat)

  • 首先在idea的项目结构设置里设置:artifacts,这个没有实际意思,在idea里表示项目的整合(打包)方式,如整合为javaee项目包,整合为webapp项目包。即决定了项目包是什么类型:jar,war….
    • artifas那里点**+**就可以选择了,如何选好点ok即可。这里选webappliaction

tomcat:点击run->edit config… 添加一个tomcat的local(另外一个为远程的意思) ,在service那栏的appliction service后面的文件夹按钮那里选择安装了tomcat的本地文件夹,不用精确到bin,到如tomcat 8.5这个文件夹即可

edit那里还有一个deployment栏,+一个artifacts即可,artifact是系统创建好的,没有的话看上面一步

可能出现的错误

  • localhost:8080 in use 表示tomcat的8080被占用,可能被其他占用,可能是tomcat不知什么时候被启动了,执行tomcat的shutdown.bat命令即可 前一种自己看是关进程还是改端口

  • 访问出现404. 查看项目结构的libraries有无这个文件夹,文件夹是否为空。没有或者空就去project structure里配置下依赖,这种情况是编译后没有把依赖的jar包编译进去

  • 重启Tomcat

具体操作:在项目结构的artifacts里,output layout一栏,展开WEB-INF目录,没有lib目录,就点击创建目录(文件夹图标的小按钮)创建一个lib目录,选中lib目录点击+按钮,选择library Files。然后全选jar依赖包。ok即可

注解简化XML-SpringMVC

在spring-first的基础上改为注解+XML版,同时增加更多功能配置

编写web.xml

还是一样的写法,复制即可。注解主要是简化springmvc的配置文件而不是web.xml
web.xml

springmvc配置文件

配置文件头跟first,去注解springmvc配置文件复制
配置文件除了视图解析器不变,处理器映射和适配删除替换为其他(记得把处理器映射对应的bean也删除了),还增加了一些其他功能的配置

我们把所有的视图(静态资源)都存放在/WEB-INF/目录下以保护文件安全,因为该文件夹默认过滤静态资源
<mvc:default-servlet-handler />
**<mvc:annotation-driven />**

java类配置

@Configuration
@ComponentScan
@EnableWebMvc // 启用Spring MVC
@PropertySource("classpath:/jdbc.properties")
public class AppConfig {
    @Bean
WebMvcConfigurer createWebMvcConfigurer() {
    return new WebMvcConfigurer() {
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/static/**").addResourceLocations("/static/");
        }
    };
}
    @Bean   //这里是配置模板引擎
ViewResolver createViewResolver(@Autowired ServletContext servletContext) {
    PebbleEngine engine = new PebbleEngine.Builder().autoEscaping(true)
            .cacheActive(false)
            .loader(new ServletLoader(servletContext))
            .extension(new SpringExtension())
            .build();
    PebbleViewResolver viewResolver = new PebbleViewResolver();
    viewResolver.setPrefix("/WEB-INF/templates/");
    viewResolver.setSuffix("");
    viewResolver.setPebbleEngine(engine);
    return viewResolver;
}
}

编写Controller

@Controller //交由IOC托管,让Spring IOC容器初始化时自动扫描到
@RequestMapping("/HelloController")//实现类级别处理器映射
public class HelloController {
   //真实访问地址    拼接: 项目名/HelloController/hello
   @RequestMapping("/hello")//方法级别处理器映射
   public String sayHello(Model model){//方法中声明Model类型的参数是为了把Action中的数据带到视图中
       //向模型中添加属性msg与值,可以在JSP页面中取出并渲染
       model.addAttribute("msg","hello,SpringMVC");
       //web-inf/jsp/hello.jsp
       return "hello";//返回的结果是视图的名称hello,加上配置文件中的前后缀变成WEB-INF/jsp/hello.jsp
  }
}

ModelAndView和Model

  • model使用时作为控制器参数被自动创建,请求数据也被封装在model对象中
    • 通过addAttribute添加模板数据
    • 可以直接返回路径字符串,不需要返回model对象
  • ModelAndView需要自己创建
    • 通过addObject添加模板数据,作用和model的addAttribute一样
    • 通过setViewName设置返回页面路径,返回时返回ModelAndView对象
  • redirect:这种是后端做的操作,前端只是显示出了跳转的效果,不要以为是返回了字符串然后前端识别到前缀进行跳转
    ModelAndView mv = new ModelAndView();
    mv.addObject(user);   使用如:${user.name}
    mv.setViewName("redirect:/");
    

    创建视图层

    跟之前一样

SpringMVC总结

使用springMVC必须配置的三大件:
处理器映射器、处理器适配器、视图解析器
实际开发中我们常常借助注解进行开发,我们只需要手动配置视图解析器,而处理器映射器和处理器适配器只需要开启注解驱动即可,而省去了大段的xml配置

获取HttpServletXXX的几种方式

//方法1:直接在控制器参数那里传入
@GetMapping
public void index(HttpServletRequest request)

//方法2:通过RequestContextHolder获取,服务层也能用
    ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
 HttpServletRequest request = servletRequestAttributes.getRequest();

//方法3:直接注入,服务层应该也能用
@Autowired
private HttpServletRequest request;