我有基于api的客户端 - 服务器应用程序,php + yii作为后端。我的目标是使后端端口从php到java(与客户端的旧查询兼容)。
我选择了Spring MVC框架,但却因解密原始帖子数据而陷入困境。问题是旧客户端使用自定义加密算法,因此HttpServletRequest.getParameterMap()
不会返回有效的地图。
所以,我的问题是:在这种情况下,在使用request.getParameterMap()
方法进行纯业务逻辑之前,更换/准备原始数据(解密)的最佳解决方案是什么?
控制器代码是这样的:
@RestController
@RequestMapping(value = "/", method = RequestMethod.POST)
public class ApiController {
@RequestMapping
@ResponseBody
public String process(HttpServletRequest request) {
ApiQueryResponse queryResponse = new ApiQueryResponse();
try {
// request = APIEncryptor.decrypt(request); // 1
// now working with request.getParameterMap() // 2
// ...
queryResponse.setText(APIEncryptor.crypt(...))
} catch (Exception e) {
queryResponse.setError(e.getMessage());
}
return queryResponse.asText();
}
...
}
APIEncryptor代码是这样的:
public class ApiEncryptor {
public static ApiQueryData encrypt(Java Object) {
// custom encryption algorithm...
return Raw data string;
}
// input post data: 103klg20fsl2g2fsldkfj20f9isjf
// output post data: a=1&b=2&c=3&d=some_text
public static ApiQueryData decrypt(Raw post data...) {
// decrypt algorithm...
return request; // HttpServletRequest object with valid post data
// after this action, .getParameter() will produce valid data
}
}
注意:我知道request.getInputStream()
之类的方法存在,但我现在不需要它。我需要知道有没有办法在使用HttpServletRequest参数getter之前准备帖子数据?或者(无论如何)我需要从请求中获取一次数据并执行我想要的操作(例如,通过getReader())?
答案 0 :(得分:1)
处理解密逻辑的最佳方法是在http过滤器内 (使用spring MVC)如下所示。此过滤器解密请求 收到请求后立即到达服务器 控制器方法。
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.filter.OncePerRequestFilter;
public class DecryptionFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
request = ApiEncryptor.decrypt(request);
filterChain.doFilter(request, response);
}
}
答案 1 :(得分:0)
HttpServletRequest在具有Spring Boot和Java 8的Filter中的控制器之前解密
public class RequestWrapper extends HttpServletRequestWrapper {
private final String body;
public RequestWrapper(HttpServletRequest request) throws Exception {
super(request);
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
throw ex;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
throw ex;
}
}
}
String encryptData = stringBuilder.toString();
String deCryptData = null;
if (encryptData != null && !encryptData.isEmpty()) {
deCryptData = MD5Utils.decrypt(encryptData);
if (deCryptData == null) {
//logger.error("Exception occured inside MD5Utils.decrypt(encryptData) - Request Body not valid : ");
}
}
body = deCryptData;
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
ServletInputStream servletInputStream = new ServletInputStream() {
public int read() throws IOException {
return byteArrayInputStream.read();
}
@Override
public boolean isFinished() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isReady() {
// TODO Auto-generated method stub
return false;
}
@Override
public void setReadListener(ReadListener listener) {
// TODO Auto-generated method stub
}
};
return servletInputStream;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
public String getBody() {
return this.body;
}
}
过滤器类
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
/* wrap the request in order to read the inputstream multiple times */
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
request = new RequestWrapper(httpServletRequest);
chain.doFilter(request, response);
}
}