Skip to content

Instantly share code, notes, and snippets.

@sunwu51
Last active September 3, 2017 06:04
Show Gist options
  • Save sunwu51/f8e274d3f4b37d95d6efa1f737d1e447 to your computer and use it in GitHub Desktop.
Save sunwu51/f8e274d3f4b37d95d6efa1f737d1e447 to your computer and use it in GitHub Desktop.
SpringBoot Weblayer

Spring Boot Weblayer

web层的相关知识点

---------Controller---------

1 ModelAndView

当需要返回传递了model的View时,我们可以通过设置返回值为ModelAndView,并传递模型映射:

@RequestMapping("/hello")
public ModelAndView hello(@RequestParam(value="name", required=false, defaultValue="World") String name) {
    HashMap<String,Object> map=new HashMap<>();
    map.put("name",name);
    map.put("age",11);
    return new ModelAndView("hello",map);
}

或者也可以返回值是String,且第一个参数为Model,通过为model添加属性来映射,这种方法和上面这种完全等价:

@RequestMapping("/hello")
public String hello(Model model, @RequestParam(value="name", required=false, defaultValue="World") String name) {
    model.addAttribute("name", name);
    model.addAttribute("age",11);
    return "hello";
}

2 Json

如果要返回的值不是一个页面而是一个Json,此时首先需要修改注解,如果是整个控制器都是Json格式的接口,则将Controller注解改为RestController【注:RestController=Controller+ResposeBody】,如果只是某个方法返回json或字符串则只在那个方法上面添加ResponseBody注解。 例如:返回String的接口:

@RequestMapping("/str")
@ResponseBody
public String str(){
    return "<h1>Hello</h1>";
}

如果要返回json格式则返回值不能为String了【除非你想手动构建json代码】通过以下方式返回json格式

@RequestMapping("/json")
@ResponseBody
public ResponseEntity<User> json(){
    User user=new User();
    user.setUserName("frank");
    user.setCredit(100);
    return new ResponseEntity<User>(user,HttpStatus.OK);
}

注意如果是有管理的模型例如User里都关联了一个father字段,类型是另一个User,则返回的Json中会有father:{name:"xx"...}这样的father的详细信息也会查出来。

接收json字符串自动转为对象@RequestBody注解写在对象参数前,可以将json字符串转对象。除了对象之外Map<String,Object>也是可以的

public void createUserByMap(@RequestBody Map<String,Object> reqMap){
      String tel = reqMap.get("tel").toString();
      String pwd = reqMap.get("pwd").toString();
      userService.createUser(tel,pwd);
}

参数传入

除了上述可以将json或xml参数直接转换为对象或map的@RequestBody传入,我们还需要其他的传入方式来应对不同的场景。 比如Rest风格的传入方式应该是直接从Url中解析 @PathVariable注解绑定Url变量

     @RequestMapping("/user/{userid}")
     public String deleteUser(@PathVariable("userid") String userid)

再比如请求参数较少的情况但不是Rest风格 @RequestParam相当于Request.getParam

 public String deleteUser(@RequestParam("userid") String userid)

以上三种即为最为常用的三种参数获取的方式。

参数校验

请求参数的校验最常用的有非空校验、长度校验、数字校验,最全能的有正则校验

一般通过两种方式进行校验,如果传入参数是对象则在前面添加@Valid注解,并在这个对象的字段中进行校验相关注解即可,例如:

 public String createUserByMap(@Valid @RequestBody User user)//User对象中需要有校验的相关注解

而针对@RequestParam的形式则可以直接在参数前面添加校验详情的注解例如下面这个校验长度为1-3的:

public String validString( @RequestParam(defaultValue = "") @Size(min = 1, max = 3) String vStr)

常用的校验注解 NotNull NotBlank Size Email Max/Min Pattern Past Future

---------View---------

SpringMVC的view是需要配置view文件放到了哪个文件夹下,后缀是什么这样的。例如用JSTL标签库: 依赖 pom.xml中需要引用jstl:

<dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>jstl</artifactId>
</dependency>

前后缀(路径) 然后需要在xxx-servlet.xml文件中制定jsp文件存放的位置,这里指定的是webapp/WEB-INF/jsp/目录下后缀为jsp的文件,当然如果不指定的话就是webapp,如下这种指定的情况,如果找不到对应的jsp文件也会到webapp目录下找。

<bean
   class="org.springframework.web.servlet.view.InternalResourceViewResolver"
   p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />

jstl标签 jsp文件中可以指定jstl的前缀,所以jsp文件的头部一般都会这样写,来指定编码和jstl的前缀为c(也可以是别的简称):

<%@ page language="java" contentType="text/html; charset=UTF-8"
   pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core"; prefix="c" %>

SpringBoot的view是不推荐使用jsp的,因为
如果用内嵌的容器(如内嵌的tomcat或jetty)的时候会有些限制,如果是tomcat内嵌则必须发布成可执行的war包才能被发布到标准的tomcat容器中,如果是jar包则不行,因为tomcat的文件硬编码的一些问题。

如果使用jetty的话war可以可以的同样可以发布到标准容器中,Ubdertow不支持jsp(这个我也不知道是啥)

自定义的error.jsp页面不会重写默认的错误页面,自定的错误页面还是会被默认页面替代。

我们也可以清晰的看到官方不推荐jsp的使用

即使在内嵌容器的时候存在一些问题,但是jstl仍然是可以使用的: 依赖 pom注意下面第二个依赖是内嵌tomcat的情况下,如果是jetty则是另外一个依赖

<dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>jstl</artifactId>
</dependency>
<dependency>
   <groupId>org.apache.tomcat.embed</groupId>
   <artifactId>tomcat-embed-jasper</artifactId>
   <scope>provided</scope>
</dependency>

前后缀(路径) 对于jsp文件路径的配置因为没有xml文件所以都是放在application.properties文件中,这里的/代表的是webapp目录,而springboot默认不会创建这个目录(默认的SpringbootApp的模板文件应该是在resouces/templates文件夹下),所以还需要自己创建这个目录。

spring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp

同样jsp文件头部也可像上面那样写。效果和SpringMVC一样。

使用推荐的引擎Thymeleaf
依赖(注意如果同时使用了jsp【jstl可有可无】和thymeleaf则会以后者解析)

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

thymeleaf是可以自动解析的引擎,因而和其他推荐引擎一样,模板文件是默认放在resource/templates目录下的并且后缀为html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
     <head>
           <meta charset="UTF-8"/>
           <title>Hello Thymeleaf!</title>
     </head>
     <body>
           <p th:text="'Hello, ' + ${name} + '!'" />
     </body>
</html>

---------Model---------

序列化与反序列化 与SpringMVC完全一致。都是通过Jackson实现的json序列化与反序列化,不过boot中web依赖中自动添加了jackson所以pom中不用单独添加。

模型层中有很多类是数据库的映射类因而会有些需要注意的地方。 模型类的字段有很多关于json转换的注解和json参数校验的注解,我们来看一些常用的注解: @JsonProperty 指定对应的json字段名(默认不指定就是属性名) @JsonIgnore 进行序列化或反序列化时忽略该字段 @JsonIgnoreType 修饰类,如果是另一个类的属性则默认就被忽略了 @JsonIdentityInfo 唯一标识,写在字段或类上面,常用于解决循环嵌套问题

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,property = "userId")

参考:http://blog.csdn.net/sdyy321/article/details/40298081

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment