How to resolve URI encoding problem in spring-boot? - java

I am using spring-boot to host a http request service.
#RequestMapping("/extract")
#SuppressWarnings("unchecked")
#ResponseBody
public ExtractionResponse extract(#RequestParam(value = "extractionInput") String input) {
// LOGGER.info("input: " + input);
JSONObject inputObject = JSON.parseObject(input);
InputInfo inputInfo = new InputInfo();
//Object object = inputObject.get(InputInfo.INPUT_INFO);
JSONObject object = (JSONObject) inputObject.get(InputInfo.INPUT_INFO);
String inputText = object.getString(InputInfo.INPUT_TEXT);
inputInfo.setInputText(inputText);
return jnService.getExtraction(inputInfo);
}
When there is a % sign, as follows, it got an errror:
http://localhost:8090/extract?extractionInput={"inputInfo":{"inputText":"5.00%"}}
The error message is below:
2018-10-09 at 19:12:53.340 [http-nio-8090-exec-1] INFO org.apache.juli.logging.DirectJDKLog [180] [log] - Character decoding failed. Parameter [extractionInput] with value [{"inputInfo":{"inputText":"5.0022:%225.00%%22}}] has been ignored. Note that the name and value quoted here may be corrupted due to the failed decoding. Use debug level logging to see the original, non-corrupted values.
Note: further occurrences of Parameter errors will be logged at DEBUG level.
2018-10-09 at 19:12:53.343 [http-nio-8090-exec-1] WARN org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver [140] [resolveException] - Resolved [org.springframework.web.bind.MissingServletRequestParameterException: Required String parameter 'extractionInput' is not present]
How to configure the URI encoding to fix this issue in my spring-boot configurations?
EDIT: Possible Java client code to make the request:
public String process(String question) {
QueryInfo queryInfo = getQueryInfo(question);
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
String jsonResult = null;
try {
String jsonStr = mapper.writeValueAsString(queryInfo);
String urlStr = Parameters.getQeWebserviceUrl() + URLEncoder.encode(jsonStr, "UTF-8");
URL url = new URL(urlStr);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
jsonResult = in.readLine();
in.close();
} catch (Exception jpe) {
jpe.printStackTrace();
}
return jsonResult
}

Without encoding from your client side - you could still achieve this if you follow any of the following strategies by encoding before the request is processed in the servlet:
use Spring preprocessor bean to preprocess the controller endpoint request
use Spring AspectJ to preprocess the controller endpoint request
use Spring servlet filter to preprocess the controller endpoint request
With any of the above cross-cutting strategies, you could encode the request URL and pass back to the endpoint.
For example below is one implmentation using Filter. You could possibly do some caching there if you need better performance.
#Component
public class SomeFilter implements Filter {
private static final Logger LOGGER = LoggerFactory.getLogger(SomeFilter.class);
#Override
public void init(final FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse, final FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletRequest modifiedRequest = new SomeHttpServletRequest(request);
filterChain.doFilter(modifiedRequest, servletResponse);
}
#Override
public void destroy() {
}
class SomeHttpServletRequest extends HttpServletRequestWrapper {
HttpServletRequest request;
SomeHttpServletRequest(final HttpServletRequest request) {
super(request);
this.request = request;
}
#Override
public String getQueryString() {
String queryString = request.getQueryString();
LOGGER.info("Original query string: " + queryString);
try {
// You need to escape all your non encoded special characters here
String specialChar = URLEncoder.encode("%", "UTF-8");
queryString = queryString.replaceAll("\\%\\%", specialChar + "%");
String decoded = URLDecoder.decode(queryString, "UTF-8");
LOGGER.info("Modified query string: " + decoded);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return queryString;
}
#Override
public String getParameter(final String name) {
String[] params = getParameterMap().get(name);
return params.length > 0 ? params[0] : null;
}
#Override
public Map<String, String[]> getParameterMap() {
String queryString = getQueryString();
return getParamsFromQueryString(queryString);
}
#Override
public Enumeration<String> getParameterNames() {
return Collections.enumeration(getParameterMap().keySet());
}
#Override
public String[] getParameterValues(final String name) {
return getParameterMap().get(name);
}
private Map<String, String[]> getParamsFromQueryString(final String queryString) {
String decoded = "";
try {
decoded = URLDecoder.decode(queryString, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String[] params = decoded.split("&");
Map<String, List<String>> collect = Stream.of(params)
.map(x -> x.split("="))
.collect(Collectors.groupingBy(
x -> x[0],
Collectors.mapping(
x -> x.length > 1 ? x[1] : null,
Collectors.toList())));
Map<String, String[]> result = collect.entrySet().stream()
.collect(Collectors.toMap(
x -> x.getKey(),
x -> x.getValue()
.stream()
.toArray(String[]::new)));
return result;
}
}
}

You probably need to URLEncode the query parameter, e.g.
http://localhost:8090/extract?extractionInput=%7B%22inputInfo%22%3A%7B%22inputText%22%3A%225.00%25%22%7D%7D
The generally easier way to pass a parameter like this is to use an HTTP POST instead of a GET, and pass your JSON object in the body.

This is not a best practice for a REST API.
Try to normalize your URLs in object oriented way to capture path variables.
if your object likes:
param1:{
param2:{
param3: ""
}
}
use url pattern to capture attribute as:
class/param1/param2/{param3}
otherwise you will get more problems when altering front-end technologies while keeping back-end REST API same.

Related

Is It possible to change the content of the Body of a responseEntity

I am trying to return the content of a Json file. But I want to modify before sending it to the front end. I want to add "[" and "]" at the beginning and end of the file. I am doing that because the json file has multiple json root elements.
Like for example extract the result as illustrated in
result = restTemplate.executeRequest(HttpMethod.GET, String.class);
//change Body and put it back in result
Question
Is it possible to change the body of the response and put it back in ResponseEntity?
Source Code
public ResponseEntity<String> getScalityObject(String chainCode, String dataCenter, String path, String byteRange) {
Map<String, Object> queryParams = new HashMap<>();
if (dataCenter != null && !dataCenter.isEmpty()) {
queryParams.put("dataCenter", dataCenter);
}
if (byteRange != null && !byteRange.isEmpty()) {
queryParams.put("byteRange", byteRange);
}
String decodedStr = URLDecoder.decode(path);
queryParams.put("path", decodedStr);
reservationService.setContext(
RESA_INTERNAL_SERVICE_NAME,
queryParams,
"/chains/{chainCode}/objects/file",
chainCode);
restTemplate.setServiceDefinition(reservationService);
ResponseEntity<String> result;
try {
result = restTemplate.executeRequest(HttpMethod.GET, String.class);
//Change responseBody here
return result;
} catch (IOException e) {
e.printStackTrace();
result = new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
return result;
}
public <T> ResponseEntity<T> executeRequest(HttpMethod method, Class<T> responseType) throws IOException {
if (this.serviceDefinition == null) {
throw new IllegalArgumentException("You haven't provided any service definition for this call. " +
"Are you sure you called the right method before using this Amadeus Rest Template?");
}
// Resolve the URI
URI url = this.serviceDefinition.getUriComponents().toUri();
// Add the extra headers if necessary
HttpHeaders headers = new HttpHeaders();
if (this.serviceDefinition.getHeaders() != null) {
for(Map.Entry<String,String> headerSet : this.serviceDefinition.getHeaders().entrySet()) {
headers.put(headerSet.getKey(), Arrays.asList(headerSet.getValue()));
}
}
HttpEntity entity = new HttpEntity(headers);
ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType);
RequestCallback requestCallback = httpEntityCallback(entity, responseType);
ClientHttpResponse response = null;
try {
ClientHttpRequest request = createRequest(url, method);
if (requestCallback != null) {
requestCallback.doWithRequest(request);
}
response = request.execute();
return (responseExtractor != null ? responseExtractor.extractData(response) : null);
}
catch (IOException ex) {
throw ex;
}
finally {
if (response != null) {
response.close();
}
}
}
One of the way which I can think of is :
ResponseEntity<String> result = restTemplate.executeRequest(HttpMethod.GET, String.class);
StringBuilder builder = new StringBuilder(result.getBody());
... //do your transformation to stringbuilder reference.
result = ResponseEntity.status(result.getStatusCode()).body(builder.toString());
Another way if you want to avoid this is to return String response from your executeRequest & modify that response before creating ResponseEntity.
Try this:
Create your own HttpMessageConverter, implementing:
public interface HttpMessageConverter<T> {
// Indicates whether the given class can be read by this converter.
boolean canRead(Class<?> clazz, MediaType mediaType);
// Indicates whether the given class can be written by this converter.
boolean canWrite(Class<?> clazz, MediaType mediaType);
// Return the list of {#link MediaType} objects supported by this converter.
List<MediaType> getSupportedMediaTypes();
// Read an object of the given type form the given input message, and returns it.
T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException;
// Write an given object to the given output message.
void write(T t, MediaType contentType, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException;
}
Register the custom converter into your restTemplate object:
String url = "url";
// Create a new RestTemplate instance
RestTemplate restTemplate = new RestTemplate();
// Add the String message converter
restTemplate.getMessageConverters().add(new YourConverter());
// Make the HTTP GET request, marshaling the response to a String
String result = restTemplate.getForObject(url, String.class);

Spring-Boot-Web: How to get the raw request?

I am using Spring-Boot-Web.
This is my handler for a web-request.
#Component
#RequestMapping ("/foo")
#CrossOrigin (maxAge = 3600)
#RestController
public class WebHandler
{
#RequestMapping ("/bar")
public String bar () throws Exception
{
return "blabla";
}
}
I need to get the full raw request string (HTTP-header and body) into the handler.
How can I do that?
Perhaps option with HttpServletRequest will suit you?
#RequestMapping("/foo")
#CrossOrigin(maxAge = 3600)
#RestController
public class WebHandler {
#RequestMapping("/bar")
public void bar(HttpServletRequest request) throws Exception {
BufferedReader reader = request.getReader();
String body = reader.lines().collect(Collectors.joining("\n"));
System.out.println(body);
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
System.out.println(headerName + ": " + request.getHeader(headerName));
}
}
}
You can also see for yourself what other information you can get from there.
If you need only body and headers, you can make it so:
#RequestMapping("/bar")
public void bar(#RequestHeader Map<String, String> headers,
#RequestBody String body) {
System.out.println(body);
System.out.println(headers);
}

Avoid encoding the data while url creation

I am trying to make get call like this:
#GET(AppConstants.BASE_URL + "{category_type}/")
Call<JsonObject> callCustomFilterApI(#Path("category_type") String type,
#QueryMap(encoded = true) Map<String,String> fields ,
#Query("page") String pageNo);
But #QueryMap can have "&" in the data, so retrofit encoding it to %26.
Is there anyway "&" do not change to "%26".
Solution I tried:
Solution mentioned here
setting encoded=true/false
And also this one.
#DebDeep Asked:
I am passing data in QueryMap as:
private void callCustomFilterSearchPagesApi(String type, ArrayList<FilterListWithHeaderTitle> customFiltersList, int pageNumber, final ApiInteractor listener) {
Map<String, String> queryMap = new HashMap<>();
for (FilterListWithHeaderTitle item: customFiltersList) {
String pairValue;
if (queryMap.containsKey(item.getHeaderTitle())){
// Add the duplicate key and new value onto the previous value
// so (key, value) will now look like (key, value&key=value2)
// which is a hack to work with Retrofit's QueryMap
String oldValue=queryMap.get(item.getHeaderTitle());
String newValue="filters[" + item.getHeaderTitle() + "][]"
+oldValue+ "&"+"filters[" + item.getHeaderTitle() + "][]"+item.getFilterItem();
pairValue=newValue;
}else {
// adding first time
pairValue= item.getFilterItem();
}
try {
//pairValue= URLEncoder.encode(pairValue, "utf-8");
// LoggerUtils.logE(TAG,pairValue);
//queryMap.put(item.getHeaderTitle(), Html.fromHtml(pairValue).toString());
queryMap.put(item.getHeaderTitle(), pairValue);
}catch (Exception u){
LoggerUtils.crashlyticsLog(TAG,u.getMessage());
}
}
Call<JsonObject> call = TagTasteApplicationInitializer.mRetroClient.callCustomFilterApI(type, queryMap, "1");
requestCall(call, listener);
}
Use Interceptor and convert %26 to &:
class RequestInterceptor implements Interceptor {
#Override
Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request();
String stringurl = request.url().toString();
stringurl = stringurl.replace("%26", "&");
Request newRequest = new Request.Builder()
.url(stringurl)
.build();
return chain.proceed(newRequest);
}
}
Set this to your OkHttp builder:
OkHttpClient client = new OkHttpClient.Builder();
client.addInterceptor(new RequestInterceptor());

Create regex which will match to all requests in Spring [duplicate]

Is there a way to get the complete path value after the requestMapping #PathVariable values have been parsed?
That is:
/{id}/{restOfTheUrl} should be able to parse /1/dir1/dir2/file.html into id=1 and restOfTheUrl=/dir1/dir2/file.html
Any ideas would be appreciated.
Non-matched part of the URL is exposed as a request attribute named HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE:
#RequestMapping("/{id}/**")
public void foo(#PathVariable("id") int id, HttpServletRequest request) {
String restOfTheUrl = new AntPathMatcher().extractPathWithinPattern(request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString(),request.getRequestURI());
...
}
Just found that issue corresponding to my problem. Using HandlerMapping constants I was able to wrote a small utility for that purpose:
/**
* Extract path from a controller mapping. /controllerUrl/** => return matched **
* #param request incoming request.
* #return extracted path
*/
public static String extractPathFromPattern(final HttpServletRequest request){
String path = (String) request.getAttribute(
HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
String bestMatchPattern = (String ) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
AntPathMatcher apm = new AntPathMatcher();
String finalPath = apm.extractPathWithinPattern(bestMatchPattern, path);
return finalPath;
}
This has been here quite a while but posting this. Might be useful for someone.
#RequestMapping( "/{id}/**" )
public void foo( #PathVariable String id, HttpServletRequest request ) {
String urlTail = new AntPathMatcher()
.extractPathWithinPattern( "/{id}/**", request.getRequestURI() );
}
Building upon Fabien Kruba's already excellent answer, I thought it would be nice if the ** portion of the URL could be given as a parameter to the controller method via an annotation, in a way which was similar to #RequestParam and #PathVariable, rather than always using a utility method which explicitly required the HttpServletRequest. So here's an example of how that might be implemented. Hopefully someone finds it useful.
Create the annotation, along with the argument resolver:
#Target(ElementType.PARAMETER)
#Retention(RetentionPolicy.RUNTIME)
#Documented
public #interface WildcardParam {
class Resolver implements HandlerMethodArgumentResolver {
#Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.getParameterAnnotation(WildcardParam.class) != null;
}
#Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
return request == null ? null : new AntPathMatcher().extractPathWithinPattern(
(String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE),
(String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE));
}
}
}
Register the method argument resolver:
#Configuration
public class WebMvcConfig implements WebMvcConfigurer {
#Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new WildcardParam.Resolver());
}
}
Use the annotation in your controller handler methods to have easy access to the ** portion of the URL:
#RestController
public class SomeController {
#GetMapping("/**")
public void someHandlerMethod(#WildcardParam String wildcardParam) {
// use wildcardParam here...
}
}
You need to use built-in pathMatcher:
#RequestMapping("/{id}/**")
public void test(HttpServletRequest request, #PathVariable long id) throws Exception {
ResourceUrlProvider urlProvider = (ResourceUrlProvider) request
.getAttribute(ResourceUrlProvider.class.getCanonicalName());
String restOfUrl = urlProvider.getPathMatcher().extractPathWithinPattern(
String.valueOf(request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE)),
String.valueOf(request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)));
I have used the Tuckey URLRewriteFilter to handle path elements that contain '/' characters, as I don't think Spring 3 MVC supports them yet.
http://www.tuckey.org/
You put this filter in to your app, and provide an XML config file. In that file you provide rewrite rules, which you can use to translate path elements containing '/' characters into request parameters that Spring MVC can deal with properly using #RequestParam.
WEB-INF/web.xml:
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<!-- map to /* -->
WEB-INF/urlrewrite.xml:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite
PUBLIC "-//tuckey.org//DTD UrlRewrite 3.0//EN"
"http://tuckey.org/res/dtds/urlrewrite3.0.dtd">
<urlrewrite>
<rule>
<from>^/(.*)/(.*)$</from>
<to last="true">/$1?restOfTheUrl=$2</to>
</urlrewrite>
Controller method:
#RequestMapping("/{id}")
public void handler(#PathVariable("id") int id, #RequestParam("restOfTheUrl") String pathToFile) {
...
}
Yes the restOfTheUrl is not returning only required value but we can get the value by using UriTemplate matching.
I have solved the problem, so here the working solution for the problem:
#RequestMapping("/{id}/**")
public void foo(#PathVariable("id") int id, HttpServletRequest request) {
String restOfTheUrl = (String) request.getAttribute(
HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
/*We can use UriTemplate to map the restOfTheUrl*/
UriTemplate template = new UriTemplate("/{id}/{value}");
boolean isTemplateMatched = template.matches(restOfTheUrl);
if(isTemplateMatched) {
Map<String, String> matchTemplate = new HashMap<String, String>();
matchTemplate = template.match(restOfTheUrl);
String value = matchTemplate.get("value");
/*variable `value` will contain the required detail.*/
}
}
Here is how I did it. You can see how I convert the requestedURI to a filesystem path (what this SO question is about). Bonus: and also how to respond with the file.
#RequestMapping(value = "/file/{userId}/**", method = RequestMethod.GET)
public void serveFile(#PathVariable("userId") long userId, HttpServletRequest request, HttpServletResponse response) {
assert request != null;
assert response != null;
// requestURL: http://192.168.1.3:8080/file/54/documents/tutorial.pdf
// requestURI: /file/54/documents/tutorial.pdf
// servletPath: /file/54/documents/tutorial.pdf
// logger.debug("requestURL: " + request.getRequestURL());
// logger.debug("requestURI: " + request.getRequestURI());
// logger.debug("servletPath: " + request.getServletPath());
String requestURI = request.getRequestURI();
String relativePath = requestURI.replaceFirst("^/file/", "");
Path path = Paths.get("/user_files").resolve(relativePath);
try {
InputStream is = new FileInputStream(path.toFile());
org.apache.commons.io.IOUtils.copy(is, response.getOutputStream());
response.flushBuffer();
} catch (IOException ex) {
logger.error("Error writing file to output stream. Path: '" + path + "', requestURI: '" + requestURI + "'");
throw new RuntimeException("IOError writing file to output stream");
}
}
private final static String MAPPING = "/foo/*";
#RequestMapping(value = MAPPING, method = RequestMethod.GET)
public #ResponseBody void foo(HttpServletRequest request, HttpServletResponse response) {
final String mapping = getMapping("foo").replace("*", "");
final String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
final String restOfPath = url.replace(mapping, "");
System.out.println(restOfPath);
}
private String getMapping(String methodName) {
Method methods[] = this.getClass().getMethods();
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName() == methodName) {
String mapping[] = methods[i].getAnnotation(RequestMapping.class).value();
if (mapping.length > 0) {
return mapping[mapping.length - 1];
}
}
}
return null;
}
To improve upon #Daniel Jay Marcaida answer
#RequestMapping( "/{id}/**" )
public void foo( #PathVariable String id, HttpServletRequest request ) {
String restOfUrl = new AntPathMatcher()
.extractPathWithinPattern(
request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString(),
request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE).toString());
}
or
#RequestMapping( "/{id}/**" )
public void foo( #PathVariable String id, HttpServletRequest request ) {
String restOfUrl = new AntPathMatcher()
.extractPathWithinPattern(
request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString(),
request.getServletPath());
}
I have a similar problem and I resolved in this way:
#RequestMapping(value = "{siteCode}/**/{fileName}.{fileExtension}")
public HttpEntity<byte[]> getResource(#PathVariable String siteCode,
#PathVariable String fileName, #PathVariable String fileExtension,
HttpServletRequest req, HttpServletResponse response ) throws IOException {
String fullPath = req.getPathInfo();
// Calling http://localhost:8080/SiteXX/images/argentine/flag.jpg
// fullPath conentent: /SiteXX/images/argentine/flag.jpg
}
Note that req.getPathInfo() will return the complete path (with {siteCode} and {fileName}.{fileExtension}) so you will have to process conveniently.

How to get the request parameters in `#Aspect`?

I was trying to add logs on every request to print IP, time, request parameters, response body, etc. Here is my code:
#Around("execution(* cn.dogchao.carcare.web.controller..*.*(..))")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes sra = (ServletRequestAttributes)ra;
HttpServletRequest request = sra.getRequest();
// always empty!
inputParamMap = request.getParameterMap();
// uri
requestPath = request.getRequestURI();
fromIP = getIpAddr(request);
//
outputParamMap = new HashMap<>();
Object result = pjp.proceed();//
outputParamMap.put("result", result);
return result;
}
And I had a Controller like this:
#Controller("channelController")
#RequestMapping(value = "/channel")
public class ChannelController {
#Autowired
private ChannelService channelService;
/**
*
* #return
*/
#ResponseBody
#RequestMapping(value = "/salesChannelAdd")
public String salesChannelAdd(#RequestParam Map<String, String> params) {
ChannelVO vo;
try {
vo = JSON.parseObject(JSON.toJSON(params).toString(), ChannelVO.class);
}catch (Exception e){
return JSON.toJSONString(new ResultJson(ErrorCode.INVALID_PARAM, "参数异常:"+e.getCause()).getResultMap());
}
if(!vo.validate()){
return JSON.toJSONString(new ResultJson(ErrorCode.INVALID_PARAM, vo.getErrorMsg()).getResultMap());
}
return JSON.toJSONString(channelService.createChannel(vo));
}
}
Now I print everything except the params. I got a empty parameter map. I don't know why it's empty and how to get all the params.

Categories