MVC的杂乱笔记

SpringMVC简单笔记

主要是学习一下Controller和View的设计,起码写的规范点

笔记部分来自简短的精通Spring MVC4,恰好书里也是用Spring Boot的,很适合上手
由于时间跨度比较大(大概2 3个月),所以可能会记录一些蠢到爆的问题。。

@SpringBootApplication 是@Configuration、@EnableAutoConfiguration 和 @ComponentScan的组合

@Configuration表明我们的这个类将会处理 Spring 的常规配置,如 bean 的声明

@ComponentScan它会告诉 Spring 去哪里查找 Spring 组 件(服务、控制器等)。在默认情况下,这个注解将会扫描当前包以及该包下面的所有 子包

@EnableAutoConfiguration 注解,它会指导 Spring Boot 发挥其魔力。如果你将其移除掉的话,就无法从 Spring Boot 的自动配置中收益了

XML常用配置(Spring Boot中并不需要,但要求了解)

一般来讲,初始的步骤如下所示:
1.初始化 Spring MVC 的 DispatcherServlet;
2.搭建转码过滤器,保证客户端请求进行正确地转码;
3.搭建视图解析器(view resolver),告诉 Spring 去哪里查找视图,以及它们是使用哪 种方言编写的(JSP、Thymeleaf 模板等);
4.配置静态资源的位置(CSS、JS);
5.配置所支持的地域以及资源 bundle;
6.配置 multipart 解析器,保证文件上传能够正常工作;
7.将 Tomcat 或 Jetty 包含进来,从而能够在 Web 服务器上运行我们的应用;
8.建立错误页面(如 404)。

properties中

debug=true Spring Boot 自动配置报告

server.port 属性或者定义名为 SERVER_PORT 的环境变量,我们可以修改默认的 HTTP 端口中定义 server.port 属性或者定义名为 SERVER_PORT 的环境变量,我们可以修改默认的 HTTP 端口

配置SSL

server.port = 8443 
server.ssl.key-store = classpath:keystore.jks 
server.ssl.key-store-password = secret 
server.ssl.key-password = another-secret 

其它已经默认配好的配置

在 JacksonAutoConfiguration 中,声明使用 Jackson 进行 JSON 序列化;

在HttpMessageConvertersAutoConfiguration 中,声明了默认的HttpMessageConverter;

在 JmxAutoConfiguration 中,声明了 JMX 功能。

模型是由Spring MVC 的Model 或ModelAndView 封装的简单 Map。

它可以来源于数据库、文件、外部服务等,这取决于你如何获取数据并将其放到模型

通过使用@RequestMapping 注解,控制器能够声明它们会根据 HTTP 方法(如 GET 或 POST 方法)和 URL 来处理特定的请求。控制器就可以确定是在 Web 响应中直接写入内容, 还是将应用路由一个视图并将属性注入到该视图中

纯粹的 RESTful 应用将会选择第一种方式,并且会在 HTTP 响应中直接暴露模型的JSON 或 XML 表述,这需要用到@ResponseBody 注解。在 Web 应用中,这种类型的架构 通常会与前端 JavaScript 框架关联,如 Backbone.js、AngularJS 或 React。在这种场景中, Spring 应用只需处理 MVC 中的模型层。

在第二种方式中,模型会传递到视图中,视图会由模板引擎进行渲染,并写入到响应 之中。

大概意思就是说前者是前后端分离的工作方式

为了加快开发速度,在 application.properties 文件中添加该属性:
spring.thymeleaf.cache=false
这将会禁止启用视图缓存,每次访问的时候都会重新加载模板。

HTTP请求经过Dispatcher Servlet分派到Handler Mapping/Controller/View Resolver/View

一个典型的 HttpServlet 类,它会将 HTTP 请求分发给 HandlerMapping。 HandlerMapping 会将资源(URL)与控制器关联起来

控制器上对应的方法(也就是带有@RequestMapping 注解的方法)将会被调用。在这 个方法中,控制器会设置模型数据并将视图名称返回给分发器。

然后,DispatcherServlet 将会查询 ViewResolver 接口,从而得到对应视图的实现。

(ThymeleafAutoConfiguration 将会为我们搭建视图解析器)

通过查看ThymeleafProperties类,可以知道视图的默认前缀是“classpath:/templates/”, 后缀 是“.html”。

这就意味着,假设视图名为 resultPage,那么视图解析器将会在类路径的 templates 目 录下查找名为 resultPage.html 的文件。

默认样例下,ViewResolver 接口是静态的,但是更为高级的实现能够根据请求的 头信息或用户的地域信息,返回不同的结

视图最终将会被渲染,其结果会写入到响应之中。

访问列表元素 list[0]
访问 Map 条目 map[key]
三元运算符 condition ? 'yes' :'no'
Elvis 运算符 person ?: default 如果 person 的值为空的话,将会返回 default
安全导航 person?.name 如果 person 为空或其 name 为空的话,返回 null
模板 'Your name is #{person.name}' 将值注入到字符串中
投影 ${persons.[name]} 抽取所有 persons 的 name,并将其放到一个列表中
选择 persons.?[name =='Bob']' 返回列表中 name 为 Bob 的 person
函数调用 person.sayHello()

数据传递到视图的方式:model->return

请求参数获取数据:@RequestParam->浏览器中?属性写入

常用required 和 defaultValue

目前进展P63

简单的遍历

 <ul>
     <li th:each="tweet : ${tweets}" th:text="${tweet}">Some tweet</li>   
</ul>

添加jQuery

<script src="/webjars/jquery/2.1.4/jquery.js"></script> 

视图的head中加入CSS

 <link href="/webjars/materializecss/0.96.0/css/materialize.css" type="text/css" rel="stylesheet" media="screen,projection"/> 

模仿样例P53

可重用页面的设计(布局)

default.html的部分

<html xmlns:th="http://www.thymeleaf.org"                xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"> 
<head>....</head>
<body> 
<section layout:fragment="content">   
    <p>Page content goes here</p> 
</section>
<script..>....</script>
</body>

对于result页面

<!DOCTYPE html> 
<html xmlns:th="http://www.thymeleaf.org"  xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"   layout:decorator="layout/default"> 
<head lang="en">
    <title>Hello twitter</title> 
</head> 
<body>
<div class="row" layout:fragment="content"> 
    <h2 class="indigo-text center" th:text="|Tweet results for ${search}|">Tweets</h2> 
    <ul class="collection"> 
        .....

其中,layout:decorator="layout/default"能够表明去哪里查找布局。这样,我们可以将内容注入到布局的不同 layout:fragment 区域中。

注意这种方法已经不推荐了(被书坑了),应该使用th:insert替代,

一个更好的用例:https://segmentfault.com/a/1190000009903821#articleHeader1

简单的错误弹出P75

关于请求的处理

Redirect/Forward 是典型的可选方案。它们都会改变展现给用户的视图,其中的区别在于 Redirect 会发送一个 302 头信息,它会在浏览器内部触发导航,而 Forward 则不会导致 URL 的变化。在 Spring MVC 中,我们可以任意使用这两种方案,只需在方法返回的字符串上添加“redirect:”或“forward:” 前缀即可

GET的常用写法

@RequestMapping("/result")   
public String hello(
        @RequestParam(defaultValue = "masterSpringMVC4") String search, 
        Model model) {
    SearchResults searchResults = twitter.searchOperations().search(search);
    List<Tweet> tweets = searchResults.getTweets();  
    model.addAttribute("tweets", tweets);  
    model.addAttribute("search", search);  return "resultPage";  
}

如果要修改表单,把method改为post(多了一个拦截postSearch的方法)

@RequestMapping(value = "/postSearch", method = RequestMethod.POST) 
public String postSearch(
        HttpServletRequest request,
        RedirectAttributes redirectAttributes) {  
    String search = request.getParameter("search");
    redirectAttributes.addAttribute("search", search);
    return "redirect:result"; 
}

RedirectAttributes 是一个 Spring 的模型,专门用于 redirect 场景下传送值

一个更加鲁棒的方法

@RequestMapping(value = "/postSearch", method = RequestMethod.POST) 
public String postSearch(
        HttpServletRequest request, 
        RedirectAttributes redirectAttributes) {  
    String search = request.getParameter("search");  
    if (search.toLowerCase().contains("struts")) {  //不允许出现的内容
        redirectAttributes.addFlashAttribute("error", "Try using spring instead!"); 
        return "redirect:/";  
    }  
    redirectAttributes.addAttribute("search", search);  
    return "redirect:result"; 
}

表单

@{}语法将会为资源构建完整的路径,它会将服务器上下文路径

因此在thymeleaf中可以用form th:action="@{...}"替代form action=..

DTO可以直接使用POJO,只需要getter和setter进行数据绑定即可

具体查阅P82

校验逻辑查阅P86

表单逻辑P99

P120

HTTP 会话(session)是用来在请求之间存储信息的一种 方式。HTTP 是无状态的协议,这就意味着没有办法将同一 用户的两个请求关联起来。Servlet容器最常用的办法是为每 个用户关联一个名为 JSESSIONID 的cookie。这个 cookie 将会通过请求头信息进行传输,借助这项技术允许用户将 任意的对象存储在 Map 中,也就是名为 HttpSession 的抽 象形式。这样的会话一般情况下会在用户关闭或切换 Web 浏览器,或者预定时间内用户没有活跃的动作时失效

可以通过使用@SessionAttributes 注解,将对象放到了会话中 P115

@Controller @SessionAttributes("picturePath") public class PictureUploadController { } 

在 Spring 中,将内容放到会话中的另外一种流行方式就是为 bean 添加@Scope ("session")注解。

表格的坑:

https://blog.csdn.net/ystyaoshengting/article/details/84773952

关于Controller的传参 返回值,还是参考MVC官方文档

https://docs.spring.io/spring/docs/5.1.8.RELEASE/spring-framework-reference/web.html

大概在1.3.3

结果还是看不太懂String View ModelAndView的关系。。。

感觉上,String返回的是View的名字,交由由ViewResolver处理,而View可以通过setter做到了String一样拿到View的名字,但可能已经进一步解析,而ModelAndView可进一步设置view里头所依赖的model

关于传参中的Model,是否需要名字一一对应?

关于@ModelAttribute

You can use the @ModelAttribute annotation on a method argument to access an attribute from the model or have it be instantiated if not present. The model attribute is also overlain with values from HTTP Servlet request parameters whose names match to field names. This is referred to as data binding, and it saves you from having to deal with parsing and converting individual query parameters and form fields. The following example shows how to do so:

@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@ModelAttribute Pet pet) { } 

The Pet instance above is resolved as follows:

  • From the model if already added by using Model.
  • From the HTTP session by using @SessionAttributes.
  • From a URI path variable passed through a Converter (see the next example).
  • From the invocation of a default constructor.
  • From the invocation of a “primary constructor” with arguments that match to Servlet request parameters. Argument names are determined through JavaBeans @ConstructorProperties or through runtime-retained parameter names in the bytecode.

猜你喜欢

转载自www.cnblogs.com/caturra/p/11026090.html
今日推荐