Spring中级课程第一课

一. 创建简单工程
网页SpringBoot
进入[SpringBoot网站][],选择自己需要的依赖(Web,Velocity,AOP),生成工程,减少自己配置的工作量。
打开Idea,导入工程,然后静静等待一会即可。
[SpringBoot网站]:http://start.spring.io/

  1. 简单结构
    web请求--->控制器---->服务---->DAO(--->数据库)
  2. 注解和对应方法参数
//相对路径,参数value和path意义相同,可以写多个,{"/path1","/path2"}
@RequestMapping(value = {"/profile/{groupId}/{userId}"})
// 该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。
//根据返回的字符串,去资源文件夹下找匹配的文件,否则直接返回字符串,
@ResponseBody
//路径参数用PathVariable,请求参数用RequestParam
public String profile(@PathVariable("groupId") String groupId,                      
@PathVariable("userId") int userId,
@RequestParam(value = "type", defaultValue = "1") int type,                      
@RequestParam(value = "key", defaultValue = "nowcoder") String key) {
}
  1. Velocity 模板语法
##获取变量值
$!{变量/表达式}
#*多行
注释*#
##.index 0开始索引,.count为计数
#foreach($color in $colors)
Color$!(foreach.count)/$(foreach.index):$!(color)
#
  1. 资源文件
  2. 静态:static/templates css和images
  3. 模板文件: templates xxx.vn
    a. 模板文件例子1
//java文件
@RequestMapping(value = {"/vm"})
//model 引入变量,多次使用时模板html中可以替换该值
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); 
return "news";
}
//然后可以在模板文件夹下的news.vm文件中调用value1变量
<html>
<body>
<pre>
    Hello, VM
    ##你看不到我(注解格式)
    $!{value1}##有则输出,无则空行
    $!{value2}
    ${value3}##完整输出该字符
##for循环
    #foreach ($color in $colors)
        Color $!{foreach.index}/$!{foreach.count}:$!{color}
    #end
    #foreach($key in $map.keySet())
        Number $!{foreach.index}/$!{foreach.count}:$!{key} $map.get($key)
    #end
    #foreach($kv in $map.entrySet())
        Number $!{foreach.index}/$!{foreach.count}:$!{kv.key} $!{kv.value}
    #end
    User: $!{user.name}
    User: $!{user.getName()}
  
    #set($hello = "hello") ##类似宏定义
    #set($hworld1 = "$!{hello} world")
    #set($hworld2 = '$!{hello} world')
    hworld1: $hworld1
    hworld2: $hworld2
</pre>
</body>
</html>

b. include和parse

##header.vm
Title <h>$!title</h>
##news.vm
##设置title变量值
#set($title = "nowcoder")
Include: #include("header.vm")
Parse: #parse("header.vm")
/*输出 Include: TiTle $!title    Parse: TiTle nowcoder
说明,include嵌入文件,parse还会解析其中的变量*/

c. macro

#macro(render_color, $color, $index)    
    Color By Macro $index, $color
#end
#foreach ($color in $colors)    
    #render_color($color, $foreach.index)
#end
  1. 请求和响应
    a. 请求
    参数解析,cookie读取,http请求字段和文件上传
@RequestMapping(value = {"/request"})
@ResponseBody
//一般都设置这三个参数
public String request(HttpServletRequest req,
HttpServletResponse resp,
HttpSession session){    
StringBuilder sb = new StringBuilder();
//获取请求头的名字,返回枚举类型
Enumeration<String> headerNames = req.getHeaderNames();    
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
sb.append(name + ":" + req.getHeader(name) + "<br>");    
}    
return sb.toString();
}

b. 响应
页面内容返回,cookie下发,http字段设置,headers

@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 resp) {
resp.addCookie(new Cookie(key,value));
resp.addHeader(key, value);
return "NowCoderId From COOkie: " + nowcoderId;}
  1. 重定向
    301:永久转移,第一次访问后记录在浏览器中,再次访问时,直接跳重定向的路径,而不用先访问原地址。
    302:临时转移,直接的方式return "redirect:/"
@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;
}
  1. 错误处理
@RequestMapping("/admin")
@ResponseBodypublic
 String admin(@RequestParam(value = "key", required = false) String key){
    if ("admin".equals(key)) {
        return "Hello admin! ";
    }
//没写异常处理,抛出异常,类似没找到资源,
    throw new IllegalArgumentException("Key 错误");
}
/*结果:Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback.

Wed Nov 16 14:03:51 CST 2016
There was an unexpected error (type=Internal Server Error, status=500).
Key 错误*/
//写异常处理
@ExceptionHandler()
@ResponseBody
public String error(Exception e) {
    return "error: " + e.getMessage();
}
//结果:error: Key 错误
  1. IoC:控制反转分成两种类型,依赖注入(DI)和依赖查找(DL),前者应用比较广泛,IoC一般指前者
//常规方式,通过构造器传参,类中的其他方法就可以调用
//Service.java
public String service(){
 return "service()";
}
//Application.java
public String application(){
   private Service service;
   public Application(Service service){
         this.service = service;
   }
}
//注解方式,通过使用注解,spring自动匹配,可以直接调用,更方便
//Service.java
@Service
public String service(){
 return "service()";
}
//Application.java
public String application(){
   @AutoWired
   private Service service;
   }
}
  1. AOP:面向切面编程,所有业务都要处理的业务,比如log服务
@Aspect
@Component
public class LogAspect {
    private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
    @Before("execution(* com.nowcoder.controller.*Controller.*(..))")
    public void beforeMethod(JoinPoint joinPoint) {
        StringBuilder sb = new StringBuilder();
        for (Object arg : joinPoint.getArgs()) {
            sb.append("arg:" + arg.toString() + "|");
        }
        logger.info("before time: " + new Date());
        logger.info("before method: "+ sb.toString());
    }
    @After("execution(* com.nowcoder.controller.IndexController.*(..))")
    public void afterMethod() {
        logger.info("after method: ");
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,497评论 18 139
  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 12,712评论 0 33
  • 1、Spring MVC请求流程 (1)初始化:(对DispatcherServlet和ContextLoderL...
    拾壹北阅读 1,941评论 0 12
  • 百科说,自卑是一种不能自助和软弱的复杂情感。有自卑的人轻视自己,认为无法赶上别人。汉语词典说,自卑是指自己看不起...
    隰有扶苏阅读 443评论 0 0
  • 这篇文章指出了Java中checked Exception的一些缺点,提出应该在程序设计中避免使用checked ...
    Jabari阅读 823评论 0 1