技術點積累

1. 通用分頁條展現思路分析

1. 構建分頁條數據:頁碼列表,分頁條的本質就是在頁面顯示頁碼列表
  • 已知當前頁pageNum和總頁數totalPages,根據每頁要求顯示的頁碼列表的條數,得出頁碼列表的頭startPage和尾endPage,在頁面循環列表,便可展現出分頁條。javascript

  • 分頁列表頭和尾的肯定:假設頁面要求顯示10個頁碼,那麼能夠選擇以當前頁前4後5的顯示方式,肯定顯示方式後,即可以計算頭尾以構建分頁列表。html

  Integer startPage = pageNum - 4;
Integer endPage = pageNum + 5;
if (startPage < 1){ //判斷列表頭startPage是否 < 1
   startPage = 1;
   endPage = startPage + 9;
}
if (endPage > totalPage){ //判斷列表尾endPage是否 > totalPages
   endPage = totalPage;
   startPage = endPage - 9;
}
  • 在頁面獲取以startPage爲頭endPage爲尾的列表,並循環展現分頁條前端

2. 先後端數據交互
  • 前端請求參數:pageNo、pageSize、QueryParamsvue

  • 後端響應數據:java

    • html異步請求:git

      PageBean<T> {pageNo,pageSize,totalCount,totalPage,List<T> result,QueryParams}github

      能夠在js中定義startPage和endPageweb

    • 模板頁同步請求:redis

      PageBean<T> {pageNo,pageSize,totalCount,totalPage,List<T> result,QueryParams,startPage,endPage}spring

3. 頁碼選中狀態顯示

是否選中狀態的通用思路:定義一個變量n記錄選中狀態的狀態值,而後把當前變量與n比較,若是當前變量等於n記錄的選中狀態值,那麼當前變量即選中狀態

  • 這裏循環頁碼列表獲取的變量page和當前頁pageNum(記錄選中狀態的變量n)比較,若是page==pageNum,那麼page對應的頁碼列表中頁碼即開啓選中狀態

  
<li th:class="${page==pageNo?'active':''}" th:each="page:${#numbers.sequence(startPage,endPage)}">
   <a th:href="${#strings.replace(url,'&pageNo='+pageNo,'&pageNo='+page)}" th:text="${page}"></a>
</li>
 
  • 引入分頁助手

  
<dependency>
   <groupId>com.github.pagehelper</groupId>
   <artifactId>pagehelper</artifactId>
   <version>3.7.5</version>
</dependency>
  • 加強

  
@Override
public PageResult<Brand> findPage(Integer page, Integer size) {
   //PageHelper.startPage設置分頁,加強方法體
   PageHelper.startPage(page,size);
   //Page<T>接收查詢結果,加強返回值
   Page<Brand> pageResult = (Page<Brand>) brandMapper.selectAll();
   return new PageResult<>(pageResult.getTotal(), pageResult.getResult());
}

 

2. 服務端頁面渲染技術Thymeleaf

  • thymeleaf與vue.js不一樣之處在於thymeleaf是在服務端渲染完成後,再將靜態頁面發給前臺,相比前端vue.js發送異步請求獲取數據後,再在前臺進行渲染的狀況, thymeleaf不會出現頁面內容延遲加載的情況;

  • thymeleaf與jsp同樣, 都是服務端渲染頁面, 但thymeleaf相比jsp具備更強大的功能, 同時thymeleaf也是springboot官方推薦的渲染引擎, thymeleaf能夠類比爲更高級的jsp

1. 生成靜態頁面:
  • 添加thymeleaf依賴

  
<dependencies>
   <dependency>
       <groupId>org.thymeleaf</groupId>
       <artifactId>thymeleaf</artifactId>
       <version>3.0.11.RELEASE</version>
   </dependency>
</dependencies>
  • 在applicationContext-thymeleaf.xml中配置模版引擎、視圖解析器、模版解析器

  
<!-- 配置模板引擎 -->
<bean id="templateEngine"
     class="org.thymeleaf.spring5.SpringTemplateEngine">
   <property name="templateResolver" ref="templateResolver"/>
</bean>
<!-- 配置視圖解析器 -->
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
   <property name="templateEngine" ref="templateEngine"/>
   <property name="characterEncoding" value="UTF-8"/>
</bean>
<!-- 配置模板解析器 -->
<bean id="templateResolver"
     class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
   <property name="prefix" value="/WEB-INF/templates/"/>
   <property name="suffix" value=".html"/>
   <property name="characterEncoding" value="UTF-8"/>
   <property name="templateMode" value="HTML"/>
</bean>
  • 在webapp/WEB-INF目錄下建立模板資源test.html

  • 建立上下文對象Context, 用於向模版傳遞數據模型Map

  
//1. 建立上下文對象,傳遞數據模型
Context context = new Context();
Map<String,Object> dataModel = new HashMap<>();
//查詢頁面渲染須要的數據(主要業務邏輯,此處略...)
dataModel.put("name",object);
context.setVariables(dataModel);
  • 建立目標文件輸出流對象PrintWriter,調用模板引擎的process方法向生成靜態頁面目標文件

  
@Value("${pagePath}")
private String pagePath;
try {
   //2. 建立目標文件輸出流對象
   File dir = new File(pagePath);
   if (!dir.exists()){
       dir.mkdirs();
  }            
   File dest = new File(pagePath + sku.getId() + ".html");
   PrintWriter pw = new PrintWriter(dest, "UTF-8");
   //3. 生成目標靜態頁面文件
   templateEngine.process("item",context,pw);
} catch (FileNotFoundException e) {
   e.printStackTrace();
} catch (UnsupportedEncodingException e) {
   e.printStackTrace();
}
2. 直接動態渲染
  
@Controller//這裏直接轉發至服務端模板頁面渲染,而不是返回數據給前端,因此不須要用RestController
public class IndexController {
   @RequestMapping("/index")
   public String index(Model model){
       //注意和生成靜態頁面區別,這裏是直接return模版頁面渲染,而不是經過流生成靜態頁面
       return "index";
  }
}
3. 經常使用頁面標籤
標籤 說明 示例
th:text 指定文本內容 <p th:text="${collect.description}"></p>
th:utext 支持html內容渲染 <p th:utext="${htmlcontent}"></p>
th:each 1. 循環列表,userStat爲循環狀態量, 有index/count/current/even/odd/first/last等屬性;2. 循環map集合,param.key、param.value分別獲取map的鍵值 <tr th:each="user:${users}"></tr>或者<tr th:each="param : ${params}" th:text = "${param.key + ':' + param.value}"></tr>
th:if 判斷是否顯示當前標籤 <a th:if="${userId == collect.userId}" >
th:href 連接地址 <a th:href="${url}"/>
th:src 圖片類地址引入 <img th:src="${user.image}" />
th:inline 定義js腳本可使用渲染變量數據,使用方法:url = url.replace("&pageNo="+/星號[[${pageNo}]]星號/, "&pageTo="+pageTo) <script th:inline="javascript">
numbers.formatDecimal 保留兩位小數 ${#numbers.formatDecimal(arg,0,2) }
numbers.sequence 以startPage、endPage爲頭尾生成列表,默認步長值爲1 ${#numbers.sequence(startPage,endPage)}
strings.replace 替換字符串 ${#strings.replace(url,'abc','cba')}
strings.startWith 判斷字符串是否以某子串開頭(boolean) ${#strings.startsWith(url,'http')}
strings.substring 截取字符串子串,指定開始索引 ${#strings.substring(url,5)
maps.containsKey 判斷Map集合是否包含某個key ${#maps.containsKey(searchMap,'category')}

 


 

3. SpringDataRedis——RedisTemplate

1. 引入依賴
  
<!-- 鏈接redis服務器 -->
<dependency>
   <groupId>redis.clients</groupId>
   <artifactId>jedis</artifactId>
   <version>2.9.0</version>
</dependency>
<!-- 引入spring-data-redis -->
<dependency>
   <groupId>org.springframework.data</groupId>
   <artifactId>spring-data-redis</artifactId>
   <version>2.0.5.RELEASE</version>
</dependency>
2. 配置spring提供的RedisTemplate

SpringDataRedis底層封裝了jedis,因此先配置JedisConnectionFactory,再注入到RedisTemplate中

  
<!-- Jedis鏈接配置對象JedisPoolConfig -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">  
   <property name="maxIdle" value="${redis.maxIdle}" />  
   <property name="maxWaitMillis" value="${redis.maxWait}" />  
</bean>  
<!-- Jedis鏈接工廠JedisConnectionFactory -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
     p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}" p:pool-config-ref="poolConfig"/>  
<!-- spring提供的模板工具redisTemplate -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">  
   <property name="connectionFactory" ref="jedisConnectionFactory" />
</bean>
3. 在代碼中注入RedisTemplate對象,綁定大Key,操做redis
  • 對象操做:boundValueOps

  
public void setValue(){
   redisTemplate.boundValueOps("name").set("青橙電商");
}
public void getValue(){
   String name = (String) redisTemplate.boundValueOps("name").get();
   System.out.println(name);
}
public void deleValue(){
   redisTemplate.delete("name");
}
  • Set集合操做:boundSetOps

  public void setValue(){
   redisTemplate.boundSetOps("nameSet").add("曹操");
   redisTemplate.boundSetOps("nameSet").add("劉備");
   redisTemplate.boundSetOps("nameSet").add("孫權");
}
public void getValue(){
   Set nameSet = redisTemplate.boundSetOps("nameSet").members();
   System.out.println(nameSet);
}
public void deleValue(){
   redisTemplate.boundSetOps("nameSet").remove("曹操");
   System.out.println(redisTemplate.boundSetOps("nameSet").members());

   redisTemplate.delete("nameSet");
}

 

  • Map集合操做:boundHashOps

  
public void setValue(){
   redisTemplate.boundHashOps("nameHash").put("0","唐僧");
   Map<String,String> map = new HashMap();
   map.put("1","悟空");
   map.put("2","八戒");
   map.put("3","沙僧");
   redisTemplate.boundHashOps("nameHash").putAll(map);
}
public void getValue(){
   String name = (String) redisTemplate.boundHashOps("nameHash").get("1");
   System.out.println(name);
}
public void deleValue(){
   redisTemplate.boundHashOps("nameHash").delete("2");
   System.out.println(redisTemplate.boundHashOps("nameHash").values());
}
  • 有序隊列操做(存取順序):boundListOps

  
public void setValue(){
   redisTemplate.boundListOps("nameList").rightPush("中間值");
   redisTemplate.boundListOps("nameList").rightPush("右壓棧");
   redisTemplate.boundListOps("nameList").leftPush("左壓棧");
   redisTemplate.boundListOps("nameList").rightPush("測試刪除的索引位置");
   redisTemplate.boundListOps("nameList").rightPush("測試刪除");
   redisTemplate.boundListOps("nameList").rightPush("測試刪除");
}
public void getValue(){
   List nameList = redisTemplate.boundListOps("nameList").range(0, -1);
   System.out.println(nameList);
   //按索引取值
   String valueOfIndex = (String) redisTemplate.boundListOps("nameList").index(1);
   System.out.println(valueOfIndex);
}
public void deleValue(){
   //remove(刪除的元素個數, 刪除的元素值); 按索引從小到大查詢指定個數的元素並刪除
   redisTemplate.boundListOps("nameList").remove(2,"測試刪除");
   System.out.println(redisTemplate.boundListOps("nameList").range(0,-1));
}
  • 有序隊列操做(須要常常發生順序變更的狀況):boundZSetOps

  
public void setValue(){
   redisTemplate.boundZSetOps("nameZset").add("曹操",10000);
   redisTemplate.boundZSetOps("nameZset").add("劉備",1000);
   redisTemplate.boundZSetOps("nameZset").add("孫權",10);
}
public void getValue(){
   //分數由低到高排序(默認)
   Set<String> nameZset1 = redisTemplate.boundZSetOps("nameZset").range(0, -1);
   System.out.println(nameZset1);
   //分數由高到低排序(逆向)
   Set<String> nameZset2 = redisTemplate.boundZSetOps("nameZset").reverseRange(0, -1);
   System.out.println(nameZset2);
   //帶分數取值
   Set<ZSetOperations.TypedTuple> nameTupleSet = redisTemplate.boundZSetOps("nameZset").rangeWithScores(0, -1);
   for (ZSetOperations.TypedTuple nameTuple : nameTupleSet) {
       System.out.println(nameTuple.getValue()+"..."+nameTuple.getScore());
  }
}
public void incrementScore(){
   redisTemplate.boundZSetOps("nameZset").incrementScore("孫權",1190);
   System.out.println(redisTemplate.boundZSetOps("nameZset").range(0,-1));
}
public void deleValue(){
   redisTemplate.boundZSetOps("nameZset").remove("孫權");
   System.out.println(redisTemplate.boundZSetOps("nameZset").range(0,-1));
}
  • 通用操做:

    1. redisTemplate. delete(redisKey); 刪除redisKey-value的方法 ; . redisTemplate. boundXxxOps(). expire(long , TimeUnit); 指定大Key的存活時間(短信驗證碼)

    2. 取不到對象, 返回null; 取不到集合, 返回[ ]


 

4. Java 8 日期、時間API(java.time.*)

LocalDate不可用做前端傳參,能夠用String接收日期對象,再用LocalDate轉換

1. 經常使用時間類
  • LocalDate:表示默認格式yyyy-MM-dd的日期對象

    LocalDate today = LocalDate.now():獲取當前日期對象

    LocalDate firstDayOf2019 = LocalDate.of(2019, Month.JANUARY, 1):獲取指定日期對象

  • LocalTime:表示默認格式hh:mm:ss.zzz的時間對象

    LocalTime time = LocalTime.now():獲取當前時間對象

    LocalTime specTime = LocalTime.of(23,23,23,23):獲取指定時間對象23:23:23.023

  • LocalDateTime:表示日期+時間對象

    LocalDateTime time = LocalDateTime.now():獲取當前日期時間對象

    LocalDateTime firstDayOf2019 = LocalDate.of(2019, Month.JANUARY, 1,0,0,0,0):獲取指定日期時間對象

2. 日期時間API工具
API 說明
LocalDate#isBefore(LocalDate date) 判斷是否在指定日期以前
LocalDate#plusDays/plusWeeks/plusMonths/minus.. 從當前日期加減日、周、月後獲得日期
Period period LocalDate#until(LocalDate date) 獲取到指定日期之間的天數
LocalDate#format(DateTimeFormatter.ofPattern("dd-MM-yyyy")) 按指定格式格式化日期對象
LocalDate.parse("yyyy-MM-dd") 解析日期字符串

 

5. 阿里大於短信微服務

1. 添加依賴
  
<dependency>
   <groupId>com.aliyun</groupId>
   <artifactId>aliyun-java-sdk-core</artifactId>
   <version>4.0.3</version>
</dependency>
2. 配置文件
  
accessKeyId=LTAIfWgh9uJxqyJM
accessSecret=NMzCzy7mGry292XYlaTRxVmRVOsDL7
#短信模版號
smsCode=SMS_173341860
#生成的驗證碼
param={"code":"[value]"}
3. 短信工具類SmsUtil
  
public class SmsUtil {
   @Value("${accessKeyId}")
   private String accessKeyId;
   @Value("${accessSecret}")
   private String accessSecret;
   public CommonResponse sendSms(String phone, String smsCode, String param){
       DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessSecret);
       IAcsClient client = new DefaultAcsClient(profile);
       CommonRequest request = new CommonRequest();
       request.setMethod(MethodType.POST);
       request.setDomain("dysmsapi.aliyuncs.com");
       request.setVersion("2017-05-25");
       request.setAction("SendSms");
       request.putQueryParameter("RegionId", "cn-hangzhou");
       request.putQueryParameter("SignName", "青橙");
       request.putQueryParameter("PhoneNumbers",phone);
       request.putQueryParameter("TemplateCode", smsCode);
       request.putQueryParameter("TemplateParam", param);
       try {
           CommonResponse response = client.getCommonResponse(request);
           return response;
      } catch (Exception e) {
           e.printStackTrace();
           return null;
      }
  }
}

 

6. Spring-Security安全框架入門(認證)

1. 引入spring-security依賴
  
<dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-web</artifactId>
   <version>${spring.version}</version>
</dependency>
<dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-config</artifactId>
   <version>${spring.version}</version>
</dependency>
2. 建立spring-security.xml配置文件
  
<!--基本配置:
1. 非目標資源解除攔截規則、目標資源攔截規則(<http>)
   2. 認證管理器:自定義認證信息提供者(UserDetailsService);密碼加密策略(BCrypt)-->

<!-- 1. 配置頁面的攔截規則 -->
<!-- 1.1 解除非目標資源的攔截規則 -->
<http pattern="/login.html" security="none"></http>
<http pattern="/login_error.html" security="none"></http>
   <!-- 1.2 配置目標資源(全部資源)必須擁有ROLE_ADMIN的角色才能訪問 -->
<http>
   <intercept-url pattern="/**" access="hasRole('ROLE_ADMIN')"/>
   <!-- 指定登錄頁面/目標訪問頁面/認證失敗頁面, 全部的頁面必須使用絕對路徑配置 -->
   <form-login login-page="/login.html" default-target-url="/index.html" authentication-failure-forward-url="/login_error.html" />
   <!-- 退出登陸 -->
   <logout />
   <!-- 關閉csrf驗證: 跨站請求僞造,csrf會隨機產生一個token放到security提供的默認表單中,由於靜態頁沒法動態生成token,因此將此功能關閉。通常靜態頁採用圖形驗證碼的方式實現防止跨域請求僞造的功能。 -->
   <csrf disabled="true"/>
</http>

<!-- 2. 配置認證管理器,獲取來自數據庫的認證信息 -->
<authentication-manager>
   <authentication-provider user-service-ref="userDetailsService">
       <password-encoder ref="bcryptEncoder"></password-encoder>
   </authentication-provider>
</authentication-manager>
<!-- 2.1 配置自定義認證信息提供者UserDetailsService -->
<beans:bean id="userDetailsService" class="com.qingcheng.demo.UserDetailsServiceImpl"></beans:bean>
<!-- 2.2 加密策略:指定由spring-security提供的相應的解密類 -->
<beans:bean id="bcryptEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"></beans:bean>
</beans:beans>
3. 建立自定義認證信息提供者UserDetailsService
  
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.ArrayList;
import java.util.List;

/** UserDetailsService是spring-security提供的用於從數據庫獲取用戶認證信息,並用UserDatils接口把"認證信息"傳給認證管理器的工具接口
*/
public class UserDetailsServiceImpl implements UserDetailsService {
   public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
       List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
       grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));

       //參數三爲用戶所具備的認證角色集合
       return new User(username,"$2a$10$amAQ3ClrcXV5K9gg6fsbfuUtdgliLTGvfzZuN3toBDAkbSK1nQliC",
                       grantedAuthorities);
  }
}

 

7. 集合流式操做Stream

1. 生成Stream流的方式
  • Collection體系集合

    使用默認方法stream()生成流, default Stream<E> stream()

  • Map體系集合

    把Map轉成Set集合,間接的生成流

  • 數組

    經過Stream靜態方法 Stream.of(T... values) 生成流

  
public class StreamDemo {
   public static void main(String[] args) {
       //Collection體系的集合可使用默認方法stream()生成流
       List<String> list = new ArrayList<String>();
       Stream<String> listStream = list.stream();
       Set<String> set = new HashSet<String>();
       Stream<String> setStream = set.stream();

       //Map體系的集合間接的生成流
       Map<String,Integer> map = new HashMap<String, Integer>();
       Stream<String> keyStream = map.keySet().stream();
       Stream<Integer> valueStream = map.values().stream();
       Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream();

       //數組能夠經過Stream接口的靜態方法of(T... values)生成流
       String[] strArray = {"hello","world","java"};
       Stream<String> strArrayStream = Stream.of(strArray);
       Stream<String> strArrayStream2 = Stream.of("hello", "world", "java");
       Stream<Integer> intStream = Stream.of(10, 20, 30);
  }
}
2. Stream的常見操做方法
方法名 說明
Stream<T> filter(Predicate predicate) 用於對流中的數據進行過濾
Stream<T> limit(long maxSize) 返回此流中的元素組成的流,截取前指定參數個數的數據
Stream<T> skip(long n) 跳過指定參數個數的數據,返回由該流的剩餘元素組成的流
static <T> Stream<T> concat(Stream a, Stream b) 合併a和b兩個流爲一個流
Stream<T> distinct() 返回由該流的不一樣元素(根據Object.equals(Object) )組成的流
Stream<T> sorted() 返回由此流的元素組成的流,根據天然順序排序
Stream<T> sorted(Comparator comparator) 返回由該流的元素組成的流,根據提供的Comparator進行排序
<R> Stream<R> map(Function mapper) 返回由給定函數應用於此流的元素的結果組成的流
IntStream mapToInt(ToIntFunction mapper) 返回一個IntStream其中包含將給定函數應用於此流的元素的結果
void forEach(Consumer action) 對此流的每一個元素執行操做
List collect(Collectors. toList()) 把元素收集到List集合中
Set collect(Collectors. toSet()) 把元素收集到Set集合中
Map collect(Collectors. toMap(Function keyMapper,Function valueMapper)) 把元素收集到Map集合中:(keyMapper,valueMapper)分別表示從流中元素獲取key和value的方法
  • filter、skip、limit、forEach、collect

  
public class StreamDemo01 {
   public static void main(String[] args) {
       ArrayList<String> list = new ArrayList<String>();
       list.add("林青霞");
       list.add("張曼玉");
       list.add("王祖賢");
       list.add("柳巖");
       list.add("張敏");
       list.add("張無忌");
       //需求1:把list集合中以張開頭的,長度爲3的元素在控制檯輸出
       list.stream().filter(s -> s.startsWith("張")).filter(s -> s.length() == 3).forEach(System.out::println);
       //需求2:跳過2個元素,把剩下的元素中前2個取出存入集合中
       List newList = list.stream().skip(2).limit(2).collect(Collectors.toList);
  }
}
  • map、mapToInt —— IntStream. min() max() sum();

  
public class StreamDemo05 {
   public static void main(String[] args) {
       ArrayList<String> list = new ArrayList<String>();
       list.add("10");
       list.add("20");
       list.add("30");
       list.add("40");
       list.add("50");
       
       //int sum() 返回此流中元素的總和
       int result = list.stream().mapToInt(Integer::parseInt).sum();
       System.out.println(result);
  }
}

 

8. SpringDataMongodb

8.1 Mongodb

Mongodb存儲的數據是JSON格式的,相比較redis而言能夠存儲大的文件數據。一方面mongodb能夠靈活存儲json,另外一方面存儲的數據相比於數據庫的核心數據不過重要,且沒有事務管理要求。

​ 1. model

  
@Document(collection = "cms_page")//collection至關於Mysql中的表的概念
public class CmsPage {
   @Id
   private String pageId;
   private String siteId;
   //....
}

​ 2. dao

  
public interface CmsPageRepository extends MongoRepository<CmsPage,String> {
}

​ 3. 基本方法

  
//1. 查詢全部
List<CmsPage> all = cmsPageRepository.findAll();

//2. 分頁查詢
int page = 0; //頁碼從0開始
int size = 10;
Pageable pageable = PageRequest.of(page,size);
Page<CmsPage> all = cmsPageRepository.findAll(pageable);
List<CmsPage> cmsPageList = all.getContent(); //獲取數據
long total = all.getTotalElements(); //獲取記錄數

//3. 條件查詢
   //建立條件值對象
   CmsPage cmsPage = new CmsPage();
   //設置條件值
   cmsPage.setSiteId("5a751fab6abb5044e0d19ea1");
   cmsPage.setTemplateId("5a962b52b00ffc514038faf7");
   cmsPage.setPageAliase("導航");
//ExampleMatcher.GenericPropertyMatchers.contains() 包含關鍵字"導航"匹配
//ExampleMatcher.GenericPropertyMatchers.startsWith() 前綴匹配
   ExampleMatcher exampleMatcher = ExampleMatcher.matching().withMatcher("pageAliase", ExampleMatcher.GenericPropertyMatchers.contains()); // 設置pageAliase字段模糊匹配
   //建立條件實例
   Example<CmsPage> example = Example.of(cmsPage,exampleMatcher);
   Page<CmsPage> all = cmsPageRepository.findAll(example, pagebale);

//4. 添加
CmsPage cmsPage = cmsPageRepository.save(cmsPage);

//根據id查詢
Optional<CmsPage> optional = cmsPageRepository.findById(id);
if (optional.isPresent()){
   CmsPage cmsPage = optional.get();
   return cmsPage;
}
return null;
8.2 GridFS

GridFS是Mongodb提供的用於持久化存儲文件的模塊。它的工做原理是將文件按256kb的大小分割進行存儲,GridFS用兩個collection存儲文件,一個是chunks,用於存儲文件的二進制數據,一個是files,用於存儲文件的元數據(文件名稱、塊大小、上傳時間等)

  
1. GridFS存儲文件
  
@Autowired
private GridFsTemplate gridFsTemplate;

public void testStoreBannerFtl() throws FileNotFoundException {
   //建立文件輸入流對象
   File file = new File("E:\\IdeaProjects\\xcEduService\\test-freemarker\\src\\main\\resources\\templates\\index_banner.ftl");
   FileInputStream fileInputStream = new FileInputStream(file);
   //用GridFSTemplate存儲文件,返回存儲文件的ObjectId
   ObjectId objectId = gridFsTemplate.store(fileInputStream, "輪播圖模板測試用");
   System.out.println(objectId);
}
  1. GridFS獲取文件

  
@Autowired
private GridFsTemplate gridFsTemplate;
@Autowired
private GridFSBucket gridFSBucket;

public void testQueryBannerFtl() throws IOException {
   String fileId = "5d83aaa0f06eb11714b0cd5a";
   //用GridFsTemplate根據id查詢文件對象
   GridFSFile gridFSFile = gridFsTemplate.findOne(Query.query(Criteria.where("_id").is(fileId)));
   //用gridFSBucket打開下載流對象
   GridFSDownloadStream gridFSDownloadStream = gridFSBucket.openDownloadStream(gridFSFile.getObjectId());
   //建立gridFsResource,用於獲取流對象
   GridFsResource gridFsResource = new GridFsResource(gridFSFile, gridFSDownloadStream);
   //獲取流中的數據
   String content = IOUtils.toString(gridFsResource.getInputStream(),"UTF-8");
   System.out.println(content);
}

 


 

9. Swagger接口測試

​ OpenAPI規範(OpenAPI Specification 簡稱OAS)是Linux基金會的一個項目,試圖經過定義一種用來描述API格式或API定義的語言,來規範RESTful服務開發過程

​ Swagger是全球最大的OpenAPI規範(OAS)API開發工具框架,支持從設計和文檔到測試和部署的整個API生命週期的開發。Spring Boot 能夠集成Swagger,生成Swagger接口。

1. Swagger經常使用註解
註解 說明
@Api 修飾整個類,描述Controller的做用
@ApiOperation 描述一個類的一個方法,或者說一個接口
@ApiParam 單個參數描述
@ApiModel 用對象來接收參數
@ApiModelProperty 用對象接收參數時,描述對象的一個字段
@ApiResponse HTTP響應其中1個描述
@ApiResponses HTTP響應總體描述
@ApiError 發生錯誤返回的信息
@ApiImplicitParam 一個請求參數
@ApiImplicitParams 多個請求參數
  • @ApiImplicitParam的屬性:

屬性 取值 做用
paramType   查詢參數類型
  path 以地址的形式提交數據
  query 直接跟參數完成自動映射賦值(地址欄拼接查詢條件,用對象屬性封裝)
  body 以流的形式提交 僅支持POST(JSON串提交,用@Requestbody接收)
  header 參數在request headers 裏邊提交
  form 以form表單的形式提交 僅支持POST
dataType   參數的數據類型 只做爲標誌說明,並無實際驗證
  Long  
  String  
name   接收參數名
value   接收參數的意義描述
required   參數是否必填
  true 必填
  false 非必填
defaultValue   默認值
2. 測試

在xc-service-api工程下建立config.Swagger2Configuration類,啓動項目,訪問localhost:31001/swagger-ui.html便可開啓測試

  
@Configuration
@EnableSwagger2
public class Swagger2Configuration {
   @Bean
   public Docket createRestApi() {
       return new Docket(DocumentationType.SWAGGER_2)
              .apiInfo(apiInfo())
              .select()
              .apis(RequestHandlerSelectors.basePackage("com.xuecheng"))
              .paths(PathSelectors.any())
              .build();
  }
   private ApiInfo apiInfo() {
       return new ApiInfoBuilder()
              .title("學成網api文檔")
              .description("學成網api文檔")
//               .termsOfServiceUrl("/")
              .version("1.0")
              .build();
  }
}

 

10. Google guava

相關文章
相關標籤/搜索