vlambda博客
学习文章列表

Web前端基础&JSON数据交互&表单标签库与数据绑定:大魏Java记20

jquery参考文献:https://cloud.tencent.com/developer/news/107298

参考图书《SpringBoot从入门到实战》


一、Web资源分类

我们将放在Internet上供外界访问的文件或者程序成为Web资源,根据呈现结果不同,“传统方法”分为:

  • 静态资源:Html、CSS、JPG

  • 动态资源:JSP、Servlet


在Web前端的开发中,动态页面的实现很重要。以前主要采用JSP/Servlet的方式,现在更多的采用动态HTML的方式。这两种方式的本质区别是:

JSP的动态效果实现,是由服务器端的程序实现的。而动态HTML,是浏览器侧执行脚本实现的。


二、Web前端三剑客

那么,HTML、CSS、JavaScript三者是什么关系呢?

Web前端三剑客:HTML、CSS、JavaScript,它们看上去是三种不同的技术,但在实际中却是相互搭配使用的。

HTML是用来标记内容的(重在内容组织上)。HTML是超文本标记语言的简称,它是一种不严谨的、简单的标识性语言。它用各种标签将页面中的元素组织起来,告诉浏览器该如何显示其中的内容。为什么说HTML是不严谨的呢?因为HTML标签即使不闭合,也并不会影响页面内容的组织。

CSS是用来修饰内容样式的(重在内容样式美化展示上)。CSS是层叠样式表的简称,它用来表现HTML文件样式的,简单说就是负责HTML页面中元素的展现及排版。

JavaScript是用来做交互的:JavaScript是一种脚本语言,既可以运行在客户端也能运行在服务器端。JavaScript的解释器就是JS引擎,JS引擎是浏览器的一部分。而JavaScript主要是用来扩展文档交互能力的,使静态的HTML具有一定的交互行为(比如表单提交、动画特效、弹窗等)。

HTML与CSS及JS三者99%的情况下都是搭配使用的,但也不是绝对的,具体关系是:

  • HTML与CSS、JS是不同的技术,可以独立存在;

  • HTML一般需要CSS和JS来配合使用,否则单一HTML文档无论是功能还是展示上效果都不理想;

  • CSS一般是不能脱离HTML或XML的,如果CSS脱离了HTML和XML,那就没有存在的必要的;

  • JS可以脱离HTML和CSS而独立存在;

  • JS可以操作HTML和CSS。

总结:如果把HTML比做身体,那CSS就好比是衣服,而JavaScript则意味着人能做的一些高级动作。


三、JavaScript、AJAXjQuery、AngularJS的解释与区别

接下来,我们对JavaScript进行更为详细的解释。

JavaScript

JavaScript是一种编程语言,这个语言是用在 web 浏览器上;这就是说,当你要设计一个Web 页面时,就要用到JavaScript了。如果要抠字眼的话,JavaScript是个什么东西呢?它是Java吗?当然不是,它与Java没有半毛钱的关系;既然带有Script,那么,它是脚本语言吗?当然不是,JavaScript同样是一种面向对象的编程语言。

对JavaScript的理解,切不可望文生义!因为它的名字,容易把你带到沟里去。

JavaScript是一门功能完整的编程语言,注意:JavaScript是运行在浏览器上的, 比如:Chrome 、 Firefox、 IE 浏览器等。JavaScript用来操作浏览器上的元素, 整个浏览器就是一个DOM树 (Document Object Model)文档对象模型。

JavaScript在哪儿运行呢?具体来说,是运行在浏览器的客户端;那么JavaScript代码存在在什么地方呢?它存放在后台服务器上,这个服务器称之为 web sever;web server 把JavaScript发送到用户的浏览器上,浏览器是个极为强大的东西,它能够识别JavaScript代码,这个识别的过程就是对JavaScript的解释,解释完了,开始运行JavaScript代码。这一切都发生在一个沙盒(sandbox)中,从而确保JavaScript不会改变浏览器内核,也不会获取电脑系统偏底层的东西。


AJAX

AJAX是 “Asynchronous JavaScript andXML“, 的简称。我们知道,网页的内容是动态发生变化的,这些变化的数据从哪里来的呢?当然是来自Web sever;XML 是一种标记语言,早期的网页与Web server 的数据交互格式是 XML;而今天是JSON(“JavaScript Object Notation”) 的天下了。JSON 越来越受欢迎。从 JSON 的名字就能看出来, JSON 是 “JavaScript Object Notation” 的缩写,这就是说,JSON 与 JavaScript 的关系更有渊源。JavaScript 解析 JSON 数据结构,更加简洁、易用!

自从有了 jQuery, AJAX 越来越边缘化了。


jQuery

jQuery是一个 JavaScript 库,为什么有JavaScript 库呢?按说,JavaScript 自身也有很多函数,问题是,直接用这些函数有些麻烦。上面提到这么多家的浏览器, 自家都说自家的好,这可害苦了开发者, 有的 JavaScript 函数在一个浏览器上表现好好的,换为另一个浏览器就不好使了。jQuery的强大之处在于:它解决了浏览器的兼容问题,对程序员来说,这是一件幸事,所以,jQuery 受到热捧。

既然 jQuery 是 JavaScript库, 在调用jQuery时,先引入jQuery 库, 有两种方法:

  • 引入本地的 jQuery 库;

  • 引入 jQuery 的CDN 链接;

一个简单的调用 jQuery 的例子, 当点击这个box 时,这个小弹出框会隐藏起来。


AngularJS

AngularJS 是一个完整的前端框架, 它是MVC 架构。AngularJS 的编程语言是 javascript。AngularJS 诞生于 Google,借助AngularJS,可以快速创建一个大型的、单页面Web 应用。

注意这里的用词,我们要创建的是 WEB application (Web 应用),而不是简单的网页。

因为 AngularJS 是用 JavaScript编写的,就像用jQuery 一样, 当用到AngularJS时,也需要  标签。那么,AngularJS与 jQuery 的区别又在哪里呢?


AngularJS与jQuery的区别

AngularJS是一个完整的前端框架,而jQuery是一个 JavaScript库;也就是说,jQuery仅仅是对 JavaScript 的封装,它确实提供了一些便利:原本 JavaScript也可以直接操作 DOM中的元素,只是用jQuery 操作 DOM 更加便利。从本质上讲,所有的前端框架都是为了解决如何操作DOM的问题。

AngularJS本身就包含了一个mini 版本的 jQuery 。


AngularJS是用 javascript 编写的,所以,要想掌握.AngularJS,必须很好地理解 javascript,尤其是对 javascript prototype 的理解,AngularJS官网上有大量的实例:example projects built with AngularJS, 可以作为学习者的参考资料。


Node.js

也许你还记得,在本文的开头,我就提到,JavaScript 是运行在浏览器上的。这样一来,JavaScript 只能做前端的事,后端还得用 Java、.net 来编写。这是因为,Web 应用只能运行在 Tomcat、 Apache、IIS 之类的 Web 应用服务器上。

但是,自从有了 Node.js ,这一切都改变了。所以说, node.js 为 JavaScript带来了新的生命力。

从本质上说,node.js 是Chrome’s V8 引擎,也可以说是 JavaScript的引擎(engine)。

在node.js 出现之前,前端和后台的开发是分开的,前端用JavaScript语言,而后台用 PHP、Java、 .net 。这是因为,在 node.js 之前,JavaScript只能运行在浏览器上;自从出现了 node.js 之后,JavaScript也能运行在后台服务器上了。这个后台服务器就是node.js 服务器。

小结

  • JavaScript:是一种编程语言,它是用来写网页的,而且是运行在浏览器上;

  • AJAX:网页上数据来自后台服务器,如何获取服务器上数据呢?JavaScript通过AJAX来获取,通过异步的方式;

  • jQuery:是一个 JavaScript 库,它解决了不同浏览器的兼容问题,从功能上讲,通过jQuery可以很轻松地实现动画的效果;

  • AngularJS:是一个完整的前端框架,它是用 JavaScript编写的,用于创建大型的、单页面Web 应用;

  • Node.js为JavaScript提供了更为广阔的舞台,在node.js 出现之前,JavaScript只能运行在浏览器上,有了node.js 之后,JavaScript 便可以运行在 Web 应用服务上。当然,这个Web 应用服务器是部署在node.js 环境上的。


四、JSON的数据交互


    JSONJavaScript Object NotationJS对象标记)是一种轻量级的数据交换格式。与XML一样,JSON也是基于纯文本的数据格式。它有两种数据结构。

    1.对象结构

    2.数组结构


    对象结构以“{”开始,以“}”结束。中间部分由0个或多个以英文“,”分隔的key/value对构成,keyvalue之间以英文“:”分隔。对象结构的语法结构如下:

{

  key1:value1,

  key2:value2,

  …

}

    其中,key必须为String类型,value可以是StringNumberObjectArray等数据类型。


    数组结构以“[”开始,以“]”结束。中间部分由0个或多个以英文“,”分隔的值的列表组成。数组结构的语法结构如下:

[

  value1,

  value2,

  …

]

    上述两种(对象、数组)数据结构也可以分别组合构成更为复杂的数据结构。例如:一个student对象包含snosnamehobbycollege对象,其JSON的表示形式如下:

{

  "sno":"201802228888",

  "sname":"陈恒",

  "hobby":["篮球","足球"],

  "college":{

  "cname":"清华大学",

  "city":"北京"

        }


JSON数据转换

    为实现浏览器与控制器类之间的JSON数据交互,Spring MVC提供了MappingJackson2HttpMessageConverter实现类默认处理JSON格式请求响应。该实现类利用Jackson开源包读写JSON数据,将Java对象转换为JSON对象和XML文档,同时也可以将JSON对象和XML文档转换为Java对象。

    Jackson开源包及其描述如下所示。

    jackson-annotations.jarJSON转换注解包。

    jackson-core.jarJSON转换核心包。

    jackson-databind.jarJSON转换的数据绑定包。

在使用注解开发时,需要用到两个重要的JSON格式转换注解,分别是@RequestBody@ResponseBody

    @RequestBody:用于将请求体中的数据绑定到方法的形参中,该注解应用在方法的形参上。

    @ResponseBody:用于直接返回JSON对象,该注解应用在方法上。

    下面通过一个实例来演示JSON数据交互过程。在该实例中,针对返回实体对象、ArrayList集合、Map<String, Object>集合以及List<Map<String,Object>>集合分别处理。



下面我们开看一套代码,源码包括:config、controller、pojo三个包。

此外,在Web App Libraries中导入了所需的jar包。

SpringMVCConfig.java

package config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.EnableWebMvc;import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import org.springframework.web.servlet.view.InternalResourceViewResolver;@Configuration@EnableWebMvc@ComponentScan("controller")public class SpringMVCConfig implements WebMvcConfigurer {/** * 配置视图解析器 */@Beanpublic InternalResourceViewResolver getViewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/WEB-INF/jsp/"); viewResolver.setSuffix(".jsp");return viewResolver; }/** * 配置静态资源 */@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/js/**").addResourceLocations("/js/"); }}

WebConfig.java

package config;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.ServletRegistration.Dynamic;import org.springframework.web.WebApplicationInitializer;import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;import org.springframework.web.servlet.DispatcherServlet;public class WebConfig implements WebApplicationInitializer{@Overridepublic void onStartup(ServletContext arg0) throws ServletException { AnnotationConfigWebApplicationContext ctx  = new AnnotationConfigWebApplicationContext(); ctx.register(SpringMVCConfig.class);//注册Spring MVC的Java配置类SpringMVCConfig ctx.setServletContext(arg0);//和当前ServletContext关联/** * 注册Spring MVC的DispatcherServlet */ Dynamic servlet = arg0.addServlet("dispatcher", new DispatcherServlet(ctx)); servlet.addMapping("/"); servlet.setLoadOnStartup(1); }}

Person.java

package pojo;public class Person {private String pname;private String password;private Integer page;public String getPname() {return pname; }public void setPname(String pname) {this.pname = pname; }public String getPassword() {return password; }public void setPassword(String password) {this.password = password; }public Integer getPage() {return page; }public void setPage(Integer page) {this.page = page; }}


TestController.java

package controller;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import pojo.Person;@Controllerpublic class TestController {/** * 接收页面请求的JSON数据,并返回JSON格式结果 */ @RequestMapping("/testJson") @ResponseBody public List<Map<String, Object>> testJson(@RequestBody Person user) {//打印接收的JSON格式数据 System.out.println("pname=" + user.getPname() +", password=" + user.getPassword() + ",page=" + user.getPage());//返回Person对象//return user;/**ArrayList<Person> allp = new ArrayList<Person>(); Person p1 = new Person(); p1.setPname("陈恒1"); p1.setPassword("123456"); p1.setPage(80); allp.add(p1);
Person p2 = new Person(); p2.setPname("陈恒2"); p2.setPassword("78910"); p2.setPage(90); allp.add(p2); //返回ArrayList<Person>对象 return allp; **/
Map<String, Object> map = new HashMap<String, Object>(); map.put("pname", "陈恒2"); map.put("password", "123456"); map.put("page", 25);//返回一个Map<String, Object>对象//return map;//返回一个List<Map<String, Object>>对象 List<Map<String, Object>> allp = new ArrayList<Map<String, Object>>(); allp.add(map);Map<String, Object> map1 = new HashMap<String, Object>(); map1.put("pname", "陈恒3"); map1.put("password", "54321"); map1.put("page", 55); allp.add(map1);return allp; }}

查看WebContent目录:

Web前端基础&JSON数据交互&表单标签库与数据绑定:大魏Java记20

其中有jquery.min.js(是一个 JavaScript 库,它解决了不同浏览器的兼容问题,从功能上讲,通过jQuery可以很轻松地实现动画的效果)、index.jsp。其中index.jsp是程序入口。


运行程序后,访问浏览器,输入信息:

Web前端基础&JSON数据交互&表单标签库与数据绑定:大魏Java记20

查看tomcat console的日志,可以看到相关信息:

Web前端基础&JSON数据交互&表单标签库与数据绑定:大魏Java记20



五、SpringMVC的基本配置

    Spring MVC的定制配置需要配置类实现WebMvcConfigurer接口,并在配置类使用@EnableWebMvc注解来开启对Spring MVC的配置支持,这样开发者就可以重写接口方法完成常用的配置。


    应用的静态资源(CSSJS、图片)等需要直接访问,这时需要开发者在配置类重写public voidaddResourceHandlers(ResourceHandlerRegistry registry)接口方法来实现。

/**

 * 配置静态资源

*/

@Override

publicvoid addResourceHandlers(ResourceHandlerRegistry registry) {

   registry.addResourceHandler("/html/**").addResourceLocations("/html/");

   //addResourceHandler指的是对外暴露的访问路径

   //addResourceLocations指的是静态资源存放的位置

}


    我们可以通过http://localhost:8080/ch2_3/html/NewFile.html直接访问静态资源文件NewFile.html(不通过DispatcherServlet

Web前端基础&JSON数据交互&表单标签库与数据绑定:大魏Java记20


六、表单与数据绑定的好处是什么?


我们以一个SpringMVC Web应用举例。

这个应用是添加用户信息,第一次添加,在职业栏中选“IT民工”,前台没有反应,后台显示添加失败。

Web前端基础&JSON数据交互&表单标签库与数据绑定:大魏Java记20

然后将职业选成“其他”,添加成功。

Web前端基础&JSON数据交互&表单标签库与数据绑定:大魏Java记20

在第一张图中,选择"IT民工”添加失败后,现有信息没有被清空,仍然保留,这就是表单标签库与数据的绑定。


接下来,我们介绍一些JSP表单相关的内容:

表单标签库

表单标签库中包含了可以用在JSP页面中渲染HTML元素的标签。JSP页面使用Spring表单标签库时,必须在JSP页面开头处声明taglib指令,指令代码如下:

<%@ taglibprefix="form" uri="http://www.springframework.org/tags/form"%>

    表单标签库中有forminputpasswordhiddentextareacheckboxcheckboxesradiobuttonradiobuttonsselectoptionoptionserrors


1.表单标签

表单标签,语法格式如下:

    <form:formmodelAttribute="xxx"method="post" action="xxx">

  ……

    </form:form>

    除了具有HTML表单元素属性外,表单标签还有具有acceptCharsetcommandNamecssClasscssStylehtmlEscapemodelAttribute等属性。

    其中,commandNamemodelAttribute属性功能基本一致,属性值绑定一个JavaBean对象。

2.input标签

    input标签,语法格式如下:

    <form:inputpath="xxx"/>

    该标签除了cssClasscssStylehtmlEscape属性外,还有一个最重要的属性pathpath属性将文本框输入值绑定到form backing object的一个属性。

3.password标签

    password标签,语法格式如下:

    <form:passwordpath="xxx"/>

    该标签与input标签用法完全一致,不再赘述。

4.hidden标签

    hidden标签,语法格式如下:

    <form:hiddenpath="xxx"/>

    该标签与input标签用法基本一致,只不过它不可显示,不支持cssClasscssStyle属性。

5.textarea标签

    textarea基本上就是一个支持多行输入的input元素,语法格式如下:

    <form:textareapath="xxx"/>

   该标签与input标签用法完全一致,不再赘述。

6.checkbox标签

    checkbox标签,语法格式如下:

    <form:checkboxpath="xxx" value="xxx"/>

    多个path相同的checkbox标签,它们是一个选项组,允许多选。选项值绑定到一个数组属性。

7.checkboxes标签

    checkboxes标签渲染多个复选框,是一个选项组,等价于多个path相同的checkbox标签。它有3个非常重要的属性:itemsitemLabelitemValue

    items:用于生成input元素的CollectionMapArray

    itemLabelitems属性中指定的集合对象的属性,为每个input元素提供label

    itemValueitems属性中指定的集合对象的属性,为每个input元素提供value

    checkboxes标签语法格式如下:

    <form:checkboxesitems="xxx" path="xxx"/>

8.radiobutton标签

    radiobutton标签,语法格式如下:

    <form:radiobuttonpath="xxx" value="xxx"/>

    多个path相同的radiobutton标签,它们是一个选项组,只允许单选。

9.radiobuttons标签


    radiobuttons标签渲染多个radio,是一个选项组,等价于多个path相同的radiobutton标签。radiobuttons标签,语法格式如下:

    <form:radiobuttonspath="xxx" items="xxx"/>

    该标签的itemLabelitemValue属性与checkboxes标签的itemLabelitemValue属性完全一样,但只允许单选。

10.select标签

    select标签的选项可能来自其属性items指定的集合,或者来自一个嵌套的option标签或options标签。语法格式如下:

    <form:selectpath="xxx" items="xxx" />

    <form:selectpath="xxx" items="xxx" >

   <optionvalue="xxx">xxx</option>

    </ form:select>

    <form:selectpath="xxx">

       <form:optionsitems="xxx"/>

    </form:select>

    该标签的itemLabelitemValue属性与checkboxes标签的itemLabelitemValue属性完全一样。


11.options标签

    options标签生成一个select标签的选项列表。因此,需要与select标签一同使用,具体用法参见select标签。

12.errors标签

    errors标签渲染一个或者多个span元素,每个span元素包含一个错误消息。它可以用于显示一个特定的错误消息,也可以显示所有错误消息。语法如下:

    <form:errorspath="*"/>

    <form:errorspath="xxx"/>

    其中,“*”表示显示所有错误消息;“xxx”表示显示由“xxx”指定的特定错误消息。


最后,我们查看一套代码,目录结构如下。一共有四个package。并且导入需要的Jar包。

四个Package有:

  • config

  • controller

  • pojo

  • service

Web前端基础&JSON数据交互&表单标签库与数据绑定:大魏Java记20


SpringMVCConfig.java,类中指定控制器类的基本包,进而扫描所有注解的控制器类(controller和@service)。本类是SpringMVCJava配置。

package config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.EnableWebMvc;import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import org.springframework.web.servlet.view.InternalResourceViewResolver;@Configuration@EnableWebMvc@ComponentScan(basePackages = {"controller","service"})public class SpringMVCConfig implements WebMvcConfigurer {/** * 配置视图解析器 */@Beanpublic InternalResourceViewResolver getViewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/WEB-INF/jsp/"); viewResolver.setSuffix(".jsp");return viewResolver; }/*** 配置静态资源 */@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/html/**").addResourceLocations("/html/");//addResourceHandler指的是对外暴露的访问路径//addResourceLocations指的是静态资源存放的位置 }}


WebConfig.java,本类部署了部署DispatcherServlet。本类是WebJava配置。

package config;import javax.servlet.ServletContext;import javax.servlet.ServletException;import org.springframework.web.WebApplicationInitializer;import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;import org.springframework.web.filter.CharacterEncodingFilter;import org.springframework.web.servlet.DispatcherServlet;public class WebConfig implements WebApplicationInitializer{ @Overridepublic void onStartup(ServletContext arg0) throws ServletException {AnnotationConfigWebApplicationContext ctx  = new AnnotationConfigWebApplicationContext(); ctx.register(SpringMVCConfig.class);//注册Spring MVC的Java配置类SpringMVCConfig ctx.setServletContext(arg0);//和当前ServletContext关联/** * 注册Spring MVC的DispatcherServlet */ javax.servlet.ServletRegistration.Dynamic servlet = arg0.addServlet("dispatcher", new DispatcherServlet(ctx)); servlet.addMapping("/"); servlet.setLoadOnStartup(1);/** * 注册字符编码过滤器 */ javax.servlet.FilterRegistration.Dynamic filter = arg0.addFilter("characterEncodingFilter", CharacterEncodingFilter.class);filter.setInitParameter("encoding", "UTF-8");filter.addMappingForUrlPatterns(null, false, "/*"); }}

UserController.java,本类定义了RequestMapping。例如下面定义了URL:如/usr/input、/usr/save、/usr/list。下面代码中,@ModelAttribute用于将多个请求参数封装到一个实体对象,从而简化数据绑定流程,而且自动暴露为模型数据用于视图页面展示时使用。也就是说,即使在页面有选线输入错误,其他已经输入的内容也不会清零。

package controller;import java.util.HashMap;inputimport java.util.List;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.ModelAttribute;import org.springframework.web.bind.annotation.RequestMapping;import pojo.User;import service.UserService;@Controller@RequestMapping("/user")public class UserController {// 得到一个用来记录日志的对象,这样打印信息的时候能够标记打印的是那个类的信息private static final Log logger = LogFactory.getLog(UserController.class);@Autowiredprivate UserService userService;@RequestMapping(value = "/input")public String inputUser(Model model) { HashMap<String, String> hobbys = new HashMap<String, String>(); hobbys.put("篮球", "篮球"); hobbys.put("乒乓球", "乒乓球"); hobbys.put("电玩", "电玩"); hobbys.put("游泳", "游泳");// 如果model中没有user属性,userAdd.jsp会抛出异常,因为表单标签无法找到// modelAttribute属性指定的form backing object model.addAttribute("user", new User()); model.addAttribute("hobbys", hobbys); model.addAttribute("carrers", new String[] { "教师", "学生", "coding搬运工", "IT民工", "其它" }); model.addAttribute("houseRegisters", new String[] { "北京", "上海", "广州", "深圳", "其它" });return "userAdd"; }@RequestMapping(value = "/save")public String addUser(@ModelAttribute User user, Model model) {if (userService.addUser(user)) { logger.info("成功");return "redirect:/user/list"; } else { logger.info("失败"); HashMap<String, String> hobbys = new HashMap<String, String>(); hobbys.put("篮球", "篮球"); hobbys.put("乒乓球", "乒乓球"); hobbys.put("电玩", "电玩"); hobbys.put("游泳", "游泳");// 这里不需要model.addAttribute("user", new// User()),因为@ModelAttribute指定form backing object model.addAttribute("hobbys", hobbys); model.addAttribute("carrers", new String[] { "教师", "学生", "coding搬运工", "IT民工", "其它" }); model.addAttribute("houseRegisters", new String[] { "北京", "上海", "广州", "深圳", "其它" });return "userAdd"; } }@RequestMapping(value = "/list")public String listUsers(Model model) { List<User> users = userService.getUsers(); model.addAttribute("users", users);return "userList"; }}


User.java,里面定义了一个名为User的实体类:

package pojo;

public class User {private String userName;private String[] hobby;//兴趣爱好private String[] friends;//朋友private String carrer;private String houseRegister;private String remark;public String getUserName() {return userName; }public void setUserName(String userName) {this.userName = userName; }public String[] getHobby() {return hobby; }public void setHobby(String[] hobby) {this.hobby = hobby; }public String[] getFriends() {return friends; }public void setFriends(String[] friends) {this.friends = friends; }public String getCarrer() {return carrer; }public void setCarrer(String carrer) {this.carrer = carrer; }public String getHouseRegister() {return houseRegister; }public void setHouseRegister(String houseRegister) {this.houseRegister = houseRegister; }public String getRemark() {return remark; }public void setRemark(String remark) {this.remark = remark; }}


UserService.java,定义一个名为UserService的接口,里面调用了集合:

package service;import java.util.ArrayList;import pojo.User;public interface UserService {boolean addUser(User u);ArrayList<User> getUsers();}

UserServiceImpl.java,定义UserService的接口实现类。该类中使用集合模拟数据库。

代码中还定义了添加用户的方法。如果为u.getCarrer()为"IT民工",则返回false,不添加用户。

package service;import java.util.ArrayList;import org.springframework.stereotype.Service;import pojo.User;@Servicepublic class UserServiceImpl implements UserService{//使用静态集合变量users模拟数据库private static ArrayList<User> users = new ArrayList<User>();@Overridepublic boolean addUser(User u) {if(!"IT民工".equals(u.getCarrer())){//不允许添加IT民工 users.add(u);return true; }return false; }@Overridepublic ArrayList<User> getUsers() {return users; }}


运行应用后,我们用上面的URI访问Web应用的Controller:

/usr/input、/usr/save、/usr/list

Web前端基础&JSON数据交互&表单标签库与数据绑定:大魏Java记20