SpringBoot_11 开发Web应用程序

开发Web应用程序


Spring Boot非常适合Web应用程序开发。您可以使用嵌入式Tomcat,Jetty,Undertow或Netty创建自包含的HTTP服务器。大多数Web应用程序使用该spring-boot-starter-web模块快速启动和运行。您还可以选择使用该spring-boot-starter-webflux模块构建响应式Web应用程序 。

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

Spring Web MVC框架


Spring Web MVC是一个丰富的“模型视图控制器” Web框架。简称Spring MVC且允许您绑定特殊的@Controller或@RestControllerbean注解来处理传入的HTTP请求。控制器中的方法通过使用@RequestMapping注解映射到HTTP 。

以下代码显示了@RestController注解为JSON数据提供服务的典型代码:

@RestController
@RequestMapping(value="/users")
public class MyRestController {

    @RequestMapping(value="/{user}", method=RequestMethod.GET)
    public User getUser(@PathVariable Long user) {
        // ...
    }

    @RequestMapping(value="/{user}/customers", method=RequestMethod.GET)
    List<Customer> getUserCustomers(@PathVariable Long user) {
        // ...
    }

    @RequestMapping(value="/{user}", method=RequestMethod.DELETE)
    public User deleteUser(@PathVariable Long user) {
        // ...
    }

}

Spring MVC自动配置


自动配置在Spring的默认值之上添加很多功能,例如:

  • 静态index.html支持
  • 自定义Favicon支持
  • 支持提供静态资源

静态内容


默认情况下,Spring Boot从资源根目录或类根目录或src/main/resources/static目录中提供静态内容.

欢迎页面


Spring Boot支持静态和模板化欢迎页面。在src/main/resources/static目录下查找index文件或模板。如果找到任何一个,它将自动用作应用程序的欢迎页面

自定义Favicon


Spring Boot 在配置的静态内容位置和类路径的根(按此顺序)中查找favicon.ico 。如果存在这样的文件,它将自动用作应用程序的展示图标。

跨源资源共享


在Spring Boot应用程序中使用带有@CrossOrigin注解的控制器方法且不需要任何其他特定配置就可以实现跨域

其他方式


  • HttpMessageConverters
  • 自定义JSON序列化程序和反序列化程序
  • MessageCodesResolver
  • 路径匹配和内容协商
  • ConfigurableWebBindingInitializer
  • 模板引擎
  • 错误处理
  • 映射Spring MVC之外的错误页面
  • Spring HATEOAS
  • Spring WebFlux框架
  • Spring WebFlux自动配置
  • 带有HttpMessageReaders和HttpMessageWriters的HTTP编解码器
  • 嵌入式Servlet容器支持
  • 程序化定制
  • 嵌入式Reactive Server支持
  • Reactive Server资源配置

下面的内容出自Spring Web MVC

带注解的控制器


Spring MVC提供基于注解的编程模型,其中@Controller和 @RestController组件使用注释来表达请求映射,请求输入,异常处理等。带注解的控制器具有灵活的方法签名,不必扩展基类,也不必实现特定的接口。以下示例显示了由注释定义的控制器:

get http://localhost:8080/hello?par=test
@Controller
public class HelloController {

    @GetMapping("/hello")
    public String handle(HttpServletRequest request, String par) {
        // others
        return "index";
    }
}

文件上传下载:最简化


@RestController
public class FileUploadController {

    @Value("${file.base.path}")
    String filePath;
    
    @PostMapping("/fileUp")
    public String getName(String fileName, MultipartFile fileUpload){
        String uid = UUID.randomUUID().toString().replace('-','x');
        if ( fileUpload.isEmpty() == false) {
            try {
                Path basePath = Paths.get(filePath+"file/");
                if(Files.notExists(basePath)) Files.createDirectory(basePath);
                fileUpload.transferTo(new File(filePath+"file/"+uid+fileName));
            } catch (IllegalStateException | IOException e) {
                e.printStackTrace();
            }
        }else{
            return "null";
        }
        return "filePath/"+uid+fileName;
    } 
    @GetMapping("/fileLoad")
    public void handleFormUpload(HttpServletResponse response) {
        try{
            OutputStream outputStream = response.getOutputStream();
            response.setContentType("application/x-download");
            response.addHeader("Content-Disposition","attachment;filename=name.txt");
            Files.copy(Paths.get(filePath+"file/name.txt"),outputStream );
            outputStream.flush();
            outputStream.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

transferTo(File):转存文件
List<MultipartFile>:接收多个文件上传
中文乱码:new String(name.getBytes("UTF-8"),"iso-8859-1");
application/x-download:设置内容类型为下载类型
Content-Disposition,attachment;filename=name:设置文件下载提示和文件名

重定向


redirect:原请求数据丢失

@Controller
public class HelloController {
    @GetMapping("/red")
    public String toRedict(HttpServletResponse response) {
        return "redirect:/boss.html";
    }
}

转发


forward:原数据还在

@Controller
public class HelloController {
    @GetMapping("/for")
    public String toForwerd(HttpServletResponse response) {
        return "forward:/client.html";
    }
}

重定向和转发的页面都是在资源下的static静态目录下的html页面,斜杠开头代表根目录开始

请求映射


你可以使用 @RequestMapping注解将请求映射到控制器方法上。它具有各种属性,可通过URL,HTTP方法,请求参数,标头和媒体类型进行匹配。您可以在类级别使用它来表示共享映射,或者在方法级别使用它来缩小到特定的端点映射。

还有HTTP方法特定的快捷方式变体@RequestMapping(默认情况下,它与所有HTTP方法匹配):
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
您可以使用以下全局模式和通配符映射请求:

  • ?匹配一个字符
  • *匹配路径段中的零个或多个字符
  • **匹配零个或多个路径段

控制器常用方法参数


控制器方法请求参数 描述
javax.servlet.ServletRequest, javax.servlet.ServletResponse 选择任何特定的请求或响应类型-例如ServletRequest,HttpServletRequest或Spring的MultipartRequest,MultipartHttpServletRequest。
javax.servlet.http.HttpSession 强制进行会话。因此,这种论点永远不会null。请注意,会话访问不是线程安全的。如果允许多个请求同时访问会话,请考虑将RequestMappingHandlerAdapter实例的synchronizeOnSession标志设置为 true。
HttpMethod 请求的HTTP方法
@PathVariable 用于访问URI模板变量
@RequestParam 用于访问Servlet请求参数,包括多部分文件。参数值将转换为声明的方法参数类型。请注意,@RequestParam对于简单参数值,使用是可选的
@RequestHeader 用于访问请求标头。标头值将转换为声明的方法参数类型。
@CookieValue 用于访问cookie。Cookie值将转换为声明的方法参数类型。
@RequestBody 用于访问HTTP请求正文。通过使用HttpMessageConverter实现将正文内容转换为声明的方法参数类型。
HttpEntity<B> 用于访问请求标头和正文。身体转换为HttpMessageConverter
@SessionAttribute 用于访问任何会话属性,与由于类级@SessionAttributes声明而存储在会话中的模型属性相反。
@RequestAttribute 用于访问请求属性。

控制器常用方法返回值


控制器常用方法返回值 描述
@ResponseBody 返回值通过HttpMessageConverter实现转换并写入响应。
HttpEntity<B>ResponseEntity<B> 指定完整响应(包括HTTP标头和正文)的返回值将通过HttpMessageConverter实现进行转换并写入响应。
HttpHeaders 用于返回带标题且没有正文的响应。
String 要使用ViewResolver实现解析的视图名称,并与隐式模型一起使用 - 通过命令对象和@ModelAttribute方法确定。处理程序方法还可以通过声明Model参数以编程方式丰富模型
View View实例以使用用于与所述隐式模型一起渲染-通过命令对象和确定@ModelAttribute方法。处理程序方法还可以通过声明Model参数以编程方式丰富模型
java.util.Maporg.springframework.ui.Model 要添加到隐式模型的属性,通过RequestToViewNameTranslator隐式确定视图名称。
@ModelAttribute 要添加到模型的属性,通过a隐式确定视图名称RequestToViewNameTranslator。请注意,这@ModelAttribute是可选的。请参见本表末尾的“任何其他返回值”。
ModelAndView 要使用的视图和模型属性,以及(可选)响应状态。
void 具有void返回类型(或null返回值)的方法被认为已完全处理响应(如果它还具有a ServletResponseOutputStream参数或@ResponseStatus注释)。如果控制器已进行正检查ETaglastModified时间戳检查,也是如此,如果以上都不是,则void返回类型还可以指示REST控制器的“无响应主体”或HTML控制器的默认视图名称选择。

URI变量


您可以在类和方法级别声明URI变量,如以下示例所示:

@Controller
@RequestMapping("/owners/{ownerId}")
public class OwnerController {

    @GetMapping("/pets/{petId}")
    public Pet findPet(@PathVariable Long ownerId, @PathVariable Long petId) {
        // ...
    }
}

URI变量会自动转换为适当的类型,或者TypeMismatchException 被引发。简单类型(int,long,Date,等)默认支持,你可以注册任何其它数据类型的支持。

您可以显式命名URI变量(例如,@PathVariable("customId"))

语法{varName:regex}声明一个URI变量,其正则表达式的语法为{varName:regex}。例如,给定URL "/spring-web-3.0.5 .jar",以下方法提取名称,版本和文件扩展名:

@GetMapping("/{name:[a-z-]+}-{version:\\d\\.\\d\\.\\d}{ext:\\.[a-z]+}")
public void handle(@PathVariable String name, @PathVariable String version, @PathVariable String ext) {
    // ...
}

URI路径模式还可以具有嵌入式${…​}占位符,这些占位符在启动时通过使用PropertyPlaceHolderConfigurer针对本地,系统,环境和其他属性源来解析。例如,您可以使用此参数来基于某些外部配置参数化基本URL。

使用consumes属性通过内容类型缩小映射范围


@PostMapping(path = "/pets", consumes = "application/json") 
public void addPet(@RequestBody Pet pet) {
    // ...
}

该consumes属性还支持否定表达式 - 例如,!text/plain表示除了以外的任何内容类型text/plain

对应关系


@GetMapping对应@RequestMapping(method=HttpMethod.GET)
@PostMapping,@PutMapping,@DeleteMapping,和@PatchMapping等都有此对应

@RequestParam,@RequestHeader,@PathVariable,@MatrixVariable,和@CookieValue)可以要求类型转换如果参数被声明为比其它的东西String。

对于此类情况,将根据配置的转换器自动应用类型转换

@GetMapping("/demo")
public void handle(@CookieValue("JSESSIONID") String cookie) { 
    //...
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容