ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

SpirngMVC 学习笔记

2021-02-25 18:06:02  阅读:121  来源: 互联网

标签:String System 笔记 学习 user println public SpirngMVC out


基本概念

DispatcherServlet
SpringMVC核心控制器(前端控制器):主要是用来分发请求的

HandlerMapping
映射处理器:根据请求的URL来映射查找到对应的Handler
Handler就是Controller层的实现类

HandlerAdapter
适配器:用来适配不同的处理器Handler
处理器有两种实现方式:实现接口、基于注解,所以执行前需要先适配

Handler
处理器:真正用来处理和执行业务,并产生数据模型Model和视图View,
Handler会将Model和View封装成ModelAndView对象并返回。

ViewResolver
视图解析器:根据视图名称解析成具体的视图,一般多为jsp页面,然后把它封装成View对象并返回。

View
视图:使用具体的视图技术进行渲染,结合Model进行数据展示。
视图有很多种形式:jsp、freemarker、velocity、excel、pdf等。

入门案例

流程分析

image-20210221094732245

配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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">
    <display-name>Archetype Created Web Application</display-name>

    <!--配置前端控制器-->
    <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:springmvc.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>

    <!--配置解决中文乱码的过滤器-->
    <filter>
        <filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

配置springmvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       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
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 开启注解扫描 HelloController 生效 -->
    <context:component-scan base-package="cn.demo"/>

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


    <!-- 开启SpringMVC框架注解的支持 @RequestMapping 生效 -->
    <mvc:annotation-driven/>

</beans>

编写 HelloController.java

package cn.demo.controller;


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

// 控制器类
@Controller
public class HelloController {

    @RequestMapping(path="/hello")
    public String sayHello(){
        System.out.println("Hello StringMVC");
        // 找试图解析器
        return "success";
    }
}

编写前端页面

index.jsp
<a href="hello">hello</a>
success.jsp
<h3>入门成功</h3>

${ msg }

@RequestMapping 详解

可作用与方法上和类上
value:用于指定请求的URL。它和path属性的作用是一样的。
method:用于指定请求的方式。
params:用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的key和value必须和配置的一模一样。

@RequestMapping(path = "/testrequestmapping", method = RequestMethod.GET,
        params = {"username=20"}, headers = "Accept")
public String testRequestMapping() {
    System.out.println("testRequestMapping");
    return "success";
}

请求参数的绑定

使用 get 传递参数

要求参数名与方法的参数名相同才能成功封装

@RequestMapping("/testparam")
public String testParam(String username, String passwd) {
    System.out.println(username +"::"+ passwd);
    return "success";
}

绑定实体类

@RequestMapping("/saveuser")
public String savaUser(User user) {
    System.out.println(user);
    System.out.println(user.getPet());
    return "success";
}
<form action="param/saveuser" method="post" name="svaeuser">
    用户名<input type="text" name="username"></br>
    密码<input type="text" name="password"></br>
    宠物名<input type="text" name="pet.petname"></br>
    宠物年龄<input type="text" name="pet.age"></br>
    <input type="submit" value="submit"></br>
</form>

中文乱码过滤器

<!--配置解决中文乱码的过滤器-->
<filter>
    <filter-name>characterEncodingFilter</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>

绑定集合类型

<form action="param/saveuser" method="post" name="svaeuser">
    用户名<input type="text" name="username"></br>
    密码<input type="text" name="password"></br>

    宠物名<input type="text" name="list[0].petname"></br>
    宠物年龄<input type="text" name="list[0].age"></br>

    字段1<input type="text" name="map['one']]">
    字段2<input type="text" name="map['two']]">

    <input type="submit" value="submit"></br>
</form>

自定义类型转换器

解决日期格式转换

编写转换器类

public class StringToDateConverter implements Converter<String, Date> {
    @Override
    public Date convert(String source) {

        if (source == null) {
            throw new RuntimeException("请传入数据");
        }
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");

        try {
            return df.parse(source);
        } catch (ParseException e) {
            throw new RuntimeException("数据转换出错");
        }
    }
}

配置springmvc.xml

<!--自定义类型转换器-->
<bean id="conversionServiceFactoryBean"
      class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="cn.demo.utils.StringToDateConverter"></bean>
        </set>
    </property>
</bean>

获取Servlet的原生API

@RequestMapping("/testservlet")
public String testServlet(HttpServletRequest request, HttpServletResponse response) {
    System.out.println(request);
    System.out.println(request.getSession());
    System.out.println(response.getContentType());
    return "success";
}

常用注解

@RequestParam

作用:把请求中的指定名称的参数传递给控制器中的形参赋值

属性:

  • value 请求参数中的名称

  • required 请求参数中是否必须提供此参数,默认值是true,必须提供

示例:

@RequestMapping("requestparam")
public String testRequestParam(@RequestParam(name = "name", required = false) String username) {
    System.out.println(username);
    return "success";
}
<a href="anno/requestparam?username=周杰伦">requestparam</a>

@RequestBody

作用:用于获取请求体的内容(注意:get方法不可以)

属性:

  • required 是否必须有请求体,默认值是true

示例:

@RequestMapping("/requestbody")
public String testRequestBody(@RequestBody String body) {
    System.out.println(body);
    return "success";
}
<form method="post" action="/anno/requestbody">
    <input name="username" type="text">
    <br>
    <input name="password" type="password">
    <input value="submit" type="submit">
</form>

@PathVariable

作用:拥有绑定url中的占位符的。例如:url中有/delete/{id},{id}就是占位符

属性:

  • value:指定url中的占位符名称

示例:

GET http://localhost:8080/demo1/anno/user/1

@RequestMapping(path = "/user/{id}")
public String testPathVariable(@PathVariable(value = "id") String id) {
    System.out.println(id);
    return "success";
}

HiddentHttpMethodFilter

用隐藏域发PUT请求

@RequestHeader

作用:用于获取消息请求头

属性:

  • value:如Accept

示例:

@RequestMapping(path = "/getrequestheader")
public String testRequestHeader(@RequestHeader (value = "Accept") String header) {
    System.out.println(header);
    return "success";
}

@CookieValue

作用:用于获取cookie的值

示例:

@RequestMapping("/getcookie")
public String testCookieValue(@CookieValue(value = "JSESSIONID") String value) {
    System.out.println(value);
    return "success";
}

@ModelAttribute

作用:

  • 出现在方法上:表示当前方法会在控制器方法执行前线执行。
  • 出现在参数上:获取指定的数据给参数赋值

场景:

  • 当提交表单数据不是完整的实体数据时,保证没有提交的字段使用数据库原来的数据
  • 只修改未提交的参数

示例1:

@RequestMapping("setuser")
public String testModelAttribute(User user) {
    System.out.println(user);
    return "success";
}

@ModelAttribute
public User showUser(String username) {
    System.out.println("showUser 执行了。。。");
    User user = new User();
    user.setUsername(username);
    user.setPassword("passwd");
    return user;
}

示例2:

@RequestMapping("setuser2")
public String testModelAttribute2(@ModelAttribute(value = "abc") User user) {
    System.out.println(user);
    return "success";
}

@ModelAttribute
public void showUser2(String username, Map<String, User> map) {
    System.out.println("showUser 执行了。。。");
    User user = new User();
    user.setUsername(username);
    user.setPassword("passwd");
    map.put("abc", user);
}

@SessionAttribute

作用:用于多次执行控制器方法间的参数共享

属性:value:指定存入属性的名称

示例:

@Controller
@RequestMapping("/anno")
@SessionAttributes(value = {"username", "password", "age"}, types = {String.class, Integer.class})
public class AnnoController {

    @RequestMapping("/save")
    public String save(Model model) {
        System.out.println("向Session中保存数据");
        model.addAttribute("username", "周杰伦");
        model.addAttribute("password", "abc123");
        model.addAttribute("age", 100);
        return "success";
    }

    @RequestMapping("/find")
    public String find(ModelMap modelMap) {
        String username = (String) modelMap.getAttribute("username");
        String password = (String) modelMap.getAttribute("password");
        Integer age = (Integer) modelMap.getAttribute("age");
        System.out.println(username);
        System.out.println(password);
        System.out.println(age);
        return "success";
    }

    @RequestMapping("/del")
    public String delete(SessionStatus status) {
        status.setComplete();
        return "success";
    }

响应数据和结果视图

返回字符串

@RequestMapping("/testString")
public String testString(Model model) {
    System.out.println("testString 执行了");
    User user = new User();
    user.setUsername("周杰伦");
    user.setPassword("zjl123");
    model.addAttribute("Jay", user);
    return "info";
}
info.jsp
${Jay.username}
${Jay.password}

返回 void

  • 默认情况下,执行完方法后,跳转到 方法名.jsp

    404 消息:文.件[/WEB-INF/pages/user/testVoid.jsp] 未找到

  • 编写请求转发的程序

    @RequestMapping("/testVoid")
    public void testVoid(
    	HttpServletRequest request, HttpServletResponse response) 
    	throws Exception {
        System.out.println("testVoid 执行了");
        request.getRequestDispatcher("/WEB-INF/pages/success.jsp").
        forward(request, response);
    }
    
  • 重定向

    response.sendRedirect(request.getContextPath()+"/index.jsp");
    
  • 设置中文乱码

    response.setCharacterEncoding("UTF-8");
    response.setContentType("text/html;charset=UTF-8");
    
  • 直接会进行响应

    response.getWriter().print("你好");
    

返回 ModelAndView

ModelAndView对象是Spring提供的一个对象,可以用来调整具体的JSP视图

示例:

@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView() {
    System.out.println("testModelAndView 执行了");

    ModelAndView mv = new ModelAndView();
    User user = new User();
    user.setUsername("周杰伦");
    user.setPassword("zjl123");
    mv.addObject("Jay", user);
    mv.setViewName("success");
    return mv;
}

使用关键字转发和重定向

示例:

@RequestMapping("/testRedirectAndForward9")
public String testRedirectAndForward() {
    System.out.println("testRedirectAndForward9 执行了");
//        return "redirect:index.jsp";
    return "forward:testString";
}

@ResponseBody

响应 JSON 数据

DispatcherServlet会拦截到所有的资源,导致一个问题就是静态资源(img、css、js)也会被拦截到,从而
不能被使用。解决问题就是需要配置静态资源不进行拦截,在springmvc.xml配置文件添加如下配置

属性:

  • mvc:resources标签配置不过滤

  • location元素表示webapp目录下的包下的所有文件

  • mapping元素表示以/static开头的所有请求路径,如/static/a 或者/static/a/b

示例:springmvc.xml

<!-- 设置静态资源不过滤 -->
<mvc:resources location="/css/" mapping="/css/**"/> <!-- 样式 -->
<mvc:resources location="/images/" mapping="/images/**"/> <!-- 图片 -->
<mvc:resources location="/js/" mapping="/js/**"/> <!-- javascript -->

导入 json api

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.4</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.11.4</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.11.4</version>
</dependency>

使用@RequestBody获取请求体数据

前端代码

$(function () {
    $('#btn').click(function () {
        $.ajax({
            url: "user/saveUser",
            contentType: "application/json;charset=UTF-8",
            data: '{"username":"周杰伦111", "password":"123"}',
            dataType: "json",
            type: "post",
            success: function (data, status) {
                console.log(data.toString())
                console.log(status)
            }
        })
    })
})

java代码

// 配置跨域请求
@CrossOrigin(origins = {"http://127.0.0.1:5500", "null"})
public class UserController implements Serializable {}

@RequestMapping("/saveUser")
public @ResponseBody User saveUser(@RequestBody User user) {
    System.out.println("saveUser 执行了");
    System.out.println(user);
    user.setUsername("周杰伦333");
    System.out.println(user);
    return user;
}

文件上传

导入依赖

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>

前端代码

<form action="file/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="upload"><br>
    <input type="submit" value="上传文件">
</form>

传统方式(失败)

@RequestMapping("upload")
public String uploadFile(HttpServletRequest request) throws Exception {
    System.out.println("文件上传。。。");

    // 获取要上传的文件目录
    String path = request.getSession().getServletContext().getRealPath("/uploads/");
    File file = new File(path);
    if (!file.exists()) {
        file.mkdirs();
        System.out.println("创建文件夹:成功");
    }

    // 创建磁盘文件项工厂
    DiskFileItemFactory factory = new DiskFileItemFactory();
    ServletFileUpload upload = new ServletFileUpload(factory);
    // 解析 request 对象
    List<FileItem> items = upload.parseRequest(request);
    System.out.println(items);


    for (FileItem item : items) {
        if (item.isFormField()) {

        } else {
            String filename = item.getName();
            String uuid = UUID.randomUUID().toString().replace("-", "");
            filename = uuid + "_" + filename;

            System.out.println("filename: " + filename);

            item.write(new File(path, filename));
            item.delete();
        }
    }

    return "success";
}

springmvc 方式

配置文件解析器对象: springmvc.xml

<!--配置文件解析器对象-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="10485760" />
</bean>
@RequestMapping("upload")
public String uploadFile(HttpServletRequest request, MultipartFile upload) throws Exception {
    System.out.println("文件上传。。。");

    // 获取要上传的文件目录
    String path = request.getSession().getServletContext().getRealPath("/uploads/");
    File file = new File(path);
    if (!file.exists()) {
        file.mkdirs();
        System.out.println("创建文件夹:成功");
    }

    String filename = upload.getOriginalFilename();
    String uuid = UUID.randomUUID().toString().replace("-", "");
    filename = uuid + "_" + filename;

    upload.transferTo(new File(path, filename));
    return "success";

}

springmvc 跨服务器

导入依赖

<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.18.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.18.1</version>
</dependency>

业务代码

@RequestMapping("upload1")
public String fileuoload3(MultipartFile upload) throws Exception {
    System.out.println("跨服务器文件上传...");

    // 定义上传文件服务器路径
    String path = "http://localhost:9090/uploads/";

    // 说明上传文件项
    // 获取上传文件的名称
    String filename = upload.getOriginalFilename();
    // 把文件的名称设置唯一值,uuid
    String uuid = UUID.randomUUID().toString().replace("-", "");
    filename = uuid+"_"+filename;

    // 创建客户端的对象
    Client client = Client.create();

    // 和图片服务器进行连接
    WebResource webResource = client.resource(path + filename);

    // 上传文件
    webResource.put(upload.getBytes());

    return "success";
}

异常处理

编写自定义异常类

package cn.demo.exception;

import lombok.Data;

public class SysException extends Exception{
    private String message;

    public SysException(String message) {
        super(message);
    }

    @Override
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

编写异常处理器

package cn.demo.exception;

import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SysExceptionResolver implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(
            HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex) {

        SysException e = null;
        if (e instanceof SysException) {
            e = (SysException) ex;
        } else {
            e = new SysException("系统正在维护中。。。");
        }

        ModelAndView view = new ModelAndView();
        view.addObject("errorMsg" + e.getMessage());
        view.setViewName("error");

        return view;
    }
}

配置异常处理器

springmvc.xml

<!--配置异常处理器-->
<bean class="cn.demo.exception.SysExceptionResolver" id="sysExceptionResolver"></bean>

拦截器

概述

  1. **SpringMVC框架中的拦截器用于对处理器进行预处理和后处理的技术。
  2. 可以定义拦截器链,连接器链就是将拦截器按着一定的顺序结成一条链,在访问被拦截的方法时,拦截器链
    中的拦截器会按着定义的顺序执行。
  3. 拦截器和过滤器的功能比较类似,有区别
  4. 过滤器是Servlet规范的一部分,任何框架都可以使用过滤器技术。
  5. 拦截器是SpringMVC框架独有的。
  6. 过滤器配置了/*,可以拦截任何资源。
  7. **拦截器只会对控制器中的方法进行拦截。
  8. **拦截器也是AOP思想的一种实现方式
  9. **想要自定义拦截器,需要实现HandlerInterceptor接口

实现拦截器

实现 HandlerInterceptor 接口

public class MyInterceptor implements HandlerInterceptor {

    /**
     * controller 执行前执行此方法
     * 返回值 true 放行 false 拦截
     */
    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器执行了。。。");
        request.getRequestDispatcher("/WEB-INF/pages/error.jsp").forward(request, response);
        return true;
    }
}

配置 springmvc.xml

<mvc:interceptors>
    <mvc:interceptor>
        <!--拦截-->
        <mvc:mapping path="/exception/*"/>
        <!--不拦截
        <mvc:exclude-mapping path=""/>  -->
        <bean class="cn.demo.interceptor.MyInterceptor" id="myInterceptor"></bean>
    </mvc:interceptor>
</mvc:interceptors>

ssm 整合

环境搭建(xml & 注解)

标签:String,System,笔记,学习,user,println,public,SpirngMVC,out
来源: https://www.cnblogs.com/alohaaukake/p/14448388.html

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

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

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

ICode9版权所有