SpringMvc学习

本文深入探讨了SpringMVC框架的概念、特点及其在Web开发中的应用。从MVC设计模式出发,介绍了SpringMVC的请求处理流程、环境搭建、参数绑定、URL映射配置、域对象配置等内容。同时,覆盖了请求转发与重定向、JSON数据处理、拦截器、文件上传、SSM框架集成等高级特性。
摘要由CSDN通过智能技术生成

Day01-SpringMvc笔记

一、MVC思想&SpringMvc框架概念与特点

1.什么叫MVC思想

model --模型 view–视图 controller–控制器

模型:数据模型,负责封装应用程序数据在视图层展示,域对象(JavaBean Map List )

视图:只是展示这些数据jsp页面,不包含任何业务逻辑。

控制器:负责接收来自用户的请求,并调用后台服务(service 或者 dao)来处理业务逻辑。-Servlet 业务逻辑处理,页面转发。

MVC 模式的核心思想是将业务逻辑从界面中分离出来,允许它们单独改变而不会相互影响。

2.MVC框架

Jsp+servlet>struts1>spring mvc>struts2+freemarker>struts2,ognl,值栈。

开发效率上,基本正好相反。值得强调的是,spring mvc 开发效率和 struts2 不相上下,但从目前来看,spring mvc 的流行度已远远超过 struts2。

3.Spring MVC是什么

​ Spring MVC 是 Spring 家族中的一个 web 成员, 它是一种基于 Java 的实现了 Web MVC 设计思想的请求驱动类型的轻量级 Web 框架,即使用了 MVC 架构模式的思想,将 web 层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,Spring MVC 也是要简化我们日常 Web 开发的。

​ Spring MVC 是服务到工作者思想的实现。前端控制器是 DispatcherServlet;应用控制器拆为处理器映射器(Handler Mapping)进行处理器管理和视图解析器(View Resolver) 进行视图管理;支持本地化/国际化(Locale)解析及文件上传等;提供了非常灵活的数据验证、格式化和数据绑定机制;提供了强大的约定大于配置(惯例优先原则)的契约式编程支持。

4.Spring MVC 特点
  1. 让我们能非常简单的设计出干净的 Web 层;
  2. 进行更简洁的 Web 层的开发;
  3. 天生与 Spring 框架集成(如 IoC 容器、AOP 等);
  4. 提供强大的约定大于配置的契约式编程支持;
  5. 能简单的进行 Web 层的单元测试;
  6. 支持灵活的 URL 到页面控制器的映射;
  7. 非常容易与其他视图技术集成,如 jsp、Velocity、FreeMarker 等等,因为模型数据不放在特定的 API 里,而是放在一个 Model 里(Map 数据结构实现,因此很容易被其他框架使用);
  8. 非常灵活的数据验证、格式化和数据绑定机制,能使用任何对象进行数据绑定,不必实现特定框架的 API;
  9. 支持灵活的本地化等解析;
  10. 更加简单的异常处理;
  11. 对静态资源的支持;

12.支持 Restful 风格。

二、SpringMvc请求流程&环境搭建与测试

1.Spring MVC 请求处理流程分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GlGMUt6p-1597568202656)(F:\A20200102\高级资源\Springmvc 框架\流程图.png)]

2.Spring MVC 环境搭建
2.1创建web工程
2.2添加依赖坐标
<!-- spring web -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>

    <!-- spring mvc -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>

    <!-- web servlet -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.0.1</version>
    </dependency>

  <build>
    <finalName>springmvc01</finalName>
    <plugins>
      <!-- 编译环境插件 -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>                 <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <encoding>UTF-8</encoding>
      </configuration>
      </plugin>
      <plugin>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>maven-jetty-plugin</artifactId>
        <version>6.1.25</version>
        <configuration>
          <scanIntervalSeconds>10</scanIntervalSeconds>
          <contextPath>/springmvc01</contextPath>
        </configuration>
      </plugin>

    </plugins>
  </build>
2.3配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.0"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">


  <!--
    编码过滤器
    前端控制器
 -->
  <filter>
    <description>char encoding filter</description>
    <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>

  <!-- servlet请求分发器 -->
  <servlet>
    <servlet-name>springMvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:servlet-context.xml</param-value>
    </init-param>
    <!-- 表示启动容器时初始化该Servlet -->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>springMvc</servlet-name>
    <!-- 这是拦截请求, /代表拦截所有请求,拦截所有.do请求 -->
    <url-pattern>/</url-pattern>
  </servlet-mapping>
    
</web-app>
2.4配置servlet-context.xml

src/main/resources

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 扫描com.shsxt.controller 下包 -->
    <context:component-scan base-package="com.shsxt.controller" />
    <!-- mvc 请求映射 处理器与适配器配置-->
    <mvc:annotation-driven/>
    <!--配置视图解析器  默认的视图解析器- -->
    <bean id="defaultViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property 	name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
        <property name="contentType" value="text/html" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>

</beans>
2.5添加控制器代码

com.shsxt.controller

package com.shsxt.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class HelloController {

    // localhost:8080/springmvc/hello
    @RequestMapping("hello")
    public ModelAndView hello(){
        ModelAndView mv =new ModelAndView();
        /**
         * 1.模型
         * 2.视图
         */
        mv.addObject("hello","hello SpringMvc");
        mv.setViewName("hello");
        return mv;
    }
}
2.6添加视图

src/main/webapp/WEB-INF/jsp–>hello.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
  ${hello}
</body>
</html>
2.7配置jetty启动命令
jetty:run  -Djetty.port=8080

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QCSEu9oq-1597568202663)(F:\A20200102\高级资源\Springmvc 框架\2.png)]

2.8启动测试

localhost:8080/springmvc01/hello

三、参数绑定&URL地址映射配置&域对象配置

1.参数绑定
1.1基本类型|包装类型

基本类型

 /**
     * 基本类型参数绑定
     *  参数值必须存在 如果未指定参数值  500错误
     *  参数名与方法形参名必须一致
     */
    @RequestMapping("p01")
    public void p01(int id,int money){
        System.out.println(id+"---"+money);
    }

    /**
     * 基本类型参数绑定
     *       参数值必须存在 如果未指定参数值  500错误
     *       参数名与方法形参名必须一致
     *       如果参数值未设置 可以通过@RequestParam
     *                                  defaultValue属性设置默认值
     *                                  name 设置形参别名
     * @param id
     * @param money
     */
    @RequestMapping("p02")
    public void p02(@RequestParam(name="userId",defaultValue="10") int id,@RequestParam(defaultValue="1000.0")double money){
        System.out.println(id+"++++"+money);
    }

包装类型

  /**
     * 包装类型参数值默认 null 推荐使用包装类型
     *      如果参数值未设置  可以通过@RequestParam
     *                              defaultValue 属性设置默认值
     *                              name 设置参数别名
     *   404错误:客户端错误   客户端传入的参数类型与后端方法形参的类型不匹配
     * @param pageNum
     * @param pageSize
     */
    @RequestMapping("p03")
    public void p03(@RequestParam(name="pn",defaultValue = "1") Integer pageNum,@RequestParam(name="ps") Integer pageSize){
        System.out.println(pageNum+"---"+pageSize);
    }
1.2 String|Date
 /**
     * 字符串类型:默认值为null
     * @param userName
     * @param userPwd
     */
    @RequestMapping("p04")
    public void p04(String userName,String userPwd){
        System.out.println(userName+","+userPwd);
    }
1.3 JavaBean 类型
  /**
     * JavaBean 类型
     *     url 参数名与JavaBean 成员属性名一致即可
     *         注意日期绑定 需要在日期变量级别 声明@DateTimeFormat(pattern = "yyyy-MM-dd")
     * @param accountQuery
     */
    @RequestMapping("p05")
    public void p05(AccountQuery accountQuery){
        System.out.println(accountQuery);
    }

AccountQuery 类

public class AccountQuery {
    private Integer pageNum;
    private Integer pageSize;
    private String aname;
    private String type;
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date time;

   private List<Integer> ids;
    
     private Map<String,Object> map;

    public List<Integer> getIds() {
        return ids;
    }

    public Map<String, Object> getMap() {
        return map;
    }

    public void setMap(Map<String, Object> map) {
        this.map = map;
    }

    public void setIds(List<Integer> ids) {
        this.ids = ids;
    }

    @Override
    public String toString() {
        return "AccountQuery{" +
                "pageNum=" + pageNum +
                ", pageSize=" + pageSize +
                ", aname='" + aname + '\'' +
                ", type='" + type + '\'' +
                ", time=" + time +
                '}';
    }

    public Integer getPageNum() {
        return pageNum;
    }

    public void setPageNum(Integer pageNum) {
        this.pageNum = pageNum;
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }

    public String getAname() {
        return aname;
    }

    public void setAname(String aname) {
        this.aname = aname;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public Date getTime() {
        return time;
    }

    public void setTime(Date time) {
        this.time = time;
    }
}
1.4数组
  /**
     * 数组参数:
     *    ids=xxx&ids=xxx&ids=xxx
     * @param ids
     */
    @RequestMapping("p06")
    public void p06(Integer[] ids){
        for(Integer id:ids){
            System.out.println(id);
        }
    }
1.5 List集合
/**
     * 集合类型参数 不能直接声明为方法形参
     *       必须有JavaBean进行包装(作为JavaBean的成员变量实现参数绑定)
     *   List 集合 参数绑定 与数组绑定参数传入类似
     *    @param accountQuery
     */
    @RequestMapping("p07")
    public void p07(AccountQuery accountQuery){
        accountQuery.getIds().forEach(id->{
            System.out.println(id);
        });
    }
1.6 Map集合
 /**
     * Map集合
     *     map[key]=value&map[key]=value&map[key]=value
     * @param accountQuery
     */
    @RequestMapping("p08")
    public void p08(AccountQuery accountQuery){
        accountQuery.getMap().forEach((k,v)->{
            System.out.println(k+"----"+v);
        });
    }
2.URL映射地址配置
url 到方法绑定
 @RequestMapping
    声明在类 + 方法级别
 value:默认属性可以省略  配置 uri 地址  uri地址可以配置多个
 如果类  方法级别均声明@RequestMapping uri 地址:类级别url/方法级别uri
method 配置方法支持的请求类型  默认Get + Post 均支持  显式声明method 方法支持具体请求类型
params :配置方法的形参 访问时以方法形参名称进行访问
 @RequestMapping("u01")
    public ModelAndView u01(){
        ModelAndView mv=new ModelAndView();
        mv.setViewName("hello");
        mv.addObject("hello","u01");
        return mv;
    }

    @RequestMapping(value = {"u02_01","u02_02"})
    public ModelAndView u02(){
        ModelAndView mv=new ModelAndView();
        mv.setViewName("hello");
        mv.addObject("hello","u02");
        return mv;
    }

    @RequestMapping(value = {"u03_01","u03_02"},method = {RequestMethod.POST,RequestMethod.GET})
    public ModelAndView u03(){
        ModelAndView mv=new ModelAndView();
        mv.setViewName("hello");
        mv.addObject("hello","u03");
        return mv;
    }

    @RequestMapping(params = "u04")
    public ModelAndView u04(){
        ModelAndView mv=new ModelAndView();
        mv.setViewName("hello");
        mv.addObject("hello","u04");
        return mv;
    }
3.域对象配置
  /**
     * 请求域对象设置
     *      方法返回ModelAndView
     *          ModelAndView
     *      方法返回字符串时
     *      ModelMap
     *      Model
     *      Map
     *      Request
     *  内置对象声明
     *     方法形参声明内置对象
     *        request  response  session
     */
    @RequestMapping("s01")
    public ModelAndView s01(){
        ModelAndView mv=new ModelAndView();
        mv.setViewName("hello");
        mv.addObject("hello","s01");
        return mv;
    }

    @RequestMapping("s02")
    public String s02(ModelMap modelMap){
        modelMap.addAttribute("hello","s02");
        return "hello";
    }

    @RequestMapping("s03")
    public String s03(Map map){
        map.put("hello","s03");
        return "hello";
    }

    @RequestMapping("s04")
    public String s04(Model model){
        model.addAttribute("hello","s04");
        return "hello";
    }

    @RequestMapping("s05")
    public String s05(HttpServletRequest request){
        request.setAttribute("hello","s05");
        return "hello";
    }

    @RequestMapping("s06")
    public ModelAndView s06(HttpServletRequest request){
        ModelAndView mv=new ModelAndView();
        mv.setViewName("hello");
        request.setAttribute("hello","s06");
        return mv;
    }

    @RequestMapping("s07")
    public ModelAndView s07(HttpSession session){
        ModelAndView mv=new ModelAndView();
        mv.setViewName("hello");
        session.setAttribute("hello","s07");
        return mv;
    }

    @RequestMapping("s08")
    public ModelAndView s08(HttpSession session){
        ModelAndView mv=new ModelAndView();
        mv.setViewName("hello");
        System.out.println(session.getAttribute("hello"));
        return mv;
    }

    @RequestMapping("s09")
    public void s09(HttpServletResponse response){
        response.setContentType("application/json;charset=utf-8");
        response.setCharacterEncoding("utf-8");
        try {
            PrintWriter pw=response.getWriter();
            pw.write("{\"id\":20,\"userName\":\"admin\"}");
            pw.flush();
            pw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

四、请求转发&重定向

1.重定向
@Controller
public class RedirectDispatcherController {

    /**
     * 请求转发 & 重定向
     */

    @RequestMapping("r01")
    public String r01(){
        return "redirect:result.jsp";
    }

    @RequestMapping("r02")
    public String r02(){
        return "redirect:result.jsp?id=10&name=admin";
    }

    /**
     * 重定向 如果存在中文参数值  默认乱码
     */
    @RequestMapping("r03")
    public String r03(){
        return "redirect:result.jsp?id=10&name=张三";
    }

    /**
     * RedirectAttributes  重定向参数  推荐使用 解决乱码
     * @param redirectAttributes
     * @return
     */
    @RequestMapping("r04")
    public String r04(RedirectAttributes redirectAttributes){
        redirectAttributes.addAttribute("id",20);
        redirectAttributes.addAttribute("name","李四");
        return "redirect:result.jsp";
    }

    //重定向到方法
    @RequestMapping("r05")
    public String r05(RedirectAttributes redirectAttributes){
        redirectAttributes.addAttribute("id",20);
        redirectAttributes.addAttribute("name","李四");
        return "redirect:test";
    }

    @RequestMapping("r06")
    public ModelAndView r06(){
        ModelAndView mv=new ModelAndView();
        mv.setViewName("redirect:test");
        mv.addObject("id",20);
        mv.addObject("name","李四");
        return mv;
    }
}

test类

@Controller
public class TestController {
    @RequestMapping("test")
    public void test(Integer id,String name){
        System.out.println(id+","+name);
    }

    @RequestMapping("test02")
    public void test02(){
        System.out.println("test02..........");
    }
}
2.请求转发
//默认是请求转发

   // 转发到 一个新的方法时
    @RequestMapping("r07")
    public ModelAndView r07(){
        ModelAndView mv=new ModelAndView();
        mv.addObject("hello","r07");
        mv.setViewName("forward:test02");
        return mv;
    }

Day02-SpringMvc笔记

一、SpringMvc转换JSON数据

1.基本概念
@ResponseBody 响应体注解
	 声明级别: 类级别   方法级别(使用较多)
 	 默认作为 请求的响应体内容 json 数据
 @RequestBody
 	声明级别:方法形参类型前面
	 默认为请求体内容 格式为json 数据
2.添加配置

添加json依赖坐标

<!-- 添加json 依赖jar包 -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.7.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.7.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.7.0</version>
    </dependency>

添加json转换器配置

servlet-context.xml

 <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter" />
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
        </mvc:message-converters>
    </mvc:annotation-driven>
3.注解使用

User类

public class User {
    private Integer id;
    private String userName;

    public User() {
    }

    public User(Integer id, String userName) {
        this.id = id;
        this.userName = userName;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
}
@RequestMapping("user")
public class UserController {
    private Map<Integer, User> users;

    public UserController(){
        users=new HashMap<>();
        users.put(10,new User(10,"admin"));
        users.put(20,new User(20,"test"));
    }

    @RequestMapping("login")
    public void login(HttpSession session){
        System.out.println("用户登录....");
        session.setAttribute("userInfo",new User(10,"admin"));
    }

    @RequestMapping("queryUserByUserId")
    @ResponseBody
    public User queryUserById(Integer userId){
        return users.get(userId);
    }

    @RequestMapping("queryUserByUserId02")
    public  @ResponseBody User queryUserById02(Integer userId){
        return users.get(userId);
    }

    @RequestMapping("list")
    @ResponseBody
    public List<User> queryUsers(){
        return Arrays.asList(new User(10,"admin"),new User(20,"test"));
    }

    @RequestMapping("list02")
    @ResponseBody
    public Map<Integer,User> queryUsers02(){
        return users;
    }

    @RequestMapping("list03")
    @ResponseBody
    public List<Map<String,User>> queryUsers03(){
        Map<String,User> map01=new HashMap<>();
        map01.put("admin",new User(10,"admin"));
        Map<String,User> map02=new HashMap<>();
        map02.put("test",new User(20,"test"));
        return Arrays.asList(map01,map02);
    }

    //请求

    @RequestMapping("queryUser")
    @ResponseBody
    public User queryUser(@RequestBody User user){
        return user;
    }

    @RequestMapping("test")
    @ResponseBody
    public ParamModel test(@RequestBody ParamModel paramModel){
        return paramModel;
    }
}

二、拦截器

1.定义拦截器二种方法

实现接口:HandlerInterceptor
继承: HandlerInterceptorAdapter

2.配置拦截器

servlet-context.xml

方式一:
 <!--
        拦截器生效配置-01
            MyInterceptor01 拦截器 拦截所有的资源
    -->
 <mvc:interceptors>
      <bean class="com.shsxt.interceptors.MyInterceptor01"></bean>
 </mvc:interceptors>
public class MyInterceptor01 implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("MyInterceptor01-->preHandle-->在Handler 方法执行前执行preHandler方法");
        return true;
        /**
         * 方法
         *   返回true:  执行目标方法
         *   返回false: 禁止目标方法执行
         */
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor01-->postHandle-->在Hander方法执行后未生成视图前执行postHandle方法");
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("MyInterceptor01-->afterCompletion-->在Handler 方法执行后并且完成视图生成执行afterCompletion");
    }
}
方式二:
<!--
  拦截器生效配置-02

     mvc:mapping path :配置拦截的资源   可以配置多个
            /**:拦截所有资源
     mvc:exclude-mapping path :配置放行资源   可以配置多个

   -->
 <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/url/**"/>
            <mvc:mapping path="/p01"/>
            <mvc:exclude-mapping path="/user/login"/>
            <bean class="com.shsxt.interceptors.MyInterceptor01"></bean>
        </mvc:interceptor>
    </mvc:interceptors>
方式三:多个拦截器
<mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/url/**"/>
            <mvc:mapping path="/p01"/>
            <mvc:exclude-mapping path="/user/login"/>
            <bean class="com.shsxt.interceptors.MyInterceptor01"></bean>
        </mvc:interceptor>
    
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.shsxt.interceptors.MyInterceptor03"></bean>
        </mvc:interceptor>

    </mvc:interceptors>
public class MyInterceptor03 extends HandlerInterceptorAdapter{
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterceptor03-->preHandle-->在Handler 方法执行前执行preHandler方法");
        return true;
    }
}
3.用户登录拦截器
<mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <mvc:exclude-mapping path="/user/login"/>
            <bean class="com.shsxt.interceptors.NoLoginInterceptor"></bean>
        </mvc:interceptor>

    </mvc:interceptors>
public class NoLoginInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        /**
         * 判断session中用户信息是否存在
         * 存在 放行
         * 不存在 重定向到login
         */
        User user= (User) request.getSession().getAttribute("userInfo");
        if(null==user){
            response.sendRedirect(request.getContextPath()+"/login.jsp");
            return false;
        }
        return true;
    }
}

三、SpringMvc文件上传

1.添加配置
添加文件上传依赖坐标
<!--文件上传-->
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.2</version>
    </dependency>

<!--jstl-->
    <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
配置文件上传解析器

servlet-context.xml

<!--
      配置文件上传解析器
   -->
    <bean id="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize">
            <value>104857600</value>
        </property>
        <property name="maxInMemorySize">
            <value>4096</value>
        </property>
    </bean>
2.文件上传使用
@Controller
public class FileController {

    @RequestMapping("/upload")
    public String uploadFile(HttpServletRequest request){

        MultipartHttpServletRequest mhsr= (MultipartHttpServletRequest) request;
        
        //获取上传的临时文件
        
        MultipartFile mf=mhsr.getFile("file");
        if(null!=mf && mf.getSize()>0){
            String basePath=request.getSession().getServletContext().getRealPath("/");
            File file=new File(basePath+"/upload");
            if(!(file.exists())){
                file.mkdir();
            }
            /**
             * 文件名定义
             *    1.获取原始文件名(可能出现文件名冲突)
             *    2.创建新的文件名(文件名唯一)
             *          2.1  年月日时分秒.png|jpg|gif
             *          2.2  获取系统当前时间毫秒数
             *          2.3  UUID  随机 不重复 32字符串
             */
            String fileName= UUID.randomUUID().toString().replace("-","");
            mf.getOriginalFilename().substring(mf.getOriginalFilename().lastIndexOf("."));
            try {
                mf.transferTo(new File(file,fileName));
                request.setAttribute("result","文件上传成功!");

            } catch (IOException e) {
                e.printStackTrace();
                request.setAttribute("result","文件上传失败!");
            }
        }else{
            request.setAttribute("result","文件上传失败!");
        }

        return "result";
    }
}

result.jsp

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

四、SSM框架集成

1.集成配置
添加依赖坐标
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.shsxt</groupId>
  <artifactId>ssm</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>ssm Maven Webapp</name>


  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>
    <!-- spring 测试 jar -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>
    <!-- spring jdbc -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>
    <!-- spring 事物 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>
    <!-- aspectj 切面编程的 jar -->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.8.9</version>
    </dependency>
    <!-- c3p0 连接池 -->
    <dependency>
      <groupId>c3p0</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.1.2</version>
    </dependency>
    <!-- mybatis -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.1</version>
    </dependency>
    <!-- 添加 mybatis 与 Spring 整合的核心包 -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.0</version>
    </dependency>
    <!-- mysql 驱动包 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.39</version>
    </dependency>
    <!-- 日志打印相关的 jar -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.2</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.2</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
    <dependency>
      <groupId>com.github.pagehelper</groupId>
      <artifactId>pagehelper</artifactId>
      <version>5.1.11</version>
    </dependency>



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

    <!-- spring mvc -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.3.2.RELEASE</version>
    </dependency>

    <!-- web servlet -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.0.1</version>
    </dependency>


    <!-- 添加json 依赖jar包 -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.7.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.7.0</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.7.0</version>
    </dependency>

	<!--文件上传-->
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.2</version>
    </dependency>

  </dependencies>

  <build>
    <finalName>ssm</finalName>
    <!--
              Maven 项目
                 如果源代码(src/main/java)存在xml  properties  tld 等文件  maven 默认不会自动编译该文件到输出目录
                 如果要编译源代码中xml properties tld 等文件  需要显式配置resources 标签
            -->
    <resources>
      <resource>
        <directory>src/main/resources</directory>
      </resource>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
          <include>**/*.properties</include>
          <include>**/*.tld</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>

    <plugins>
      <plugin>
        <groupId>org.mybatis.generator</groupId>
        <artifactId>mybatis-generator-maven-plugin</artifactId>
        <version>1.3.2</version>
        <configuration>
          <configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
          <verbose>true</verbose>
          <overwrite>true</overwrite>
        </configuration>
      </plugin>

        <!--jetty-->
      <plugin>
        <groupId>org.mortbay.jetty</groupId>
        <artifactId>maven-jetty-plugin</artifactId>
        <version>6.1.25</version>
        <configuration>
          <scanIntervalSeconds>10</scanIntervalSeconds>
          <contextPath>/ssm</contextPath>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         id="WebApp_ID" version="3.0">
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <filter>
    <description>char encoding filter</description>
    <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>
  <servlet>
    <servlet-name>springMvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>springMvc</servlet-name>
   <!-- <url-pattern>*.do</url-pattern>-->
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>
添加servlet-context.xml
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 扫描com.shsxt.controller 下包 -->
    <context:component-scan base-package="com.shsxt.controller" />
    <!-- mvc 请求映射 处理器与适配器配置-->
    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter" />
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
        </mvc:message-converters>
    </mvc:annotation-driven>
    <!--配置视图解析器  默认的视图解析器- -->
    <bean id="defaultViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property 	name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
        <property name="contentType" value="text/html" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <!--
      配置文件上传解析器
   -->
    <bean id="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize">
            <value>104857600</value>
        </property>
        <property name="maxInMemorySize">
            <value>4096</value>
        </property>
    </bean>

    <!--
        放行静态资源  SpringMvc框架不做处理 直接响应给浏览器
    -->
    <mvc:default-servlet-handler/>

    <!--
        全局异常统一处理-01
            处理应用程序视图异常  无法处理方法响应json 的情况
    -->
    <!--<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="defaultErrorView" value="error"></property>
        <property name="exceptionAttribute" value="ex"></property>
        <property name="exceptionMappings">
            <props>
                <prop key="com.shsxt.exceptions.ParamsException">param-error</prop>
                <prop key="com.shsxt.exceptions.NoLoginException">no-login-error</prop>
            </props>
        </property>
    </bean>-->

</beans>

spring.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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
       <!--  配置扫描器     -->
       <context:component-scan base-package="com.shsxt">
              <!--除了controller层不扫描-->
              <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
       </context:component-scan>

       <!--properties 文件加载配置-->
       <context:property-placeholder location="classpath:jdbc.properties"/>
       <!--
              c3p0数据源配置
       -->
       <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
              <property name="driverClass" value="${jdbc.driver}"></property>
              <property name="jdbcUrl" value="${jdbc.url}"></property>
              <property name="user" value="${jdbc.uname}"></property>
              <property name="password" value="${jdbc.password}"></property>
       </bean>
       <!--自动化注入-->
       <aop:aspectj-autoproxy/>
       <!--
      事物管理器
   -->
       <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
              <property name="dataSource" ref="dataSource"></property>
       </bean>
       <tx:advice id="txAdvice" transaction-manager="txManager">
              <tx:attributes>
                     <tx:method name="save*" propagation="REQUIRED"/>
                     <tx:method name="update*" propagation="REQUIRED"></tx:method>
                     <tx:method name="del*" propagation="REQUIRED"></tx:method>
              </tx:attributes>
       </tx:advice>

       <aop:config>
              <aop:pointcut id="cut" expression="execution(* com.shsxt.service..*.*(..))"/>
              <aop:advisor pointcut-ref="cut" advice-ref="txAdvice"></aop:advisor>
       </aop:config>
       <!--
      Mybatis 整合Spring
   -->
       <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
              <property name="dataSource" ref="dataSource"></property>
              <!--
                  mybatis 全局配置文件
              -->
              <property name="configLocation" value="classpath:mybatis.xml"></property>
              <!--
                  sql 映射文件
              -->
              <property name="mapperLocations" value="classpath:com/shsxt/mappers/*.xml"></property>
       </bean>

       <bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
              <property name="basePackage" value="com.shsxt.dao"></property>
              <property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean"></property>
       </bean>
</beans>
2.测试使用
@Controller
public class IndexController{

    @Resource
    private IndexService indexService;

    @RequestMapping("index")
    public String index(HttpServletRequest request){
        request.setAttribute("msg","hello ssm");
		return "index";
    }
}

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    ${msg}
</body>
</html>
3.静态文件处理
@Controller
public class IndexController{

    @Resource
    private IndexService indexService;

    @RequestMapping("index")
    public String index(HttpServletRequest request){
        request.setAttribute("msg","hello ssm");
        //放入上下文路径/ssm
        request.setAttribute("ctx",request.getContextPath());
		return "index";
    }
}

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <%--引入css--%>
    <link rel="stylesheet" href="${ctx}/statics/css/user.css">
</head>
<body>
    ${msg}
    <img src="${ctx}/statics/images/2.jpg">
</body>
</html>

拦截器

web.xml

<servlet-mapping>
    <servlet-name>springMvc</servlet-name>
   <!-- <url-pattern>*.do</url-pattern>-->
    <url-pattern>/</url-pattern>
  </servlet-mapping>

五、SpringMvc全局异常统一处理

1.全局异常处理方式一
 <!--
        全局异常统一处理-01
            处理应用程序视图异常  无法处理方法响应json 的情况
    -->
 <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
       <!--视图-->
        <property name="defaultErrorView" value="error"></property>
     
        <!--异常信息-->
     
        <property name="exceptionAttribute" value="ex"></property>
     
     <!--分类异常-->
     
        <property name="exceptionMappings">
            <props>
                <prop key="com.shsxt.exceptions.ParamsException">param-error</prop>
                <prop key="com.shsxt.exceptions.NoLoginException">no-login-error</prop>
            </props>
        </property>
    </bean>

<%-- error.jsp--%>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    服务器错误,请稍后再试.....${ex}
</body>
</html>

<%-- param-error.jsp--%>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    参数异常页面---${ex}
</body>
</html>

<%-- no-login-error.jsp--%>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    未登录异常页面-----${ex}
</body>
</html>

/**
 * 自定义参数异常  ParamsException
 */

public class ParamsException extends RuntimeException{
    private Integer code=300;
    private String msg="参数异常!";

    public ParamsException(){
        super("参数异常!");
    }
    public ParamsException(String msg){
        super(msg);
        this.msg=msg;
    }

    public ParamsException(Integer code) {
        super("参数异常!");
        this.code = code;
    }

    public ParamsException(String msg, Integer code) {
        super(msg);
        this.code = code;
        this.msg=msg;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

/**
 * 自定义参数异常  NoLoginException
 */

public class NoLoginException  extends RuntimeException{
    private Integer code=500;
    private String msg="未登录异常!";

    public NoLoginException() {
        super("未登录异常!");
    }

    public NoLoginException(Integer code) {
        super("未登录异常!");
        this.code = code;
    }

    public NoLoginException(String msg) {
        super(msg);
        this.msg = msg;
    }

    public NoLoginException(Integer code, String msg) {
        super(msg);
        this.code = code;
        this.msg = msg;
    }

    public Integer getCode() {

        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

/**
* service 层 处理异常
*/
@Service
public class IndexService {
    public void test(){
        if(1==1){
            throw new ParamsException("异常测试!");
        }
    }

    public void test2(){
        if(1==1){
            throw new NoLoginException();
        }
    }
}
2.全局异常处理方式二
@Component
public class GlobalException implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception ex) {
      /**
      * 第二种全局异常配置
      * */
        /* ModelAndView mv=new ModelAndView();
       mv.setViewName("error");
       mv.addObject("ex",ex);

       //判断参数异常
        if(ex instanceof ParamsException){
            ParamsException pe= (ParamsException) ex;
            mv.setViewName("param-error");
            mv.addObject("ex",pe.getMsg());
        }

        //判断是否登录异常
        if(ex instanceof NoLoginException){
            NoLoginException ne= (NoLoginException) ex;
            mv.setViewName("no-login-error");
            mv.addObject("ex",ne.getMsg());
        }
        return mv;*/

        //数据转换成json数据
        
        String result="{\"code\":300,\"msg\":\"默认错误\"}";
        PrintWriter pw=null;

        try {
            httpServletResponse.setContentType("application/json;charset=utf-8");
            httpServletResponse.setCharacterEncoding("utf-8");
            pw=httpServletResponse.getWriter();
            pw.write(result);
            pw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(null !=pw){
                pw.close();
            }

        }
        return null;
    }
}
3.全局异常处理方式三
/**
 * 注解异常配置 继承思想
 */
@Controller
public class BaeController {

    @ExceptionHandler(value = Exception.class)
    public ModelAndView resolveException(Exception ex)		{
        ModelAndView mv=new ModelAndView();
        mv.setViewName("error");
        mv.addObject("ex",ex);

        //判断参数异常
        if(ex instanceof ParamsException){
            ParamsException pe= (ParamsException) ex;
            mv.setViewName("param-error");
            mv.addObject("ex",pe.getMsg());
        }

        //判断是否登录异常
        if(ex instanceof NoLoginException){
            NoLoginException ne= (NoLoginException) ex;
            mv.setViewName("no-login-error");
            mv.addObject("ex",ne.getMsg());
        }

        return mv;
    }
}

@Controller
public class IndexController extends BaeController{

    @Resource
    private IndexService indexService;

    @RequestMapping("index")
    public String index(HttpServletRequest request){
        request.setAttribute("msg","hello ssm");
        //放入上下文路径/ssm
        request.setAttribute("ctx",request.getContextPath());
       // int i=1/0;
       indexService.test();
       indexService.test2();
        return "index";
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值