天天看點

springBoot--web開發springBoot–web開發

springBoot–web開發

重要 : 你導入了這個才能在通過controller轉發到templates下的html頁面。如果不通過controller轉發是通路不到html頁面的。但是放到static下的HTML頁面可以直接通路到通過網頁url位址。

更改:隻要是通過控制器controller的轉發的頁面,不論在哪裡如果浏覽器直接通路都會通路不到。隻能發請求讓控制器去處理轉發頁面,必須經過控制器。

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
           
  1. resources下的靜态資源目錄結構
    Spring Boot serves static content from a directory  called /static (or /public or /resources or /META-INF/resources)
               
    就是說springboot 的靜态資源可以放在這些目錄下。即使是/META-INF/resources/apple.jpg,你也可以直接通過8080/apple.jpg通路。就是項目的根路徑+你的資源名。
    resources are mapped on /** 他将這些映射到了/**
               
    請求進來,先去找Controller看能不能處理。不能處理的所有請求又都交給靜态資源處理器。靜态資源也找不到則響應404頁面
    spring.mvc.static-path-pattern=/resources/**
               
    1. web應用,攔截器的使用。比如登陸需要攔截未登陸使用者的動态請求。/**就把所有的請求都攔截了。可以在杠星星前加一個字首。。。使用上面的屬性來配置靜态資源通路字首
    2. 你也可以使用你指定的目錄作為靜态資源目錄
      You can also customize the static resource locations by using the spring.web.resources.static-locations
                 
    3. 給你的網頁标題旁邊加上小圖示。格式為favicon.ico。可以f12别的網頁,然後在net搜尋這個favicon.ico,把小圖示下載下傳下來自己用,不過有點問題是你放到了static但是還是通路不到。這時候直接打開項目的target把圖檔放進去。可能是因為沒有編譯進去,然後就會報404
  2. 請求處理
    1. Rest風格的支援
      spring:
        mvc:
          hiddenmethod:
            filter:
              enabled: true   #開啟頁面表單的Rest功能
                 
      1. html頁面
      <form method="post">
          <input name="_method" type="hidden" value="DELETE"/>
      </form>
                 
      1. 或者使用PostMan
    2. 請求參數
      1. 注解

        @PathVariable、@RequestHeader、@ModelAttribute、@RequestParam、@MatrixVariable、@CookieValue、@RequestBody

        1. @PathVariable rest風格擷取url路徑中的參數
        @GetMapping("/car/{id}/owner/{username}")
         public Map<String,Object> getCar(@PathVariable("id") Integer id,
                                             @PathVariable("username") String name,
                                             @PathVariable Map<String,String> pv,){}
         可一個一個擷取路徑中的參數,也可以使用map擷取所有的參數,key-value
                   
        1. @RequestHeader擷取請求頭中的參數
          @RequestHeader("User-Agent") String userAgent,
          @RequestHeader Map<String,String> header,//擷取所有
                     
        2. @RequestParam 擷取請求的參數
          //OC2020/user/login?name=123&inters=a&inters=b
           @RequestParam("name") String name,//擷取一個參數的值
          @RequestParam("inters") List<String> inters,//擷取多個同名參數的值
                     
        3. @CookieValue 擷取cookie中的值
          @CookieValue("_ga") String _ga,
          @CookieValue("_ga") Cookie cookie//擷取cookie對象
                     
        4. @RequestBody 擷取請求體,post請求的表單資料 , @RequestBody String content
        5. @RequestAttribute
          package com.w.contro;
          
          import lombok.extern.slf4j.Slf4j;
          import org.springframework.stereotype.Controller;
          import org.springframework.web.bind.annotation.*;
          
          import javax.servlet.http.HttpServletRequest;
          
          @Slf4j
          //@RestController 相當于@Controller,@ResponseBody
          @Controller
          public class contro {
          
              @RequestMapping("/hello")
              public String hell(HttpServletRequest request){
          
                  log.info("請求進來了");
                  request.setAttribute("msg","cuowu");
                  request.setAttribute("code",200);
                  return "forward:/success";//請求轉發
              }
          
              @GetMapping("/success")
              @ResponseBody
              public String suce(@RequestAttribute("msg") String msg,HttpServletRequest request){//還是同一次請求
                  System.out.println(msg);
                  int code = (int)request.getAttribute("code");//在同一次請求中域中資料存在
                  return "code";
              }
          //在控制台列印出cuowu,頁面通路 /hello顯示出200
          }
          
                     
        6. 矩陣變量文法: 請求路徑:/cars/sell;low=34;brand=byd,audi,yd

          cookie和session,session中存入資料。每次請求都攜帶cookie–》jsessionId–>然後通過id在session中找到資料

          2、SpringBoot預設是禁用了矩陣變量的功能

      2. servlet API

        WebRequest、ServletRequest、MultipartRequest、 HttpSession、javax.servlet.http.PushBuilder、Principal、InputStream、Reader、HttpMethod、Locale、TimeZone、ZoneId

      3. 複制參數

        Map、**Model(map、model裡面的資料會被放在request的請求域 request.setAttribute)、**Errors/BindingResult、RedirectAttributes( 重定向攜帶資料)、ServletResponse(response)、SessionStatus、UriComponentsBuilder、ServletUriComponentsBuilder

    3. web實驗
      @RequestMapping(value = {"/","/login"})//進入項目直接通路登陸頁面
          public String Index(){
              return "Ican";
          }
                 

      至于怎麼樣區分真正的登陸請求,可以在類上多加一個@RequestMapping,多一級路徑。

      或者使用rest風格的

      @GetMapping
      @PostMapping 這樣來區分
                 
      1. 解決登陸成功回退home頁面一要求重新發表單問題

        如果登陸請求處理成功之後使用請求轉發,那麼return回home頁面會要求重新發送表單。此時如果請求轉發登陸成功位址欄還是你登陸的那個請求,是以會重新發送表單。

        @PostMapping("/login")
            public String main(User user, HttpSession session, Model model){
        
                if(StringUtils.hasLength(user.getUserName()) && "123456".equals(user.getPassword())){
                    //把登陸成功的使用者儲存起來
                    session.setAttribute("loginUser",user);
                    //登入成功重定向到main.html;  重定向防止表單重複送出
                    return "redirect:/main.html";
                }else {
                    model.addAttribute("msg","賬号密碼錯誤");
                    //回到登入頁面
                    return "login";
                }
        
            }
                   
      2. 攔截器
        1. 編寫攔截類實作HandlerInterceptor接口
          package com.w.interceptor;
          
          import lombok.extern.slf4j.Slf4j;
          import org.springframework.web.servlet.HandlerInterceptor;
          
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          import javax.servlet.http.HttpSession;
          
          @Slf4j
          public class Interceptor implements HandlerInterceptor {
          	
              //方法執行前
              @Override
              public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
          
          
                  String requestURI = request.getRequestURI();
                  log.info("preHandle攔截的請求是:",requestURI);
          
                  HttpSession session = request.getSession();
                  Object ok = session.getAttribute("ok");
          
                  if (ok != null){
                      //放行
                      return true;
                  }else{
                      //攔截到,跳轉到留言界面
                      request.setAttribute("msg","先發個留言呗!");
                      request.getRequestDispatcher("/wall").forward(request,response);
                      return false;
                  }
          
          
              }
          }
          
                     
          1. 攔截器注冊到容器中(實作WebMvcConfigurer的addInterceptors)
            package com.w.config;
            
            import com.w.interceptor.Interceptor;
            import org.springframework.context.annotation.Configuration;
            import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
            import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
            
            /**
             * 1、編寫一個攔截器實作HandlerInterceptor接口
             * 2、攔截器注冊到容器中(實作WebMvcConfigurer的addInterceptors)
             * 3、指定攔截規則【如果是攔截所有,靜态資源也會被攔截】
             */
            @Configuration
            public class LybWebConfig implements WebMvcConfigurer {
                @Override
                public void addInterceptors(InterceptorRegistry registry) {
                    registry.addInterceptor(new Interceptor())
                            .addPathPatterns("/getAll");
            			// .addPathPatterns("/**")  //所有請求都被攔截包括靜态資源
                         //   .excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**"); //放行的請求
                }
            }
            
                       
          2. 所有在templates下的頁面,必須經過控制器。
        2. 檔案上傳
          1. 頁面表單
            <form method="post" action="/upload" enctype="multipart/form-data">
                <input type="file" name="file"><br>
                <input type="submit" value="送出">
            </form>
                       
          2. 背景代碼
            /**
                 * MultipartFile 自動封裝上傳過來的檔案
                 * @param email
                 * @param username
                 * @param headerImg
                 * @param photos
                 * @return
                 */
                @PostMapping("/upload")
                public String upload(@RequestParam("email") String email,
                                     @RequestParam("username") String username,
                                     @RequestPart("headerImg") MultipartFile headerImg,
                                     @RequestPart("photos") MultipartFile[] photos) throws IOException {
            
                    log.info("上傳的資訊:email={},username={},headerImg={},photos={}",
                            email,username,headerImg.getSize(),photos.length);
            
                    if(!headerImg.isEmpty()){
                        //儲存到檔案伺服器,OSS伺服器
                        String originalFilename = headerImg.getOriginalFilename();
                        headerImg.transferTo(new File("H:\\cache\\"+originalFilename));
                    }
            
                    if(photos.length > 0){
                        for (MultipartFile photo : photos) {
                            if(!photo.isEmpty()){
                                String originalFilename = photo.getOriginalFilename();
                                photo.transferTo(new File("H:\\cache\\"+originalFilename));
                            }
                        }
                    }
            
            
                    return "main";
                }