用Spring MVC取代Struts2作为视图层

本文介绍了如何使用Spring MVC替代Struts2作为视图层,详细讲解了Spring MVC的注解如@RequestMapping、@SessionAttributes、@ModelAttribute等的使用,以及Ajax交互、数据校验和格式化等内容,提供了丰富的示例和配置说明。
摘要由CSDN通过智能技术生成

SpringMVC

这里写图片描述
ViewResolver视图解析将逻辑视图名转换成物理视图;再调用render方法渲染视图返回给用户。

  1. 可以将任何一个java类当做控制器,只要标注@Controller
  2. 类里面返回值为String,表示返回的逻辑视图名,此时需要一个视图解析器来进行解析,需要在配置文件里配置该bean(InternalResourceViewResolver)
  3. DispacherServlet是核心控制器,用于处理请求,要在web.xml里面进行配置。

Spring MVC 标签

@RequestMapping

RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
RequestMapping注解有六个属性,下面我们把她分成三类进行说明。

  1. value, method;
    value: 指定请求的实际地址,指定的地址可以是URI Template 模式;
    method: 指定请求的method类型, GET、POST、PUT、DELETE等;

  2. consumes,produces
    consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
    produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;

  3. params,headers
    params: 指定request中必须包含某些参数值时,才让该方法处理。
    headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。

可以支持简单的操作,一定要有某属性或者没有某属性才能访问该函数。

@SessionAttributes

让同一个会话不同请求间可以共享数据。

@SessionAttributes即将值放到session作用域中,写在class上面。
此处的值必须是在模型数据里面,即request里面有的。
此外,可以通过模型里面的key值或者类型值将对象加到session中。用类型值的时候,比如types=[String.class],那么模型里面所有的String类型的数据都会保存到session中。

@ModelAttribute

主要用于对象合并,先从数据库里面取一遍(如修改时,把那些不能从表单中得到的信息从数据库拿出来),再进行绑定。
这里写图片描述
此处,注册时间无法修改,也无法通过前端获得,后端在用Hibernate时,更新那个user会把注册时间变成NULL,不合理。
@ModelAttribute可以修饰方法,使得他在所有业务方法之前执行,这样我们可以:
1. 先在那个方法里面获得对应的user,
2. 放到请求范围中

- 返回值为void,用map/model/modelmap手动放;
- 返回值为对应的类型(此时自动放到请求范围中,key值为类型名首字母小写,或者通过ModelAttribute的value属性设置)

3. 再将前端获得的数据“覆盖”原来的数据,而那个注册时间本来就有就不会覆盖了。
这里需要说明一下入参的绑定规则

入参绑定规则

首先在请求范围中查找指定key(POJO对应的类名首字母小写单词),如果是用ModelAttrubute修饰的入参,则按照指定key进行绑定。没找到就新建一个类放到请求范围中。

这里写图片描述

当@ModelAttribute修饰方法参数时,方法参数的实例来自于:

  • 它可能已经存在与模型中了,因为使用了@SessionAttributes — 见“使用@SessionAttributes存储模型属性到 HTTP 会话中”一节.
  • 它可能已经存在于模型中了,因为同一个控制器中的@ModelAttribute方法,就像上一节中解释的那样。
  • 它可能是从URI模板变量和类型转换器中获取的(下面会详细解释)。
  • 它可能是使用默认构造器初始化的。

@PathVariable

用于将请求URL中的模板变量映射到功能处理方法的参数上,即取出uri模板中的变量作为参数。

@requestParam

获取get 方式中queryString的值,也可以处理post方式中 body data的值。

@requestParam主要用于在SpringMVC后台控制层获取参数,类似一种是request.getParameter(“name”),它有三个常用参数:defaultValue = “0”, required = false, value = “isApp”;defaultValue 表示设置默认值,required 通过boolean设置是否是必须要传入的参数,value 值表示接受的传入的参数类型。

@ResponseBody

作用: 该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。通常用来返回JSON数据或者是XML数据,需要注意的呢,在使用此注解之后不会再走试图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。

更多参考:
https://blog.csdn.net/lovincc/article/details/72800117
https://www.cnblogs.com/leskang/p/5445698.html

ModelAndView/Model/ModelMap/Map

ModelAndView需要手动new,将待返回页面需要的信息通过addObject放进mv里面,再return mv。
addObject加进去的模型数据是放在request范围中的。

Model 、ModelMap 、Map都不用new,直接在方法参数里面就行,Spring MVC会自动将已经创建好的模型引用赋给他们。然后方法里面直接addAttribute进需要的信息,也不需要去return model,直接在页面通过EL表达式就可以获取,因为是引用,函数里面的所有操作都是全局性的,实际request范围里面也会增加。

此外,这三者本质上一样,只是使用的API不同,一般用Map就行:

public ModelAndView returnJson(Model model, Map map, ModelMap modelmap) {
  ...断点...}

这里写图片描述

Ajax交互

这里写图片描述

如果AJAX发送数组,而入参是List,则不支持直接绑定了,需要用到@RequestBody,需要在传到后端时指定数据类型是json字符串。

若干示例

package com.springmvc.controller;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.springmvc.entity.Address;
import com.springmvc.entity.UserInfo;
import com.springmvc.entity.UserInfoMap;
@SessionAttributes(value={
  "userInfo"})
@RequestMapping("/springmvc")
@Controller
public class SpringMVCHandler {
   

    @RequestMapping("/helloWorld")
    public String sayHello() {
        System.out.println("Hello World");
        return "success";
    }

    /**
     * 使用@RequestMapping注解的method属性指定请求方式
     */
    @RequestMapping(value = "/requestMethod", method = RequestMethod.POST)
    public String requestMethod() {
        System.out.println("Request Method");
        return "success";
    }

    /**
     * Ant风格的URL路径映射
     */
    @RequestMapping("/*/pathAnt")
    public String pathAnt() {
        System.out.println("Path Ant");
        return "success";
    }

    /**
     * 使用@PathVariable注解映射URL中的占位符到目标方法的参数中
     * 
     */
    @RequestMapping("/pathVariable/{id}")
    public String pathVariable(@PathVariable("id") Integer id) {
        System.out.println("Path Variable:" + id);
        return "success";
    }

    /**
     * 使用@RequestParam注解绑定请求参数到控制器方法参数,与前端中name属性的值对应,
     * 如果形参名字和一致请求参数名字一样,就不用标注@resquestParam
     */
    @RequestMapping("/requestParam")
    public String requestParam(
            @RequestParam(value = "userName") String userName,
            @RequestParam(value = "password") String password) {
        System.out.println("Request Param:" + userName + " " + password);
        return "success";
    }

    /**
     * 将请求参数绑定到控制器方法的表单对象POJO,要名字一样才能绑定,可以支持级联属性,如UserInfo多了一个属性为address(类,包含city和street),则在前端表单中street需指定name属性为"address.street"
     */
    @RequestMapping("/saveUserInfo")
    public String saveUserInfo(UserInfo ui) {
        System.out.println(ui);
        return "success";
    }


    /**
     * 将请求参数绑定到控制器方法的Map对象
     */
    @RequestMapping("/getUserInfos")
    public String getUserInfos(UserInfoMap uiMap) {
        Set set=uiMap.getUiMap().keySet();
        Iterator iterator=set.iterator();       
        while(iterator.hasNext()){
            Object keyName=iterator.next();
            UserIn
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值