资讯专栏INFORMATION COLUMN

Spring Boot QuickStart (3) - Web & Restful

chnmagnus / 1845人阅读

摘要:不过可以切换到版本,兼容性未知。注解一旦添加了依赖会判断这是一个应用,并启动一个内嵌的容器默认是用于处理请求。注意中空字符串与的区别。

环境:Spring Boot 1.5.4

基于 Spring Boot 可以快速创建一个Web & Restful 应用,在开始应用之前,至少要了解以下用法:

定义路由,定义 HTTP 方法

获取Header、GET、POST、路径等参数

Cookie、Session操作

应用一个模板引擎,选择 Thymeleaf

获取表单数据,以及文件上传数据

完成一个登陆、登出、注册流程

增加以下两个依赖即可完成构建:


    org.springframework.boot
    spring-boot-starter-thymeleaf


    org.springframework.boot
    spring-boot-starter-web

注意:当前版本默认选择的 Thymeleaf 是 2.x 版本的,对html 标签闭合性要求比较高,虽然可以通过设置 mode,改变解析方式,但是还要引入额外的 nekoHTML,所以很蛋疼。不过可以切换到 3.x 版本,兼容性未知。


    3.0.2.RELEASE
    2.1.1
注解

一旦添加了 spring-boot-starter-web 依赖 Spring Boot 会判断这是一个Web 应用,并启动一个内嵌的Servlet容器(默认是Tomcat)用于处理HTTP请求。

Spring 框架中关于 Web 应用有大量的注解:

@Controller
注解一个 Web 控制器类,框架会将 Servlet 容器里收到的 HTTP 请求根据路径分发给对应的 Controller 类进行处理

@RestController
注解一个 Restful 控制器,默认会自动返回 JSON

@RequestMapping
注解一个路由,如果定义在类上,相当于一个路由组,最终路由是类+方法路由,参数有路由规则和 HTTP 方法,同时还有一些简写形式如:@GetMapping@PutMapping

@PathVariable
注解路径参数,如 /user/{id}

@RequestParam
注解请求参数,如 ?user=a 或 post["user"] = a

@RequestBody
注解请求体

@RequestHeader
注解请求header头

@CookieValue
注解一个Cookie值

@SessionAttribute
注解一个Session值

路由,方法

下面代码对应了两个路由:

/ 使用 @ResponseBody 注解,所以返回了文本串
/hello 返回表示模板的字符串,将会使用 resources/templates/hello.html 模板渲染

@Controller
public class IndexController {

    @RequestMapping("/")
    @ResponseBody
    public String index() {
        return "Spring Boot Index";
    }

    @RequestMapping("/hello")
    public String hello(Model model) {
        model.addAttribute("title", "Spring Boot");
        return "hello";
    }
}

这段代码对应了 /rest/ 路由。注意 @RequestMapping 中空字符串与 "/" 的区别。
使用空,则 /rest 与 /rest/ 都可以访问,使用 / 则必须通过 /rest 访问:

@RestController
@RequestMapping("/rest")
public class RestfulController {

    @RequestMapping("")
    public String index() {
        return "Hello Rest";
    }
}    

hello.html:




    
    title


h1

请求参数 单一参数

@RequestParam 可以用来注解一个请求参数,默认会合并 GET、POST 请求名相同的参数,变成一个数组,所以下面的 text2 会进行数组 -> String 的转型。

@RequestMapping(value = "/get", method = {RequestMethod.GET, RequestMethod.POST})
@ResponseBody
public String get(@RequestParam("text1") String text1, @RequestParam("text2") String text2) {

   return text1 + "/" + text2;
}

在这里不使用注解同样可以获得数据,那为什么要使用注解呢? 因为 @RequestParam 主要提供了一些额外的功能:
如参数名->变量名的映射,required 检查等,更严谨一些。

@RequestMapping(value = "/getsimple", method = {RequestMethod.GET, RequestMethod.POST})
@ResponseBody
public String getSimple(String text1, String text2) {
   return text1 + "/" + text2;
}
参数列表

除了使用 @RequestParam 注解获取单个参数意外,还可以获取一个参数列表,但这种方式,POST 不会合并 GET 中的同名参数:

@RequestMapping("/getmap")
@ResponseBody
public String getMap(@RequestParam Map gets) {
   return gets.toString();
}
额外参数列表

除了注解获取数据以外,我们还可以通过向 Controller 中的方法,注入 Servlet 相关的类,来获取一些额外的参数,比如客户端 IP 地址

@RequestMapping("/request")
@ResponseBody
public String request(HttpServletRequest request) {
   HashMap requests = new HashMap<>();

   requests.put("Method", request.getMethod());
   requests.put("QueryString", request.getQueryString());
   requests.put("RequestURI", request.getRequestURI());
   requests.put("getRequestURL", request.getRequestURL().toString());
   requests.put("RemoteAddr", request.getRemoteAddr());

   return requests.toString();
}
Cookie

Cookie 的操作其实和 Spring 没有太大的关系,不过Spring 提供了一个 @CookieValue 注解用来快速获取 Cookie 值

通过 HttpServletResponse 设置页面的 Cookie:

@RequestMapping("/setcookie")
@ResponseBody
public String setCookie(HttpServletResponse response) {
   Cookie cookie1 = new Cookie("cookie1", "value1");
   cookie1.setMaxAge(1800);
   Cookie cookie2 = new Cookie("cookie2", "value2");
   cookie2.setMaxAge(3600);

   response.addCookie(cookie1);
   response.addCookie(cookie2);
   return "cookie set ok";
}

通过 HttpServletRequest 或 @CookieValue 注解获取 Cookie:

@RequestMapping("/getcookie")
@ResponseBody
public String getCookie(HttpServletRequest request,
       @CookieValue(value = "cookie1", required = false) String cookie1) {

   HashMap map = new HashMap<>();
   Cookie[] cookies = request.getCookies();
   if (cookies != null) {
       for (Cookie cookie : cookies) {
           map.put(cookie.getName(), cookie.getValue());
       }
   }

   logger.info(cookie1);

   return map.toString();
}

清空Cookie,就是重新设置cookie的值与过期时间:

@RequestMapping("/delcookie")
@ResponseBody
public String delCookie(HttpServletRequest request, HttpServletResponse response) {
   Cookie[] cookies = request.getCookies();
   if (cookies != null) {
       for (Cookie cookie : cookies) {
           // setValue只是清空了value,cookie还在
           cookie.setValue(null);
           cookie.setMaxAge(0);
           response.addCookie(cookie);
       }
   }

   return "delete ok";
}
Session

Session的相关操作,通过 HttpSession、HttpServletRequest、@SessionAttribute 来完成。

设置 Session:

@RequestMapping("/setsession")
@ResponseBody
public String setSession(HttpSession session) {
   session.setAttribute("session1", "value1");
   session.setAttribute("session2", "value2");
   return "";
}

获取Session:

@RequestMapping("/getsession")
@ResponseBody
public String getSession(
       HttpServletRequest request,
       HttpSession httpSession,
       @SessionAttribute(value = "session1", required = false) String session1) {
   HttpSession session = request.getSession();
   String session2 = (String)session.getAttribute("session2");
   String http_session1 = (String)httpSession.getAttribute("session1");

   logger.info(http_session1);
   logger.info(session1);
   logger.info(session2);

   HashMap sessionMap = new HashMap<>();
   Enumeration sessions = session.getAttributeNames();
   while(sessions.hasMoreElements()) {
       String key = sessions.nextElement();
       sessionMap.put(key, (String)session.getAttribute(key));
   }

   return sessionMap.toString();
}

删除Session:

@RequestMapping("/delsession")
@ResponseBody
public String delSession(HttpSession httpSession) {
   httpSession.removeAttribute("session1");
   httpSession.removeAttribute("session2");

   return "delete session ok";
}
模板引擎

在模板引擎之前,要了解怎么向模板中传递数据,于是有这三种姿势:

Map,这是一个Java原生类型
ModelMap,这是一个类
Model,这是一个接口,其实现类为 ExtendedModelMap,继承了 ModelMap 类

这三个都可以在方法参数中直接注入使用,暂时不知道这三个有什么区别,用起来差不多。

@RequestMapping("/model")
public String model(Model model, ModelMap modelMap, Map map) {
   model.addAttribute("title1", "model_title");
   modelMap.addAttribute("title2", "modelMap_title");
   map.put("title2", "map_title");

   User user = new User(1, "test");
   model.addAttribute("user", user);

   return "model";
}

除了上面的用法,还可以使用 ModelAndView 手动渲染模板,效果是一样的:

@RequestMapping("/modelandview")
public ModelAndView modelAndView() {
   ModelAndView modelAndView = new ModelAndView();
   modelAndView.setViewName("model");
   modelAndView.addObject("title1", "title1");
   modelAndView.addObject("title2", "title2");

   User user = new User(1, "test");
   modelAndView.addObject("user", user);

   return modelAndView;
}

最后 SpringBoot 默认可以集成好几种模板引擎,现在主要使用 thymeleaf。

@ModelAttribute 注解

这个注解有点复杂。可以注解到方法上,也可以注解到方法参数上

注解到方法参数

大概意思是通过模型中获取,这个模型是什么呢?大概通过一些途径(可能来自Session?可能来自请求参数?可能来自控制器注解到方法上的 @ModelAttribute)

完成自动填充,并且自动传递到模板中,这是 Spring MVC 数据绑定。

下面是两个例子:

请求通过 /xxx?id=1&name=张三,能够自动进行映射,并且传到模板中,并且还能自动进行输出格式转换,如下面第一个例子,受 @ResponseBody 影响,直接输出了 JSON

@RequestMapping("/getmodel")
@ResponseBody
public User getModel(@ModelAttribute User user) {
   return user;
}

@RequestMapping("/modelattribute")
public String modelAttribute(@ModelAttribute User user) {
   return "model";
}

注解到方法

将这个控制器的方法,变成一个非请求处理的方法,在其它请求方法(RequestMapping)被调用前首先调用该方法,并将返回的数据放到 Model 中

有什么用呢?

估计是用来生成初始化数据的,比如生成一个带有一些默认数据的表单?在进入控制器之前对数据进行一些整理和清洗?

常用配置 自动 trim 参数

大多数 PHP 框架都有自动 trim GET/POST 参数的功能

在 Spring 里面,可以借助 @InitBinder 注解可以完成这种事情,我们定义一个控制器基类,方便接受请求的控制器继承

public class BaseController {
    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        StringTrimmerEditor stringtrimmer = new StringTrimmerEditor(true);
        binder.registerCustomEditor(String.class, stringtrimmer);
    }
}
server

server.address 绑定地址
server.port 绑定端口
server.compression.enabled 是否开启压缩
server.compression.mime-types 压缩的类型
server.compression.min-response-size 压缩的阈值

server.tomcat.* access日志,日志目录,线程数等

server.session.cookie.* SessionCookie相关配置

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/67275.html

相关文章

  • Spring Boot QuickStart (1)

    摘要:开始介绍简化了基于的应用开发,你只需要就能创建一个独立的,产品级别的应用。该包含很多搭建,快速运行项目所需的依赖,并提供一致的,可管理传递性的依赖集。日志级别通过标识开启控制台级别日志记录,也可以在中指定日志级别配置示例 开始 介绍 Spring Boot 简化了基于 Spring 的应用开发,你只需要 run 就能创建一个独立的,产品级别的 Spring 应用。 Spring 平台...

    klinson 评论0 收藏0
  • 7、服务发现&amp;服务消费者Ribbon

    摘要:在服务注册服务提供者这一篇可能学习了这么开发一个服务提供者,在生成上服务提供者通常是部署在内网上,即是服务提供者所在的服务器是与互联网完全隔离的。服务消费者本质上也是一个。 在《服务注册&服务提供者》这一篇可能学习了这么开发一个服务提供者,在生成上服务提供者通常是部署在内网上,即是服务提供者所在的服务器是与互联网完全隔离的。这篇说下服务发现(服务消费者),通常服务消费者是部署在与互联网...

    tangr206 评论0 收藏0
  • Spring Boot 2 快速教程:WebFlux 快速入门(二)

    摘要:响应式编程是基于异步和事件驱动的非阻塞程序,只是垂直通过在内启动少量线程扩展,而不是水平通过集群扩展。三特性常用的生产的特性如下响应式编程模型适用性内嵌容器组件还有对日志消息测试及扩展等支持。 摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 02:WebFlux 快速入门实践 文章工程: JDK...

    gaara 评论0 收藏0
  • Spring 指南(目录)

    摘要:指南无论你正在构建什么,这些指南都旨在让你尽快提高工作效率使用团队推荐的最新项目版本和技术。使用进行消息传递了解如何将用作消息代理。安全架构的主题指南,这些位如何组合以及它们如何与交互。使用的主题指南以及如何为应用程序创建容器镜像。 Spring 指南 无论你正在构建什么,这些指南都旨在让你尽快提高工作效率 — 使用Spring团队推荐的最新Spring项目版本和技术。 入门指南 这些...

    only_do 评论0 收藏0
  • Spring Boot QuickStart (2) - 基础

    摘要:比如日志默认使用作为第一选择,默认集成了,并且支持配置使用貌似和有点变化,暂时不折腾了单元测试 环境:Spring Boot 1.5.4 基于 Spring Boot 创建一个命令行应用,先来个最基本的体验,体验一下: 配置管理(配置文件加载,多环境配置文件) 日志 单元测试 创建项目 比较好的两种方法: 通过 https://start.spring.io/ 网站,生成项目框架...

    zgbgx 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<