SpringMVC

spring mvc

用来开发基于 web 的应用程序

1. 流行的 mvc 框架

  • struts 1.x
  • webwork
  • struts 2.x (webwork+struts 1.x) ssh 经常暴露安全问题
  • springmvc 更容易上手,相对更安全

2. mvc 思想

model 模型 - 数据 domain
view 视图 - 数据的展现方式 jsp, jstl, el
controller 控制器 - 结合模型和视图,控制请求流程 servlet, controller

servlet 如果作为控制器
缺点1:请求参数处理麻烦 String 值 = request.getParameter(“参数名”)
缺点2:当业务比较多时,servlet 类的数量膨胀不好管理
controller 优点
优点:利用spring 各种思想,ioc, di, aop, 可扩展性高

3. spring mvc 使用步骤

  1. 添加jar依赖
<!-- spring mvc 依赖 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.3.21.RELEASE</version>
</dependency>

<!-- servlet, jsp, 标签库 -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>2.2.1</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>jstl</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
  1. 添加 spring 配置文件
<?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           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/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.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

	<!-- 启用了 与 springmvc 相关的注解      
	    @RestController
	    @RequestMapping
	    @ResponseBody
	    @ExceptionHandler
    ...
    -->
    <mvc:annotation-driven />
  1. 添加控制器
  • spring 提供的前控制器(实际是一个servlet),作为一个统一入口,由它来分发请求,进入真正的控制器
    需要使用 web.xml 文件配置它的路径
<!-- 配置前控制器 (servlet) -->
<servlet>
    <servlet-name>aa</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!-- 指明 spring 配置文件的位置, 根据它创建 spring容器 -->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <!-- tomcat 启动时, 就创建和初始化 servlet, 同时创建 spring 容器 -->
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>aa</servlet-name>
    <!-- / 用来匹配所有的路径 -->
    <url-pattern>/</url-pattern>
</servlet-mapping>
  • 自己提供的控制器
@Controller
public class 控制器类 {

    @RequestMapping("请求路径") // 请求路径要唯一
    public String 方法1() {

    }

    ...

    @RequestMapping("请求路径")
    public String 方法n() {
        
    }

}
  1. 配置视图
    控制器方法的返回值是一个视图名,此视图名经过视图解析器解析为一个完整路径,利用请求转发跳转至该jsp
<mvc:view-resolvers>
    <!-- 前缀 + 视图名 + 后缀 ==  完整路径, 再利用请求转发跳转至 jsp -->
    <mvc:jsp prefix="/" suffix=".jsp" />
</mvc:view-resolvers>
  1. 处理请求参数

方法1: 只要把方法的参数名称和请求的参数名称对象,springmvc 会将请求参数的值赋值给方法参数,并完成类型转换
日期类型需要特殊处理,请求参数类型转换出错,会出现400错误, 日期可以使用 @DateTimeFormat(pattern=“日期格式”)

 @RequestMapping("/c1")
    public String a1(String name, Integer age,@DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday) {
        System.out.println("执行了 a1 方法: name:" + name + " age:" + age + " birthday:" + birthday);
         // 返回值代表视图的名字,但要注意它不是完整路径
        // /hello.jsp
        return "hello";
         // 没有经过视图解析器,直接转发进行了跳转
        return "forward:/hello.jsp";
    }

方法2:当请求参数较多时,可以把请求参数映射到java对象的属性上

class User{
    private String name;
    private Integer age;
    private Date birthday;
}
 @RequestMapping("/c3")
    public String c3(User user) {
        System.out.println(user);
        return "hello";
    }

方法3:把参数信息包含在路径当中
删除用户

/deleteUser?id=1
/deleteUser?id=2

/deleteUser/1 删除1号用户
/deleteUser/2 删除2号用户

// 例如 /deleteUser/1  {id} 的值就是1 /deleteUser/2  {id} 的值就是2
@RequestMapping("/deleteUser/{id}")
// @PathVariable 获取一个路径变量的值{id}, 然后复制给方法参数
public String c4(@PathVariable("id") int aa) {
    System.out.println("值为:" + aa);
    return "hello";
}
  1. 处理模型数据
    Model接口, 需要调用Model 的相关方法把数据存入模型,页面上再从模型中获取数据并显示
 @RequestMapping("/c5")
    public String c5(Model model) {
        model.addAttribute("name", "张三");
        model.addAttribute("list", Arrays.asList("苹果","草莓","橘子"));
        return "model";
    }

${名字} <c:forEach>

原理:会把模型中数据放入request作用域

=========================================================

1. 汉字乱码

在 web.xml 中添加一个 spring 提供的 CharacterEncodingFilter

<!-- 配置字符编码过滤器  -->
<filter>
    <filter-name>bb</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>bb</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

2. 使用传统 servlet 中的类

HttpServletRequest, HttpServletResponse, HttpSession 他们都可以作为控制器方法的参数,直接使用即可,spring会把他们准备好

 @RequestMapping("/s1")
    public String s1(HttpServletRequest request,
                     HttpServletResponse response,
                     HttpSession session) {
        session.setAttribute("name", "老王");
        return "servlet";
    }

3. 异常处理

局部的异常处理器,只针对某个控制器

// 专门定义一个处理异常的方法
// ArrayIndexOutOfBoundsException
@ExceptionHandler(Exception.class) // 异常处理器, 可以指定具体的异常类型
public String error(Exception e) {
    System.out.println("进入了 ExceptionController error " + e.getMessage());
    return "error";
}

全局的异常处理器,针对所有的控制器

@ControllerAdvice
class 全局异常处理器类 {

    @ExceptionHandler(异常类型)
    public String error(异常对象) {
        // 异常处理
        return "视图名";
    }
}

局部的异常处理优先级高于全局的异常处理

4. 文件上传

  1. pom.xml添加依赖
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
</dependency>
  1. springmvc.xml 中对上传文件表单做特殊配置

简单表单
name=zhangsan&age=18

上传文件表单
multipartResovler 上传文件表单的解析器


    <!-- 配置上传文件表单解析器, id 是固定的 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 限制上传文件的总大小,单位是字节-->
        <property name="maxUploadSize" value="2000"></property>
    </bean>
  1. 编辑表单页面
<!-- multipart/form-data 表示表单数据由多部分,属于复杂的表单格式 -->
<form action="请求地址" method="post" enctype="multipart/form-data">
    <!-- 文件选择框 -->
    <input type="file" name="请求参数名">
</form>
  1. 编写控制器
@Controller
public class UploadController {

    @RequestMapping("/upload")
    public String upload(String username,
                         Integer age,
                         MultipartFile image) throws IOException {
        System.out.println("上传文件的原始名称:" + image.getOriginalFilename());
        System.out.println("上传文件的类型:" + image.getContentType());
        System.out.println("获取上传文件大小:" + image.getSize());

        // 生成了临时文件, 当请求结束, 此临时文件会被删除
        // 把临时文件另存为: file
        image.transferTo(new File("d:\\" + image.getOriginalFilename()));
        return "hello";
    }
}
  1. 图片预览
    通过js完成
<input type="file" name="image" id="image" onchange="preview()">

<img src="" id="preview"/>
function preview() {
    // 获取图片选择框中图片的二进制信息
    var image = document.getElementById("image");
    var file = image.files[0]; // 拿到数组中第一个图片文件

    // 读取文件内容
    var reader = new FileReader();
    // 定义事件
    reader.onload = function() {
        // 获取结果
        document.getElementById("preview").src = this.result;
    };
    // 开始读取
    reader.readAsDataURL(file);
}
  1. 对上传文件的控制
    从客户端的角度限制

服务器端要对上传文件做检查
图片,修改大小 800x600 -> 640x480 成功
假图片,修改大小 800x600 -> 640x480 报异常

文件大小限制

<!-- 配置上传文件表单解析器, id 是固定的 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 限制上传文件的总大小,单位是字节-->
    <property name="maxUploadSize" value="2000"></property>
</bean>
  1. springmvc 对静态文件的处理(图片,html,js,css)
    springmvc 默认把所有路径都当做了 控制器 的路径
    在springmvc.xml中设置
 <!-- 对静态资源的处理, 不要把静态资源的路径当做 controller 的路径-->
    <mvc:default-servlet-handler/>

5. spring 中的拦截器

请求到达控制器之前,先经过拦截器,才到达控制器

Filter 过滤器接口
HandlerInterceptor 拦截器接口

  1. 编写拦截器
@Component
public class Interceptor1 implements HandlerInterceptor {

    // 在控制器方法执行前被调用, 返回 true 放行请求, 如果返回 false 拦截请求(不会前进了)
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("==========> 进入了 Interceptor1 preHandle");
        return true;
    }

    // 在控制器方法执行后被调用
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("==========> 进入了 Interceptor1 postHandle");
    }

    // 在控制器和视图都完成后被调用
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("==========> 进入了 Interceptor1 afterCompletion");
    }
}
  1. 配置拦截器
<!-- 某个拦截器 -->
<mvc:interceptor>
    <!-- 拦截器要匹配的路径 -->
    <mvc:mapping path="/hello" />

    <!-- 要调用的拦截器 -->
    <ref bean="interceptor1"/>
</mvc:interceptor>

6. 对 json 数据的支持

var xhr = new XMLHttpRequest(); 可以在页面不刷新的情况下与服务器进行交互

xhr.onload = function() {
    var json = xhr.responseText;
    JSON.parse(json); // 把json字符串转为 js 对象
};

xhr.open("get|post", url, true|false);
xhr.send();

6.1 @ResponseBody 注解

加在控制器方法上,将控制器方法的返回结果转换为json字符串,并写入响应

6.2 @RestController 注解

加在控制器类上,表示所有控制器方法都加了 @ResponseBody 注解

6.3 其他注解

@RequestMapping // 不区分 get,post

@GetMapping // 专门匹配 get 请求 等价于 @RequestMapping(method=RequestMethod.GET)
@PostMappping // 专门匹配 post 请求
@DeleteMapping // 专门匹配 delete 请求
@PutMapping // 专门匹配 put 请求

get 一般对应查询操作 select
post 一般对应新增操作 insert
delete 对应删除操作 delete
put 对应修改操作 update

6.4 @RequestBody

把请求中的json 字符串,转换为java 对象
服务器端代码:

@PostMapping("/json4")
// @RequestBody 作用是把请求体中的 json 字符串,转为 java 中的对象
public void json4(@RequestBody Student student) {
    System.out.println(student);
    System.out.println("ok");
}

客户端代码:

function sendStudent() {
    var student = {"id": 2, "name":"李四"}; // {id: 2, name:"李四"}
    var xhr = new XMLHttpRequest();
    xhr.open("post", "/json4", true);
    // 设置请求体的格式为 json 格式
    xhr.setRequestHeader("content-type", "application/json");

    // 将 js 对象 转为为 json 字符串, 并作为请求体, 发送给服务器
    xhr.send( JSON.stringify(student) );
}

6.5 ajax 请求跨域(源)

两个应用程序,ip 地址不一样或是端口号不一样,就称之为跨域

localhost:8080 提供控制器,返回json数据, 通过 cors 的技术运行其他域的机器访问我的数据
@CrossOrigin(“允许访问我的数据的ip地址”)

@CrossOrigin("http://192.168.9.3") // 只允许9.3 访问
@CrossOrigin("http://192.168.9.3,http://192.168.9.4,http://192.168.9.5") //允许多个ip访问
@CrossOrigin("*") // 允许所有域访问

可以加在方法上,表示只有此方法允许跨域
还可以加在控制器类上,表示此控制器中的所有方法都允许跨域

localhost:9090 ajax 获取 localhost:8080 的json数据, 默认情况没有权限访问

7. 重定向请求

@RequestMapping("/test1")
public String test1() {
    // 重定向到 /test2 控制器
    return "redirect:/test2";
}

@RequestMapping("/test2")
public void test2() {
    //...
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。在编写C程序时,需要注意变量的声明和定义、指针的使用、内存的分配与释放等问题。C语言中常用的数据结构包括: 1. 数组:一种存储同类型数据的结构,可以进行索引访问和修改。 2. 链表:一种存储不同类型数据的结构,每个节点包含数据和指向下一个节点的指针。 3. 栈:一种后进先出(LIFO)的数据结构,可以通过压入(push)和弹出(pop)操作进行数据的存储和取出。 4. 队列:一种先进先出(FIFO)的数据结构,可以通过入队(enqueue)和出队(dequeue)操作进行数据的存储和取出。 5. 树:一种存储具有父子关系的数据结构,可以通过中序遍历、前序遍历和后序遍历等方式进行数据的访问和修改。 6. 图:一种存储具有节点和边关系的数据结构,可以通过广度优先搜索、深度优先搜索等方式进行数据的访问和修改。 这些数据结构在C语言中都有相应的实现方式,可以应用于各种不同的场景。C语言中的各种数据结构都有其优缺点,下面列举一些常见的数据结构的优缺点: 数组: 优点:访问和修改元素的速度非常快,适用于需要频繁读取和修改数据的场合。 缺点:数组的长度是固定的,不适合存储大小不固定的动态数据,另外数组在内存中是连续分配的,当数组较大时可能会导致内存碎片化。 链表: 优点:可以方便地插入和删除元素,适用于需要频繁插入和删除数据的场合。 缺点:访问和修改元素的速度相对较慢,因为需要遍历链表找到指定的节点。 栈: 优点:后进先出(LIFO)的特性使得栈在处理递归和括号匹配等问题时非常方便。 缺点:栈的空间有限,当数据量较大时可能会导致栈溢出。 队列: 优点:先进先出(FIFO)的特性使得
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值