> 文章列表 > Java实现在查询结果中某类型属性追加字符串的方法

Java实现在查询结果中某类型属性追加字符串的方法

Java实现在查询结果中某类型属性追加字符串的方法

目录

前言

解决方案

方法一:修改原始数据

方法二:遍历替换

方法三:过滤数据


前言

查询一个列表,修改列表中某个属性的内容

例如:从数据库查询出用户列表,需要返回给web前端,但是发现存储的图片由于数据库存储中的图片格式,由png格式转换成了.jpeg格式。所以就需要重新生成新的列表。

如何做到把 .jpeg 换成 .png ,然后再返回给web前端?

[{id:1, name:"小明", avatar:"https://image.xxxxx.com/avatar/111111.jpeg"},{id:2, name:"小红", avatar:"https://image.xxxxx.com/avatar/222222.jpeg"},{id:3, name:"小刚", avatar:"https://image.xxxxx.com/avatar/333333.jpeg"},{id:3, name:"小丽", avatar:"https://image.xxxxx.com/avatar/444444.jpeg"},......
]

解决方案

我这里提供三种思路

方法一:修改原始数据

如果数据数量小,可以对数据库里的原始数据进行修改。

虽然一劳永逸的解决了数据问题,但是直接改数据库里的原始数据,一旦出现问题,就不是小问题了。

具体需求,不同分析,这里只提供 追加/替换 的SQL示例

# .png替换.jpeg
UPDATE user set avatar = REPLACE(avatar, '.jpeg', '.png');
# 追加.png
UPDATE user SET avatar = CONCAT(avatar, '.png');

建议:像例子中这种图片链接的数据,设计数据库表的时候,将扩展名与路径分成多个属性来存储

方法二:遍历替换

如果查询接口调用不频繁,或者这种数据并不是很多,可以循环遍历,替换成新的字符串

如果此方法用的地方太多,冗余代码,过于臃肿,不断重复造轮子,这样就不推荐了

public static void main(String[] args) {List<User> list = list();// 循环遍历,替换值for (User item: list) {String avatar = item.getAvatar().replaceAll(".jpeg", ".png");item.setAvatar(avatar);}
}

方法三:过滤数据

拦截请求接口,筛选过滤数据,类似与AOP切面过滤数据

最大限度的避免了重复造轮子、修改原始数据;更能自定义拦截指定的请求接口

Request工具类

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import java.util.*;/*  Request工具类*/
public class RequestUtil extends HttpServlet{public static HttpServletRequest getRequest() {if(RequestContextHolder.getRequestAttributes() != null){return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();}return null;}public static HashMap<String, Object> getRequestParamAndHeader(){try{HttpServletRequest request = getRequest();if(request == null){return null;}//request信息HashMap<String, Object> data = new HashMap<>();HashMap<String, Object> requestParams = new HashMap<>();Enumeration<String> paraNames = request.getParameterNames();if(paraNames != null){for(Enumeration<String> enumeration =paraNames;enumeration.hasMoreElements();){String key= enumeration.nextElement();requestParams.put(key, request.getParameter(key));}}HashMap<String, Object> requestFilter = new HashMap<>();Enumeration<String> attributeNames = request.getAttributeNames();if(attributeNames != null){for ( Enumeration<String> attributeNames1 = attributeNames; attributeNames1.hasMoreElements();) {String key= attributeNames1.nextElement();if(key.contains("request_")){requestFilter.put(key, request.getAttribute(key));}}}data.put("url", request.getRequestURL());data.put("uri", request.getRequestURI());data.put("method", request.getMethod());data.put("request", requestParams);data.put("request_filter", requestFilter);//header 信息Enumeration<String> headerNames = request.getHeaderNames();HashMap<String, Object> headerParams = new HashMap<>();if(headerNames != null){for(Enumeration<String> enumeration = headerNames;enumeration.hasMoreElements();){String key= enumeration.nextElement();String value=request.getHeader(key);headerParams.put(key, value);}}data.put("header", headerParams);return data;}catch (Exception e){e.printStackTrace();return null;}}public static String getDomain(){HttpServletRequest request = getRequest();if(request == null){return null;}return request.getServerName() + ":" + request.getServerPort();}public static String getUri(HttpServletRequest request){String uri = request.getRequestURI();List<String> list = stringToArrayStrRegex(uri, "/");// 去掉url中的数字参数list.removeIf(StringUtils::isNumeric);// 去掉url中的逗号分隔参数list.removeIf(c -> c.contains(","));return StringUtils.join(list, "/");}/* 字符串分割,转化为数组* @param str 字符串* @param regex 分隔符有* @author Mr.Zhang* @since 2020-04-22* @return List<String>*/public static List<String> stringToArrayStrRegex(String str, String regex ){List<String> list = new ArrayList<>();if (str.contains(regex)){String[] split = str.split(regex);for (String value : split) {if(!StringUtils.isBlank(value)){list.add(value);}}}else {list.add(str);}return list;}}

返回值输出过滤器 

import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;/* 返回值输出过滤器*/
@Component
public class ResponseFilter implements Filter {/ @param request* @param response* @param filterChain* @throws IOException* @throws ServletException*/@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {//转换成代理类ResponseWrapper wrapperResponse = new ResponseWrapper((HttpServletResponse) response);// 这里只拦截返回,直接让请求过去,如果在请求前有处理,可以在这里处理filterChain.doFilter(request, wrapperResponse);//获取返回值byte[] content = wrapperResponse.getContent();//判断是否有值if (content.length > 0) {String str = new String(content, StandardCharsets.UTF_8);try {HttpServletRequest req = (HttpServletRequest) request;// Response业务逻辑处理调用str = new ResponseRouter().filter(str, RequestUtil.getUri(req));} catch (Exception e) {e.printStackTrace();}//把返回值输出到客户端ServletOutputStream outputStream = response.getOutputStream();if (str.length() > 0) {outputStream.write(str.getBytes());outputStream.flush();outputStream.close();//最后添加这一句,输出到客户端response.flushBuffer();}}}
}

Response包装类

import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;/* Response包装类*/
public class ResponseWrapper extends HttpServletResponseWrapper {private ByteArrayOutputStream buffer;private ServletOutputStream out;public ResponseWrapper(HttpServletResponse httpServletResponse) {super(httpServletResponse);buffer = new ByteArrayOutputStream();out = new WrapperOutputStream(buffer);}@Overridepublic ServletOutputStream getOutputStream() { return out; }@Overridepublic void flushBuffer() throws IOException {if (out != null) {out.flush();}}public byte[] getContent() throws IOException {flushBuffer();return buffer.toByteArray();}static class WrapperOutputStream extends ServletOutputStream {private ByteArrayOutputStream bos;public WrapperOutputStream(ByteArrayOutputStream bos) { this.bos = bos; }@Overridepublic void write(int b) { bos.write(b); }@Overridepublic boolean isReady() { return false; }@Overridepublic void setWriteListener(WriteListener arg0) { }}
}

WebImageConfig,过滤配置,只过滤自定义的请求 

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import java.util.ArrayList;
import java.util.List;/* WebImageConfig*/
@Configuration
public class WebImageConfig extends WebMvcConfigurerAdapter {/* 过滤需要压缩图片url接口* @return*/@Beanpublic FilterRegistrationBean<ResponseFilter> imageFilter() {FilterRegistrationBean<ResponseFilter> registrationBean = new FilterRegistrationBean<>();ResponseFilter filter = new ResponseFilter();registrationBean.setFilter(filter);List<String> urls = new ArrayList<>();// 过滤所有请求// urls.add("/*");// 过滤指定的请求urls.add("/user/getList");urls.add("/user/getInfo");registrationBean.setUrlPatterns(urls);return registrationBean;}
}

Response业务逻辑处理

这里对进行对结果中包含图片链接的数据进行拦截处理,如果有其他特殊需求,可以在这一层进行改动

/* response业务逻辑处理*/
public class ResponseRouter {public String filter(String data, String path) {boolean result = un().contains(path);if (result) {return data;}//根据需要处理返回值if (data.contains("https://image.xxxxx.com/avatar/") && !data.contains("data:image/png;base64")) {//data包含if (data.contains(".png")){data = data.replaceAll(".png", ".png");}if (data.contains(".jpg")){data = data.replaceAll(".jpg", ".png");}if (data.contains(".jpeg")){data = data.replaceAll(".jpeg", ".png");}}return data;}public static String un() {return "";}}