# java学习 **Repository Path**: corgile/java-learning ## Basic Information - **Project Name**: java学习 - **Description**: 学习 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-02-26 - **Last Updated**: 2022-02-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 整合 Jackson 和 Gson 1. 将服务的返回的对象序列化成json字符串 2. 将前端传来的json字符串反序列化成对象 所有的Json生成都需要相关的 HttpMessageConverter SpringBoot 中自动配置了Jackson和Gson的HttpMessageConverter, > 如何配置全局 json 格式(比如说日期格式) 1. 创建配置类 image-20220226154052274 2. 手动提供一个converter的 bean ```java package com.a.bootweb.config; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import java.text.SimpleDateFormat; @Configuration public class WebConfig { @Bean MappingJackson2HttpMessageConverter mapping() { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); ObjectMapper om = new ObjectMapper(); // 设置全局统一日期格式 om.setDateFormat(new SimpleDateFormat("yy-MM-dd")); converter.setObjectMapper(om); return converter; } } ``` 3. 或者也可以:因为真正起作用的是`ObjectMapper` ```java package com.a.bootweb.config; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.text.SimpleDateFormat; @Configuration public class WebConfig { @Bean public ObjectMapper mapper() { ObjectMapper om = new ObjectMapper(); om.setDateFormat(new SimpleDateFormat("MM-dd-yyyy")); return om; } } ``` ## 全局异常处理 ```java package com.a.bootweb.controller; import org.omg.CosNaming.NamingContextPackage.NotFound; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.servlet.NoHandlerFoundException; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @RestControllerAdvice public class MyExceptionHandler { @ExceptionHandler(NoHandlerFoundException.class) public void notFound(HttpServletResponse response) throws IOException { response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); out.write("

404 Not Found! 找不到服务器

"); out.flush(); out.close(); } } ``` 404需要配置: ```properties spring.mvc.throw-exception-if-no-handler-found=true ``` ## 跨域 1. 跨域注解可以写在方法或类上,也可以写在全局配置中 ```java package com.a.bootweb.config; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.text.SimpleDateFormat; /** * @author Corgile * @date 2022-02-26 */ @Configuration public class WebConfig implements WebMvcConfigurer { @Bean public ObjectMapper mapper() { ObjectMapper om = new ObjectMapper(); om.setDateFormat(new SimpleDateFormat("MM-dd-yyyy")); return om; } @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/user/**") .allowedOrigins("http://localhost:8081") .allowedHeaders("*") .allowedMethods("*") //.allowedMethods("/getuser", "/setuser") .maxAge(30 * 1000); } } ``` ## AOP 定义切点:在service所有方法执行时 ```java @Pointcut(value = "execution(* com.a.bootweb.service.*.*(..))") public void pointCutForServices() { } ``` 各种通知类型 ```java @Before(value = "pointCutForServices()") public void before(JoinPoint joinPoint) { String name = joinPoint.getSignature().getName(); System.out.println("before-----" + name); } @After(value = "pointCutForServices()") public void after(JoinPoint joinPoint) { String name = joinPoint.getSignature().getName(); System.out.println("after-----" + name); } @AfterReturning(value = "pointCutForServices()", returning = "result") public void afterReturning(JoinPoint joinPoint, Object result) { String name = joinPoint.getSignature().getName(); System.out.println("afterReturning----" + name + "---" + result); } @AfterThrowing(value = "pointCutForServices()", throwing = "e") public void afterThrowing(JoinPoint joinPoint, Exception e) { String name = joinPoint.getSignature().getName(); System.out.println("afterThrowing---" + name + "----" + e.getMessage()); } @Around(value = "pointCutForServices()") public Object around(ProceedingJoinPoint pjp) throws Throwable { return pjp.proceed(); } ``` 完整 ```java package com.a.bootweb.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; /** * @author Corgile * @date 2022-02-26 */ @Component @Aspect public class MyLogger { @Pointcut(value = "execution(* com.a.bootweb.service.*.*(..))") public void pointCutForServices() { } @Before(value = "pointCutForServices()") public void before(JoinPoint joinPoint) { String name = joinPoint.getSignature().getName(); System.out.println("before-----" + name); } @After(value = "pointCutForServices()") public void after(JoinPoint joinPoint) { String name = joinPoint.getSignature().getName(); System.out.println("after-----" + name); } @AfterReturning(value = "pointCutForServices()", returning = "result") public void afterReturning(JoinPoint joinPoint, Object result) { String name = joinPoint.getSignature().getName(); System.out.println("afterReturning----" + name + "---" + result); } @AfterThrowing(value = "pointCutForServices()", throwing = "e") public void afterThrowing(JoinPoint joinPoint, Exception e) { String name = joinPoint.getSignature().getName(); System.out.println("afterThrowing---" + name + "----" + e.getMessage()); } @Around(value = "pointCutForServices()") public Object around(ProceedingJoinPoint pjp) throws Throwable { return pjp.proceed(); } } ``` ## 文件上传 1. 全局异常处理大小超过限制 ```java @ControllerAdvice public class GlobalController { @ExceptionHandler(FileSizeLimitExceededException.class) public void maxSizeFile(FileSizeLimitExceededException e, HttpServletResponse resopnse) { resopnse.setContentType("text/html;charset=utf-8"); try { PrintWriter out = resopnse.getWriter(); out.write("

上传文件大小超过限制

"); out.flush(); out.close(); } catch (IOException ioException) { ioException.printStackTrace(); } } } ``` ![image-20220226230001340](https://gitee.com/corgile/images/raw/master/images/2021/image-20220226230001340.png) 2. 上传成功 ![image-20220226230107670](https://gitee.com/corgile/images/raw/master/images/2021/image-20220226230107670.png) ```java package com.a.bootweb.controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.UUID; /** * @author Corgile * @date 2022-02-26 */ @RestController @RequestMapping(value = "file") public class FileUploadController { @PostMapping(value = "upload") public String upload(MultipartFile file, HttpServletRequest request) throws IOException { String format = new SimpleDateFormat("/yyyy/MM-dd/").format(new Date()); String realPath = request.getServletContext().getRealPath("/img") + format; File folder = new File(realPath); if (!folder.exists()) { folder.mkdirs(); } return getUrl(request, format, folder, file); } @PostMapping(value = "uploads") public List uploads(MultipartFile[] files, HttpServletRequest request) throws IOException { String format = new SimpleDateFormat("/yyyy/MM-dd/").format(new Date()); String realPath = request.getServletContext().getRealPath("/img") + format; File folder = new File(realPath); if (!folder.exists()) { folder.mkdirs(); } List urls = new ArrayList<>(); for (MultipartFile file : files) { urls.add(getUrl(request, format, folder, file)); } urls.forEach(System.out::println); return urls; } private String getUrl(HttpServletRequest request, String format, File folder, MultipartFile file) throws IOException { String oldName = file.getOriginalFilename(); assert oldName != null; String newName = UUID.randomUUID() + oldName.substring(oldName.lastIndexOf(".")); file.transferTo(new File(folder, newName)); return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/img" + format + newName; } } ``` 3. 配合Ajax上传 ```html 文件上传
Ajax单文件上传
``` ## 整合持久层 ### JDBCTemplate + 多数据源 1. 配置文件中说明要用到的数据库 ![image-20220227032532117](https://gitee.com/corgile/images/raw/master/images/2021/image-20220227032532117.png) 2. 手动配置数据源 ![image-20220227032626406](https://gitee.com/corgile/images/raw/master/images/2021/image-20220227032626406.png) 3. 数据源的操作类 ![image-20220227032709378](https://gitee.com/corgile/images/raw/master/images/2021/image-20220227032709378.png) 4. 在Service中指明用的是哪一个数据源的操作类 ![image-20220227032834164](https://gitee.com/corgile/images/raw/master/images/2021/image-20220227032834164.png) 5. 测试通过✅ ![image-20220227033128695](https://gitee.com/corgile/images/raw/master/images/2021/image-20220227033128695.png) ### MyBatis + 多数据源 > 与Jdbc多数据源配置类似,`DataSourceConfig`类不变 1. properties文件 ![image-20220227161821778](https://gitee.com/corgile/images/raw/master/images/2021/image-20220227161821778.png) 2. 添加各个数据源的配置类,这里只给出其一,要加`@Primary` ![image-20220227162014677](https://gitee.com/corgile/images/raw/master/images/2021/image-20220227162014677.png) 3. 创建数据访问接口和对应的xml文件 ![image-20220227162342377](https://gitee.com/corgile/images/raw/master/images/2021/image-20220227162342377.png) 4. 测试✅ ![image-20220227162610897](https://gitee.com/corgile/images/raw/master/images/2021/image-20220227162610897.png) ### JPA(Java Persistence API) 1. 配置JPA相关 ![image-20220227172221966](https://gitee.com/corgile/images/raw/master/images/2021/image-20220227172221966.png) 2. 创建一个实体类 ![image-20220227172437085](https://gitee.com/corgile/images/raw/master/images/2021/image-20220227172437085.png) 3. 启动项目,表已被自动创建 ![image-20220227172641728](https://gitee.com/corgile/images/raw/master/images/2021/image-20220227172641728.png) 4. 随便弄几个函数查询 ![image-20220227181000171](https://gitee.com/corgile/images/raw/master/images/2021/image-20220227181000171.png) - Controller ![image-20220227181041348](https://gitee.com/corgile/images/raw/master/images/2021/image-20220227181041348.png) - 测试通过✅ ![image-20220227181207044](https://gitee.com/corgile/images/raw/master/images/2021/image-20220227181207044.png) ## Session共享 正向代理:Proxy向Client作出response,并隐藏Server袭击 反向代理:Proxy向Server发出request,并隐藏Client细节 负载均衡 ```java # 上有服务器配置 upstream some_server_name{ server 127.0.0.1:8080 weight=2; server 127.0.0.1:8081 weight=1; } # 路由分发配置 server { listen 80; server_name localhost; location / { proxy_pass http://some_server_name; proxy_redirect default; } } ``` ## JdbcTemplate 构建 Restful