Tech&WK_programming_Java Web
purpose: 记录开发过程中的需要注意的点
Spring boot 项目下静态资源访问的配置
默认是 templates, 自定义 static


1. SpEL 在配置引用字段,注意大小写敏感

2. collection application config


View Code
3. bean 很多的大型项目,需要将 application-context 层次设计




Spring async web
WebAsyncTask<T>
1 @RestController 2 @RequestMapping("/async/webAsyncTask") 3 public class WebAsyncTaskCtr { 4 5 @GetMapping 6 public WebAsyncTask<String> getResponse() throws Exception{ 7 System.out.println((Thread.currentThread().getName() + ", web server main thread start.")); 8 9 Callable<String> callable = () -> { 10 System.out.println((Thread.currentThread().getName() + ", sub thread started.")); 11 TimeUnit.SECONDS.sleep(5); 12 System.out.println((Thread.currentThread().getName() + ", sub thread end.")); 13 14 return "webAsyncTask callable action."; 15 }; 16 17 WebAsyncTask<String> webAsyncTask = new WebAsyncTask<>(6000, callable); 18 19 webAsyncTask.onCompletion(() -> System.out.println("Program process completed back invocation")); 20 webAsyncTask.onTimeout(() ->"Program time out back invocation"); 21 webAsyncTask.onError(() -> "Program error occurred."); 22 23 System.out.println(Thread.currentThread().getName() + ", web server main thread end."); 24 return webAsyncTask; 25 } 26 }
Spring web test
1. @RunWith(SpringRunner.class)
@WebMvcTest( [ contract-controller.class] )
1 package org.techroad.springboot.practice.netSource.mvcAsysnc; 2 3 import org.junit.Test; 4 import org.junit.runner.RunWith; 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 7 import org.springframework.http.MediaType; 8 import org.springframework.test.context.junit4.SpringRunner; 9 import org.springframework.test.web.servlet.MockMvc; 10 import org.springframework.test.web.servlet.MvcResult; 11 import org.springframework.test.web.servlet.result.MockMvcResultHandlers; 12 13 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch; 14 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; 15 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; 16 17 @RunWith(SpringRunner.class) 18 @WebMvcTest(WebAsyncTaskCtr.class) 19 public class WebAsyncTaskCtrTest { 20 21 @Autowired 22 private MockMvc mockMvc; 23 24 @Test 25 public void getResponse() throws Exception { 26 27 MvcResult mvcResult = mockMvc.perform(get("/async/webAsyncTask")) 28 .andExpect(request().asyncStarted()) 29 .andDo(MockMvcResultHandlers.log()) 30 .andReturn(); 31 32 mockMvc.perform(asyncDispatch(mvcResult)) 33 .andExpect(status().isOk()) 34 .andExpect(content().contentTypeCompatibleWith(MediaType.TEXT_PLAIN)) 35 .andExpect(content().string("webAsyncTask callable action.")); 36 } 37 }
1. aync task executor

2. ResponseBodyEmitter

1 import org.springframework.web.bind.annotation.GetMapping; 2 import org.springframework.web.bind.annotation.RestController; 3 import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter; 4 import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; 5 6 import java.io.IOException; 7 import java.util.List; 8 import java.util.concurrent.ExecutorService; 9 import java.util.concurrent.Executors; 10 11 @RestController 12 public class ResponseBodyEmitterMock { 13 14 private final MockEmitterService service; 15 16 public ResponseBodyEmitterMock(MockEmitterService service){ 17 this.service = service; 18 } 19 20 @GetMapping("/mock") 21 public ResponseBodyEmitter entities(){ 22 ResponseBodyEmitter emitter = new ResponseBodyEmitter(); 23 ExecutorService executorService = Executors.newSingleThreadExecutor(); 24 executorService.execute( 25 () -> { 26 List<MockEntity> entityList = service.findAll(); 27 try{ 28 for(MockEntity e : entityList){ 29 // delay() 30 emitter.send(e); 31 } 32 emitter.complete(); 33 }catch (IOException e){ 34 emitter.completeWithError(e); 35 } 36 }); 37 executorService.shutdown(); 38 return emitter; 39 } 40 41 // Content-type head -> text/event-stream , 事件流,可以保持打开状态并接受事件通知 42 // 编写的每个对象都通过 HttpMessageConvert 转换为 JSON 对象 43 // 每个对象都作为事件数据写入 data 字段中。 44 45 // id , event 事件类型, data 事件数据, retry 事件流重启连接的时间。 46 47 @GetMapping("/mockSse") 48 public SseEmitter orders(){ 49 SseEmitter emitter = new SseEmitter(); 50 ExecutorService executorService = Executors.newSingleThreadExecutor(); 51 executorService.execute( 52 () -> { 53 List<MockEntity> entities = service.findAll(); 54 try { 55 for (MockEntity e : entities) { 56 // delay(); 57 emitter.send(e); 58 } 59 emitter.complete(); 60 } catch (Exception e) { 61 emitter.completeWithError(e); 62 } 63 }); 64 executorService.shutdown(); 65 return emitter; 66 } 67 68 @GetMapping("/mockConfigSseEventBuilder") 69 public SseEmitter sseEmitterBuilder(){ 70 SseEmitter sseEmitter = new SseEmitter(); 71 ExecutorService executorService = Executors.newSingleThreadExecutor(); 72 executorService.execute( 73 () -> { 74 List<MockEntity> entities = service.findAll(); 75 try{ 76 for(MockEntity e : entities){ 77 // delay() 78 SseEmitter.SseEventBuilder eventBuilder = sseEmitter.event(); 79 // 可填充 id 和 event 字段 80 sseEmitter.send( 81 eventBuilder 82 .data(e) 83 .name("specify") 84 .id("uuid")); 85 } 86 sseEmitter.complete(); 87 }catch (IOException e){ 88 sseEmitter.completeWithError(e); 89 } 90 } 91 ); 92 executorService.shutdown(); 93 return sseEmitter; 94 }
IDEA web war deploy

记一次 MultipartFile 报错 AccessDenied 无法上传文件的错误:


2020-12-2519:09:46
Controller upload redirect
https://www.cnblogs.com/panchanggui/p/11582633.html
https://www.cnblogs.com/alsf/p/9134552.html
https://www.cnblogs.com/fangjian0423/p/springMVC-redirectView-analysis.html
1. String

2. RedirectView RedirectAttributes





Work platform foreground web
2021-01-06 12:49:08
IDEA controller , 返回类型为 String 时,注意 url 前的 “/”
但是在打包成 jar , 会报 Thymeleaf 解析错误,因此以 ModelAndView 作为返回类型。 此时IDEA运行和 项目打包 jar 运行均正常.

注意 Thymeleaf insert replace 如果解析错误也会导致 打包Jar 后运行异常。

2021-02-18
数据量大。

2021-03-09
Chiller / performance / option 相同的上传处理流程, 带上 biz process 参数。


浙公网安备 33010602011771号