Spring Boot快速入门及实例
前言spring Boot是Spring社区较新的一个项目。该项目的目的是帮助开发者更容易的创建基于Spring的应用程序和服务,让更多人的人更快的对Spring进行入门体验,让Java开发也能够实现Ruby on Rails那样的生产效率。为Spring生态系统提供了一种固定的、约定优于配置风格的框架。Spring Boot特性Spring Boot具有如下特性:为基于Spring的开发提供更快
前言
spring Boot是Spring社区较新的一个项目。该项目的目的是帮助开发者更容易的创建基于Spring的应用程序和服务,让更多人的人更快的对Spring进行入门体验,让Java开发也能够实现Ruby on Rails那样的生产效率。为Spring生态系统提供了一种固定的、约定优于配置风格的框架。
Spring Boot特性
Spring Boot具有如下特性:
- 为基于Spring的开发提供更快的入门体验
- 开箱即用,没有代码生成,也无需XML配置。同时也可以修改默认值来满足特定的需求。
- 提供了一些大型项目中常见的非功能性特性,如嵌入式服务器、安全、指标,健康检测、外部配置等。
- Spring Boot并不是不对Spring功能上的增强,而是提供了一种快速使用Spring的方式。
官方文档:http://docs.spring.io/spring-boot/docs/current/reference/html/index.html
https://start.spring.io/是官方的提供的,可以快速生成空的项目文件,免去了配置文件等初始化流程。
Spring Boot 实例demo
环境准备:
- 一个称手的文本编辑器(例如Vim、Emacs、Sublime Text)或者IDE(Eclipse、Idea Intellij)
- Java环境(JDK 1.7或以上版本)
- Maven 3.0+(Eclipse和Idea IntelliJ内置,如果使用IDE并且不使用命令行工具可以不安装)
目录结构
有Spring基础的接触Spring Boot应该很快就可以上手的,首先通过上面提供的官方的初始化一个项目,如下是本实例demo是的一个目录结构(环境是IntelliJ):
java目录:用来存放java文件,例如MVC模式的话,存放相关代码
resources目录有static和templates两个子目录,其中static目录存放css/js/images等文件,templates目录存放模板文件,例如xx.vm(Velocity的文件是.vm,Velocity的相关介绍可以参见之前博客http://blog.csdn.net/megustas_jjc/article/details/60596358)
实例demo
程序入口
首先来创建src/main/java/ToutiaoApplication.java:
@SpringBootApplication
public class ToutiaoApplication {
public static void main(String[] args) {
SpringApplication.run(ToutiaoApplication.class, args);
}
}
程序的入口:SpringApplication.run(Application.class, args)
,SpringApplication是Spring Boot框架中描述Spring应用的类,它的run()方法会创建一个Spring应用上下文(Application Context)。另一方面它会扫描当前应用类路径上的依赖,如果Spring Boot判断这是一个Web应用,会启动一个内嵌的Servlet容器(默认是Tomcat)用于处理HTTP请求。
@SpringBootApplication:
Spring Boot提供一个方便的 @SpringBootApplication 选择。该 @SpringBootApplication 注解等价于以默认属性使用 @Configuration+@EnableAutoConfiguration+@ComponentScan
@Configuration :
定义一个配置类,用@Configuration注解该类,等价于XML中配置beans;用@Bean标注方法等价于XML中配置bean
public class SpringConfig {
@Bean
public Piano piano(){
return new Piano();
}
@Bean(name = "counter")
public Counter counter(){
return new Counter(12,"Shake it Off",piano());
}
}
@EnableAutoConfiguration:启动Spring MVC
@ComponentScan:启用组件扫描
实现Hello World显示
在controller目录下创建一个IndexController 类(之后的方法除特殊说明,否则都是IndexController类中的方法),
@Controller
public class IndexController {
@RequestMapping(path = {"/","/index"})
@ResponseBody
public String index(HttpSession session){
return "Hello World" ;
}
}
运行我们的Application文件,右键Run As -> Java Application,之后打开浏览器输入地址:http://127.0.0.1:8080/(或者http://127.0.0.1:8080/ index) 就可以看到Hello world。
@Controller :基于@Component注解,表明是控制类组件,辅助实现组件扫描,组件扫描会自动找到@Controller注解对应的类,并将其声明为Spring应用上下文的一个bean
@RequestMapping:@RequestMapp(value=”/”,method),value值属性指定了这个方法所要处理的请求路径,method属性细化了它所处理的HTTP方法(GET或者POST),例如@RequestMapping(value = "/login", method = RequestMethod.POST)
@RequestBody绑定请求对象,Spring会帮你进行协议转换,将Json、Xml协议转换成你需要的对象。
@ResponseBody可以标注任何对象,由Srping完成对象——协议的转换。
在SpringMVC中,可以使用@RequestBody和@ResponseBody两个注解,分别完成请求报文到对象和对象到响应报文的转换,底层这种灵活的消息转换机制,就是Spring3.x中新引入的HttpMessageConverter即消息转换器机制。
获取请求中信息
//value与path都是别名,实质上是一样的
@RequestMapping(value = {"/profile/{groupId}/{userId}"})
@ResponseBody
//127.0.0.1:8080/profile/12/33?key=xx&type=33
//不要混淆PathVariable与RequestParam
public String profile(
@PathVariable("groupId") String groupId,
@PathVariable("userId") int userId,
@RequestParam(value = "key",defaultValue = "megustas") String key,
@RequestParam(value = "type",defaultValue = "1") int type) {
return String.format("GID{%s},UID{%d},KEY{%s},TYPE{%d}",groupId,userId,key,type);
}
例如//127.0.0.1:8080/profile/12/33?key=xx&type=33,
String.format():Java字符串格式化-静态方法String.format()
@Pathvariable:
当使用@RequestMapping URI template 样式映射时, 即 someUrl/{paramId}, 这时的paramId可通过 @Pathvariable注解绑定它传过来的值到方法的参数上
@RequestParam:获取请求参数
模板渲染
在之前所有的@RequestMapping注解的方法中,返回值字符串都被直接传送到浏览器端并显示给用户。但是为了能够呈现更加丰富、美观的页面,我们需要将HTML代码返回给浏览器,浏览器再进行页面的渲染、显示。
一种很直观的方法是在处理请求的方法中,直接返回HTML代码,但是这样做的问题在于——一个复杂的页面HTML代码往往也非常复杂,并且嵌入在Java代码中十分不利于维护。更好的做法是将页面的HTML代码写在模板文件中(此处使用Velocity模板语言),渲染后再返回给用户。为了能够进行模板渲染,需要将@RestController改成@Controller:
//返回值不再是ResponseBody,返回值是一个模板,模板存放于resources/templates中
@RequestMapping(value = {"/vm"})
//后端与渲染之间铰链的一个数据模型Model,通过Model向前台视图传递参数,Model中存入的数据在Velocity中直接使用
public String news(Model model){
model.addAttribute("value1", "vv1");
List<String> colors = Arrays.asList(new String[]{"RED", "GREEN", "BLUE"});
Map<String, String> map = new HashMap<String, String>();
for (int i = 0; i < 4; ++i) {
map.put(String.valueOf(i), String.valueOf(i * i));
}
model.addAttribute("colors", colors);
model.addAttribute("map", map);
//传递自定义对象
model.addAttribute("user",new User("Megustas"));
return "news";//news.vm
}
在上述例子中,返回值”news”并非直接将字符串返回给浏览器,而是寻找名字为news的模板进行渲染,news.vm文件存放于resources/templates目录下(vm源码见博客最后)。
request/response
一次网页请求中,通过request获取它的所有数据
@RequestMapping(value = {"/request"})
@ResponseBody
public String request(HttpServletRequest request,
HttpServletResponse response,
HttpSession session){
//获取Http请求的头文件
StringBuilder sb = new StringBuilder();
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()){
String name = headerNames.nextElement();
sb.append(name + ":" + request.getHeader(name) + "<br>");
}
for(Cookie cookie : request.getCookies()){
sb.append("Cookie");
sb.append(cookie.getName());
sb.append(":");
sb.append(cookie.getValue());
sb.append("<br>");
}
sb.append("getMethod:" + request.getMethod()+ "<br>");
sb.append("getPathInfo:" + request.getPathInfo()+ "<br>");
sb.append("getQueryString:" + request.getQueryString()+ "<br>");
sb.append("getRequestURI" + request.getRequestURI());
return sb.toString();
}
StringBuilder:
String对象是不可改变的。每次使用 System.String类中的方法之一时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间。在需要对字符串执行重复修改的情况下,与创建新的 String对象相关的系统开销可能会非常昂贵。如果要修改字符串而不创建新的对象,则可以使用System.Text.StringBuilder类。例如,当在一个循环中将许多字符串连接在一起时,使用 StringBuilder类可以提升性能。
Enumeration:
Enumeration接口作用和Iterator类似,提供了遍历元素的功能,其中只定义了两种方法:
boolean hasMoreElements():测试Enumeration对象中是否包含元素,如果有返回true,则表示至少包含一个元素
Object nextElement():如果Enumeration对象还有元素,返回对象的下一个元素,否则抛出NoSuchElementException
request.getQueryString():
request.getQueryString()就是获取查询字符串
即请求?后面的就是QueryString,例如127.0.0.1:8080/request?type=2&&k=xx中,QueryString为type=2&&k=xx,RequestURI为/request
也可以通过HttpServletResponse response将更多数据写回
@RequestMapping(value = {"/response"})
@ResponseBody
public String response(@CookieValue(value="nowcoderid",defaultValue = "a") String nowcoderId,
@RequestParam(value = "key", defaultValue = "key") String key,
@RequestParam(value = "value", defaultValue = "value") String value,
HttpServletResponse response){
response.addCookie(new Cookie(key,value));
response.addHeader(key,value);
return "NowCoderId From Cookie:" + nowcoderId;
}
127.0.0.1:8080/response : NowCoderId From Cookie:a,此时为默认值
127.0.0.1:8080/response?key=nowcoderid&value=22:NowCoderId From Cookie:22
重定向与error
301:永久转移
302:临时转移
首先介绍两种重定向的方式,第二种更简单直接一些:
@RequestMapping("/redirect/{code}")
public RedirectView redirect(@PathVariable("code") int code){
RedirectView red = new RedirectView("/",true);//通过/跳转到首页
if(code == 301){
red.setStatusCode(HttpStatus.MOVED_PERMANENTLY);
}
return red;
}
//一种简单方式的跳转
@RequestMapping("/redirect/{code}")
public String redirect(@PathVariable("code") int code,HttpSession session){
session.setAttribute("msg","Jump from redirect.");
return "redirect:/";
}
通过自定义的方式捕获error:
@RequestMapping("/admin")
@ResponseBody
//可以通过required=false或者true来要求@RequestParam配置的前端参数是否一定要传,required=false表示不传的话,会给参数赋值为null,required=true就是必须要有
public String admin(@RequestParam(value = "key",required = false) String key){
if("admin".equals(key)){
return "hello admin";
}
throw new IllegalArgumentException("Key 错误");
}
//好处是可以用统一的页面处理问题,例如baidu.com/megustas之类的都会统一跳转到一个页面:很抱歉,您要访问的页面不存在
@ExceptionHandler()
@ResponseBody
public String error(Exception e){
return "error:" + e.getMessage();
}
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)