Http 요청 기능 추가
This commit is contained in:
@@ -33,6 +33,8 @@ dependencies {
|
|||||||
// implementation 'com.google.jimfs:jimfs:1.2'
|
// implementation 'com.google.jimfs:jimfs:1.2'
|
||||||
|
|
||||||
implementation 'io.springfox:springfox-boot-starter:3.0.0'
|
implementation 'io.springfox:springfox-boot-starter:3.0.0'
|
||||||
|
implementation 'org.apache.httpcomponents:httpclient:4.5.13'
|
||||||
|
|
||||||
|
|
||||||
implementation 'org.apache.commons:commons-lang3:3.12.0'
|
implementation 'org.apache.commons:commons-lang3:3.12.0'
|
||||||
implementation 'commons-io:commons-io:2.11.0'
|
implementation 'commons-io:commons-io:2.11.0'
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.eactive.httpmockserver;
|
package com.eactive.httpmockserver;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
@@ -8,11 +7,6 @@ import java.util.Random;
|
|||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import com.eactive.httpmockserver.script.Script;
|
|
||||||
import com.eactive.httpmockserver.script.ScriptLoader;
|
|
||||||
import com.jayway.jsonpath.DocumentContext;
|
|
||||||
import com.jayway.jsonpath.JsonPath;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.commons.lang3.math.NumberUtils;
|
import org.apache.commons.lang3.math.NumberUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -24,10 +18,14 @@ import org.springframework.http.HttpStatus;
|
|||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.server.ResponseStatusException;
|
import org.springframework.web.server.ResponseStatusException;
|
||||||
|
|
||||||
|
import com.eactive.httpmockserver.script.Script;
|
||||||
|
import com.eactive.httpmockserver.script.ScriptLoader;
|
||||||
|
import com.jayway.jsonpath.DocumentContext;
|
||||||
|
import com.jayway.jsonpath.JsonPath;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class ApiController {
|
public class ApiController {
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
@@ -48,7 +46,9 @@ public class ApiController {
|
|||||||
HttpServletResponse response) throws Exception {
|
HttpServletResponse response) throws Exception {
|
||||||
logger.info("==================================================");
|
logger.info("==================================================");
|
||||||
logger.info("==================================================");
|
logger.info("==================================================");
|
||||||
logger.info(request.getServletPath());
|
logger.info("request.getMethod()= {}", request.getMethod());
|
||||||
|
logger.info("request.getServletPath()= {}", request.getServletPath());
|
||||||
|
logger.info("request.getQueryString()= {}", request.getQueryString());
|
||||||
logger.info("--------------------------------------------------");
|
logger.info("--------------------------------------------------");
|
||||||
logger.info("httpEntity.getHeaders().toString()= {}", httpEntity.getHeaders());
|
logger.info("httpEntity.getHeaders().toString()= {}", httpEntity.getHeaders());
|
||||||
logger.info("--------------------------------------------------");
|
logger.info("--------------------------------------------------");
|
||||||
@@ -58,7 +58,7 @@ public class ApiController {
|
|||||||
Map<String, String[]> paramMap = request.getParameterMap();
|
Map<String, String[]> paramMap = request.getParameterMap();
|
||||||
for (Entry<String, String[]> entry : paramMap.entrySet()) {
|
for (Entry<String, String[]> entry : paramMap.entrySet()) {
|
||||||
for (String value : entry.getValue()) {
|
for (String value : entry.getValue()) {
|
||||||
logger.info("{}={}", entry.getKey(), value);
|
logger.info("request.getParameter({})={}", entry.getKey(), value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,142 @@
|
|||||||
|
package com.eactive.httpmockserver;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Index;
|
||||||
|
import javax.persistence.Lob;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
@Entity
|
||||||
|
@Table(indexes = { @Index(name = "idxHttpRequestInfo01", columnList = "requestGroupName, requestName") })
|
||||||
|
public class HttpRequestInfo implements Serializable {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
@Column(length = 100, nullable = false)
|
||||||
|
private String requestGroupName;
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
@Column(length = 100, nullable = false)
|
||||||
|
private String requestName;
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
@Column(length = 200, nullable = false)
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@Column(length = 5000)
|
||||||
|
private String queryParams;
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
@Column(length = 10)
|
||||||
|
private String method;
|
||||||
|
|
||||||
|
@Column(length = 50)
|
||||||
|
private String requestContentType;
|
||||||
|
|
||||||
|
@Column(length = 20)
|
||||||
|
private String encode;
|
||||||
|
|
||||||
|
@Column(length = 5000)
|
||||||
|
private String requestHeaders;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Lob
|
||||||
|
private String requestBody;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRequestGroupName() {
|
||||||
|
return requestGroupName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestGroupName(String requestGroupName) {
|
||||||
|
this.requestGroupName = requestGroupName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRequestName() {
|
||||||
|
return requestName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestName(String requestName) {
|
||||||
|
this.requestName = requestName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getQueryParams() {
|
||||||
|
return queryParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQueryParams(String queryParams) {
|
||||||
|
this.queryParams = queryParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMethod() {
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMethod(String method) {
|
||||||
|
this.method = method;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRequestContentType() {
|
||||||
|
return requestContentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestContentType(String requestContentType) {
|
||||||
|
this.requestContentType = requestContentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEncode() {
|
||||||
|
return encode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEncode(String encode) {
|
||||||
|
this.encode = encode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRequestHeaders() {
|
||||||
|
return requestHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestHeaders(String requestHeaders) {
|
||||||
|
this.requestHeaders = requestHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRequestBody() {
|
||||||
|
return requestBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestBody(String requestBody) {
|
||||||
|
this.requestBody = requestBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "HttpRequestInfo [id=" + id + ", requestGroupName=" + requestGroupName + ", requestName=" + requestName
|
||||||
|
+ ", url=" + url + ", queryParams=" + queryParams + ", method=" + method + ", requestContentType="
|
||||||
|
+ requestContentType + ", encode=" + encode + ", requestHeaders=" + requestHeaders + ", requestBody="
|
||||||
|
+ requestBody + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,302 @@
|
|||||||
|
package com.eactive.httpmockserver;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.KeyManagementException;
|
||||||
|
import java.security.KeyStoreException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.http.Header;
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
|
import org.apache.http.NameValuePair;
|
||||||
|
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpDelete;
|
||||||
|
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.client.methods.HttpPut;
|
||||||
|
import org.apache.http.client.methods.HttpRequestBase;
|
||||||
|
import org.apache.http.client.utils.URIBuilder;
|
||||||
|
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||||
|
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||||
|
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
|
||||||
|
import org.apache.http.entity.ContentType;
|
||||||
|
import org.apache.http.entity.StringEntity;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClients;
|
||||||
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
|
import org.apache.http.ssl.SSLContexts;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.domain.Example;
|
||||||
|
import org.springframework.data.domain.ExampleMatcher;
|
||||||
|
import org.springframework.data.domain.ExampleMatcher.GenericPropertyMatcher;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
|
import com.eactive.httpmockserver.datatables.DataTablesRequest;
|
||||||
|
import com.eactive.httpmockserver.datatables.DataTablesResponse;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class HttpRequestInfoController {
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private HttpRequestInfoService httpRequestInfoService;
|
||||||
|
|
||||||
|
@PostMapping("/manage/executeHttpRequest")
|
||||||
|
@ResponseBody
|
||||||
|
public HttpResponseInfo executeHttpRequest(@Valid HttpRequestInfo httpRequestInfo, BindingResult result)
|
||||||
|
throws IOException, URISyntaxException, KeyManagementException, NoSuchAlgorithmException,
|
||||||
|
KeyStoreException {
|
||||||
|
HttpResponseInfo httpResponseInfo = new HttpResponseInfo();
|
||||||
|
|
||||||
|
if (result.hasErrors()) {
|
||||||
|
httpResponseInfo.setBody(result.toString());
|
||||||
|
return httpResponseInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logger.isInfoEnabled()) {
|
||||||
|
logger.info("======================== Request Info ==========================");
|
||||||
|
logger.info(httpRequestInfo.toString());
|
||||||
|
logger.info("================================================================");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(httpRequestInfo.getEncode())) {
|
||||||
|
httpRequestInfo.setEncode(StandardCharsets.UTF_8.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method 생성 및 body 셋팅
|
||||||
|
HttpRequestBase base;
|
||||||
|
|
||||||
|
switch (HttpMethod.resolve(StringUtils.upperCase(httpRequestInfo.getMethod()))) {
|
||||||
|
case GET:
|
||||||
|
base = new HttpGet(httpRequestInfo.getUrl());
|
||||||
|
break;
|
||||||
|
case DELETE:
|
||||||
|
base = new HttpDelete(httpRequestInfo.getUrl());
|
||||||
|
break;
|
||||||
|
case POST:
|
||||||
|
base = new HttpPost(httpRequestInfo.getUrl());
|
||||||
|
assignBody(base, httpRequestInfo);
|
||||||
|
break;
|
||||||
|
case PUT:
|
||||||
|
base = new HttpPut(httpRequestInfo.getUrl());
|
||||||
|
assignBody(base, httpRequestInfo);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
base = new HttpGet(httpRequestInfo.getUrl());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// queryParams 셋팅
|
||||||
|
List<NameValuePair> urlParameters = assignQueryParams(httpRequestInfo.getQueryParams());
|
||||||
|
if (urlParameters != null && urlParameters.size() > 0) {
|
||||||
|
URI uri = new URIBuilder(base.getURI()).addParameters(urlParameters).build();
|
||||||
|
base.setURI(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
// heaser 셋팅
|
||||||
|
assignRequestHeaders(base, httpRequestInfo);
|
||||||
|
|
||||||
|
try (CloseableHttpClient httpClient = assignHttpClient(httpRequestInfo.getUrl());
|
||||||
|
CloseableHttpResponse response = httpClient.execute(base)) {
|
||||||
|
httpResponseInfo.setStatusCode(String.valueOf(response.getStatusLine().getStatusCode()));
|
||||||
|
httpResponseInfo.setHeaders(assignResponseHeaders(response.getAllHeaders()));
|
||||||
|
HttpEntity entity = response.getEntity();
|
||||||
|
String responseStr = "";
|
||||||
|
if (entity != null) {
|
||||||
|
responseStr = EntityUtils.toString(entity, httpRequestInfo.getEncode());
|
||||||
|
httpResponseInfo.setBody(responseStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logger.isInfoEnabled()) {
|
||||||
|
logger.info("======================== Response Info ==========================");
|
||||||
|
logger.info("= ProtocolVersion = {}", response.getProtocolVersion());
|
||||||
|
logger.info("= StatusCode = {}", response.getStatusLine().getStatusCode());
|
||||||
|
logger.info("= Body = {}", responseStr);
|
||||||
|
logger.info("================================================================");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpResponseInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String assignResponseHeaders(Header[] headers) {
|
||||||
|
String headerStr = "";
|
||||||
|
for (Header header : headers) {
|
||||||
|
headerStr += header.getName() + "=" + header.getValue();
|
||||||
|
headerStr += ",";
|
||||||
|
}
|
||||||
|
return StringUtils.removeEnd(headerStr, ",");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assignRequestHeaders(HttpRequestBase base, HttpRequestInfo httpRequestInfo) {
|
||||||
|
if (StringUtils.isBlank(httpRequestInfo.getRequestHeaders())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// service_code=1234,user_id=james
|
||||||
|
String[] headerPairs = org.springframework.util.StringUtils
|
||||||
|
.tokenizeToStringArray(httpRequestInfo.getRequestHeaders(), ",");
|
||||||
|
for (String headerPair : headerPairs) {
|
||||||
|
String[] keyValue = org.springframework.util.StringUtils.tokenizeToStringArray(headerPair, "=");
|
||||||
|
if (keyValue.length == 2 && StringUtils.isNotBlank(keyValue[0]) && StringUtils.isNotBlank(keyValue[1])) {
|
||||||
|
base.setHeader(keyValue[0], keyValue[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assignBody(HttpRequestBase base, HttpRequestInfo httpRequestInfo) throws IOException {
|
||||||
|
if (StringUtils.isBlank(httpRequestInfo.getRequestBody())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.equals(httpRequestInfo.getRequestContentType(), MediaType.APPLICATION_FORM_URLENCODED_VALUE)) {
|
||||||
|
List<NameValuePair> parameters = assignQueryParams(httpRequestInfo.getRequestBody());
|
||||||
|
if (parameters != null) {
|
||||||
|
((HttpEntityEnclosingRequestBase) base)
|
||||||
|
.setEntity(new UrlEncodedFormEntity(parameters, httpRequestInfo.getEncode()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ContentType contentType = ContentType.create(
|
||||||
|
StringUtils.defaultIfBlank(httpRequestInfo.getRequestContentType(), MediaType.TEXT_PLAIN_VALUE),
|
||||||
|
httpRequestInfo.getEncode());
|
||||||
|
((HttpEntityEnclosingRequestBase) base)
|
||||||
|
.setEntity(new StringEntity(httpRequestInfo.getRequestBody(), contentType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<NameValuePair> assignQueryParams(String queryParams) {
|
||||||
|
if (StringUtils.isBlank(queryParams)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<NameValuePair> queryParamList = new ArrayList<>();
|
||||||
|
|
||||||
|
// service_code=1234,user_id=james
|
||||||
|
String[] queryPairs = org.springframework.util.StringUtils.tokenizeToStringArray(queryParams, "&");
|
||||||
|
for (String queryPair : queryPairs) {
|
||||||
|
String[] keyValue = org.springframework.util.StringUtils.tokenizeToStringArray(queryPair, "=");
|
||||||
|
if (keyValue.length == 2) {
|
||||||
|
queryParamList.add(new BasicNameValuePair(keyValue[0], keyValue[1]));
|
||||||
|
} else if (keyValue.length == 1) {
|
||||||
|
queryParamList.add(new BasicNameValuePair(keyValue[0], ""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return queryParamList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CloseableHttpClient assignHttpClient(String url)
|
||||||
|
throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
|
||||||
|
if (StringUtils.startsWith(url, "https")) {
|
||||||
|
SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(
|
||||||
|
SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build(),
|
||||||
|
NoopHostnameVerifier.INSTANCE);
|
||||||
|
return HttpClients.custom().setSSLSocketFactory(factory).build();
|
||||||
|
} else {
|
||||||
|
return HttpClients.createDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/manage/findAllHttpRequestInfos")
|
||||||
|
public String getAllAllHttpRequestInfos(Pageable pageable, Model model) {
|
||||||
|
return "page/list-http-request-info";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/manage/rest/httpRequestInfos")
|
||||||
|
@ResponseBody
|
||||||
|
public DataTablesResponse<HttpRequestInfo> getAllHttpRequestInfosForDatatables(@RequestBody DataTablesRequest req) {
|
||||||
|
Pageable pageable = ApiManageRestController.assignJpaPageable(req);
|
||||||
|
|
||||||
|
// search option
|
||||||
|
Example<HttpRequestInfo> example = null;
|
||||||
|
if (StringUtils.isNotBlank(req.getSearch().getValue())) {
|
||||||
|
HttpRequestInfo info = new HttpRequestInfo();
|
||||||
|
info.setRequestGroupName(req.getSearch().getValue());
|
||||||
|
info.setRequestName(req.getSearch().getValue());
|
||||||
|
info.setUrl(req.getSearch().getValue());
|
||||||
|
|
||||||
|
ExampleMatcher matcher = ExampleMatcher.matchingAny()
|
||||||
|
.withMatcher("requestGroupName", new GenericPropertyMatcher().contains().ignoreCase())
|
||||||
|
.withMatcher("requestName", new GenericPropertyMatcher().contains().ignoreCase())
|
||||||
|
.withMatcher("url", new GenericPropertyMatcher().contains().ignoreCase());
|
||||||
|
example = Example.of(info, matcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
DataTablesResponse<HttpRequestInfo> res = new DataTablesResponse<HttpRequestInfo>(
|
||||||
|
httpRequestInfoService.findHttpRequestInfos(example, pageable));
|
||||||
|
res.setRecordsFiltered(httpRequestInfoService.getRecordsCount(example));
|
||||||
|
res.setRecordsTotal(httpRequestInfoService.getRecordsCount(null));
|
||||||
|
res.setDraw(req.getDraw());
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(path = { "/manage/getHttpRequestInfoForm", "/manage/getHttpRequestInfoForm/{id}" })
|
||||||
|
public String getgetHttpRequestInfoForm(Model model, @PathVariable Optional<Long> id) {
|
||||||
|
if (id.isPresent()) {
|
||||||
|
Optional<HttpRequestInfo> optional = httpRequestInfoService.findById(id.get());
|
||||||
|
if (optional.isPresent()) {
|
||||||
|
model.addAttribute("httpRequestInfo", optional.get());
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("No data, id: " + id.get());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
HttpRequestInfo httpRequestInfo = new HttpRequestInfo();
|
||||||
|
httpRequestInfo.setMethod(HttpMethod.POST.name());
|
||||||
|
httpRequestInfo.setRequestContentType(MediaType.APPLICATION_JSON_VALUE);
|
||||||
|
httpRequestInfo.setEncode(StandardCharsets.UTF_8.name());
|
||||||
|
model.addAttribute("httpRequestInfo", httpRequestInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "page/add-edit-http-request-info";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/manage/saveHttpRequestInfo")
|
||||||
|
public String saveHttpRequestInfo(@Valid HttpRequestInfo httpRequestInfo, BindingResult result, Model model) {
|
||||||
|
if (result.hasErrors()) {
|
||||||
|
return "page/add-edit-http-request-info";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (httpRequestInfo.getId() == null) {
|
||||||
|
httpRequestInfoService.save(httpRequestInfo);
|
||||||
|
} else {
|
||||||
|
httpRequestInfoService.update(httpRequestInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "redirect:/manage/findAllHttpRequestInfos";
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/manage/deleteHttpRequestInfo/{id}")
|
||||||
|
public String deleteHttpRequestInfo(@PathVariable Long id) {
|
||||||
|
if (id == null) {
|
||||||
|
throw new IllegalArgumentException("No data, id: " + id);
|
||||||
|
}
|
||||||
|
|
||||||
|
httpRequestInfoService.delete(id);
|
||||||
|
|
||||||
|
return "redirect:/manage/findAllHttpRequestInfos";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.eactive.httpmockserver;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface HttpRequestInfoDao extends JpaRepository<HttpRequestInfo, Long> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.eactive.httpmockserver;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.springframework.data.domain.Example;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
|
||||||
|
public interface HttpRequestInfoService {
|
||||||
|
public Optional<HttpRequestInfo> findById(Long id);
|
||||||
|
|
||||||
|
public HttpRequestInfo save(HttpRequestInfo httpRequestInfo);
|
||||||
|
|
||||||
|
public List<HttpRequestInfo> findAllHttpRequestInfos(Pageable pageable);
|
||||||
|
|
||||||
|
public List<HttpRequestInfo> findHttpRequestInfos(Example<HttpRequestInfo> example, Pageable pageable);
|
||||||
|
|
||||||
|
public HttpRequestInfo update(HttpRequestInfo httpRequestInfo);
|
||||||
|
|
||||||
|
public void delete(Long id);
|
||||||
|
|
||||||
|
public long getRecordsCount(Example<HttpRequestInfo> example);
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
package com.eactive.httpmockserver;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.domain.Example;
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Transactional(propagation = Propagation.SUPPORTS)
|
||||||
|
public class HttpRequestInfoServiceImpl implements HttpRequestInfoService {
|
||||||
|
@Autowired
|
||||||
|
private HttpRequestInfoDao httpRequestInfoDao;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<HttpRequestInfo> findById(Long id) {
|
||||||
|
return httpRequestInfoDao.findById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
|
||||||
|
public HttpRequestInfo save(HttpRequestInfo httpRequestInfo) {
|
||||||
|
return httpRequestInfoDao.save(httpRequestInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<HttpRequestInfo> findAllHttpRequestInfos(Pageable pageable) {
|
||||||
|
Page<HttpRequestInfo> pagedResult = httpRequestInfoDao.findAll(pageable);
|
||||||
|
if (pagedResult.hasContent()) {
|
||||||
|
return pagedResult.getContent();
|
||||||
|
} else {
|
||||||
|
return new ArrayList<HttpRequestInfo>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<HttpRequestInfo> findHttpRequestInfos(Example<HttpRequestInfo> example, Pageable pageable) {
|
||||||
|
if (example == null) {
|
||||||
|
return findAllHttpRequestInfos(pageable);
|
||||||
|
}
|
||||||
|
|
||||||
|
Page<HttpRequestInfo> pagedResult = httpRequestInfoDao.findAll(example, pageable);
|
||||||
|
if (pagedResult.hasContent()) {
|
||||||
|
return pagedResult.getContent();
|
||||||
|
} else {
|
||||||
|
return new ArrayList<HttpRequestInfo>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
|
||||||
|
public HttpRequestInfo update(HttpRequestInfo httpRequestInfo) {
|
||||||
|
return httpRequestInfoDao.save(httpRequestInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(propagation = Propagation.REQUIRED, readOnly = false)
|
||||||
|
public void delete(Long id) {
|
||||||
|
httpRequestInfoDao.deleteById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getRecordsCount(Example<HttpRequestInfo> example) {
|
||||||
|
if (example == null) {
|
||||||
|
return httpRequestInfoDao.count();
|
||||||
|
} else {
|
||||||
|
return httpRequestInfoDao.count(example);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.eactive.httpmockserver;
|
||||||
|
|
||||||
|
public class HttpResponseInfo {
|
||||||
|
private String statusCode;
|
||||||
|
private String headers;
|
||||||
|
private String body;
|
||||||
|
|
||||||
|
public String getStatusCode() {
|
||||||
|
return statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatusCode(String statusCode) {
|
||||||
|
this.statusCode = statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHeaders() {
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeaders(String headers) {
|
||||||
|
this.headers = headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBody() {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBody(String body) {
|
||||||
|
this.body = body;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "HttpResponseInfo [statusCode=" + statusCode + ", headers=" + headers + ", body=" + body + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -89,6 +89,12 @@
|
|||||||
</p>
|
</p>
|
||||||
</a>
|
</a>
|
||||||
<ul class="nav nav-treeview">
|
<ul class="nav nav-treeview">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a th:href="@{/manage/findAllHttpRequestInfos}" class="nav-link">
|
||||||
|
<i class="far fa-circle nav-icon"></i>
|
||||||
|
<p>HTTP 요청 관리</p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a th:href="@{/manage/findAllScriptInfos}" class="nav-link">
|
<a th:href="@{/manage/findAllScriptInfos}" class="nav-link">
|
||||||
<i class="far fa-circle nav-icon"></i>
|
<i class="far fa-circle nav-icon"></i>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<form id="form" class="inputForm" action="#" th:action="@{/manage/saveApi}"
|
<form id="form" class="inputForm" action="#" th:action="@{/manage/saveApi}"
|
||||||
th:object="${apiInfo}" method="post">
|
th:object="${apiInfo}" method="post">
|
||||||
<div class="card card-default">
|
<div class="card card-primary">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h3 class="card-title">Basic Info</h3>
|
<h3 class="card-title">Basic Info</h3>
|
||||||
</div>
|
</div>
|
||||||
@@ -103,7 +103,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card card-default">
|
<div class="card card-primary">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h3 class="card-title">Response Info</h3>
|
<h3 class="card-title">Response Info</h3>
|
||||||
</div>
|
</div>
|
||||||
@@ -198,7 +198,7 @@
|
|||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label class="col-sm-3 col-form-label">응답 Body1</label>
|
<label class="col-sm-3 col-form-label">응답 Body1</label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div id="responseBody1" class="shadow-sm" style="height:400px"></div>
|
<div id="responseBody1" class="shadow-sm" style="height: 200px; border: 1px solid #ced4da; border-radius: .25rem;"></div>
|
||||||
<!-- <textarea class="form-control" th:field="*{responseBody1}"-->
|
<!-- <textarea class="form-control" th:field="*{responseBody1}"-->
|
||||||
<!-- rows="3"></textarea>-->
|
<!-- rows="3"></textarea>-->
|
||||||
</div>
|
</div>
|
||||||
@@ -210,7 +210,7 @@
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<!-- <textarea class="form-control" th:field="*{responseBody2}"-->
|
<!-- <textarea class="form-control" th:field="*{responseBody2}"-->
|
||||||
<!-- rows="3"></textarea>-->
|
<!-- rows="3"></textarea>-->
|
||||||
<div id="responseBody2" class="shadow-sm" style="height:400px"></div>
|
<div id="responseBody2" class="shadow-sm" style="height: 200px; border: 1px solid #ced4da; border-radius: .25rem;"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -282,8 +282,8 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setMonaco('responseBody1', 'syntaxResponseBody1', [[${apiInfo.responseBody1}]]);
|
setMonaco('responseBody1', 'syntaxResponseBody1', /*[[${apiInfo.responseBody1}]]*/);
|
||||||
setMonaco('responseBody2', 'syntaxResponseBody2', [[${apiInfo.responseBody2}]]);
|
setMonaco('responseBody2', 'syntaxResponseBody2', /*[[${apiInfo.responseBody2}]]*/);
|
||||||
</script>
|
</script>
|
||||||
</th:block>
|
</th:block>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<form id="bytesMessageSpecForm" name="bytesMessageSpecForm" class="inputForm" action="#" th:action="@{/manage/saveBytesMessageSpec}"
|
<form id="bytesMessageSpecForm" name="bytesMessageSpecForm" class="inputForm" action="#" th:action="@{/manage/saveBytesMessageSpec}"
|
||||||
th:object="${bytesMessageSpec}" method="post">
|
th:object="${bytesMessageSpec}" method="post">
|
||||||
<div class="card card-default">
|
<div class="card card-primary">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h3 class="card-title">Basic Info</h3>
|
<h3 class="card-title">Basic Info</h3>
|
||||||
</div>
|
</div>
|
||||||
@@ -122,7 +122,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card card-default">
|
<div class="card card-primary">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h3 class="card-title">Response Message Info</h3>
|
<h3 class="card-title">Response Message Info</h3>
|
||||||
<br>
|
<br>
|
||||||
@@ -136,7 +136,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card card-default">
|
<div class="card card-primary">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h3 class="card-title">Acho Message Info</h3>
|
<h3 class="card-title">Acho Message Info</h3>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,321 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:th="http://www.thymeleaf.org"
|
||||||
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
layout:decorator="layout/default_layout">
|
||||||
|
|
||||||
|
<div class="content-wrapper" layout:fragment="content">
|
||||||
|
<!-- Content Header (Page header) -->
|
||||||
|
<section class="content-header">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<h1 th:if="${httpRequestInfo.id == null}">HTTP 요청 정보 등록</h1>
|
||||||
|
<h1 th:unless="${httpRequestInfo.id == null}">HTTP 요청 정보 수정</h1>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<ol class="breadcrumb float-sm-right">
|
||||||
|
<li class="breadcrumb-item"><a href="#">Home</a></li>
|
||||||
|
<li class="breadcrumb-item active">부가 기능</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /.container-fluid -->
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Main content -->
|
||||||
|
<section class="content" style="padding-bottom: 1rem;">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<form id="form" class="inputForm" action="#" th:action="@{/manage/saveHttpRequestInfo}"
|
||||||
|
th:object="${httpRequestInfo}" method="post">
|
||||||
|
<div class="card card-primary">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="card-title">Basic Info</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-3 col-form-label">요청 그룹명<small>(*)</small></label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="text" th:field="*{requestGroupName}"
|
||||||
|
class="form-control"> <span
|
||||||
|
th:if="${#fields.hasErrors('requestGroupName')}"
|
||||||
|
th:errors="*{requestGroupName}" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-3 col-form-label">요청명<small>(*)</small></label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="text" th:field="*{requestName}" class="form-control">
|
||||||
|
<span th:if="${#fields.hasErrors('requestName')}"
|
||||||
|
th:errors="*{requestName}" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-3 col-form-label">URL<small>(*)</small></label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="text" th:field="*{url}" class="form-control"
|
||||||
|
placeholder="ex) http://~~:8080/api/~~"> <span
|
||||||
|
th:if="${#fields.hasErrors('url')}" th:errors="*{url}"
|
||||||
|
class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-3 col-form-label">Method<small>(*)</small></label>
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<div class="form-radio">
|
||||||
|
<label class="form-check-label"> <input type="radio"
|
||||||
|
th:field="*{method}" class="form-check-input" value="POST">
|
||||||
|
POST <i class="input-helper"></i></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<div class="form-radio">
|
||||||
|
<label class="form-check-label"> <input type="radio"
|
||||||
|
th:field="*{method}" class="form-check-input" value="GET">
|
||||||
|
GET <i class="input-helper"></i></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<div class="form-radio">
|
||||||
|
<label class="form-check-label"> <input type="radio"
|
||||||
|
th:field="*{method}" class="form-check-input" value="PUT">
|
||||||
|
PUT <i class="input-helper"></i></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-3">
|
||||||
|
<div class="form-radio">
|
||||||
|
<label class="form-check-label"> <input type="radio"
|
||||||
|
th:field="*{method}" class="form-check-input" value="DELETE">
|
||||||
|
DELETE <i class="input-helper"></i></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-3 col-form-label">URL Query Params</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="text" th:field="*{queryParams}"
|
||||||
|
class="form-control"
|
||||||
|
placeholder="ex) apiCode=A10&userId=James&...">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="card card-primary">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="card-title">Request Info</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-3 col-form-label">Content Type</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select class="form-control" th:field="*{requestContentType}" th:value="*{requestContentType}">
|
||||||
|
<option th:value="'application/json'" th:text="'application/json'"></option>
|
||||||
|
<option th:value="'application/xml'" th:text="'application/xml'"></option>
|
||||||
|
<option th:value="'application/x-www-form-urlencoded'" th:text="'application/x-www-form-urlencoded'"></option>
|
||||||
|
<option th:value="'text/plain'" th:text="'text/plain'"></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-3 col-form-label">Encode</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="text" th:field="*{encode}"
|
||||||
|
class="form-control">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-3 col-form-label">요청 Headers</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="text" th:field="*{requestHeaders}"
|
||||||
|
class="form-control"
|
||||||
|
placeholder="ex) api-code=A10,user-id=James,...">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-3 col-form-label">요청 Body</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<div id="requestBodyDiv" class="shadow-sm" style="height: 200px; border: 1px solid #ced4da; border-radius: .25rem;"></div>
|
||||||
|
<input type="hidden" th:field="*{requestBody}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="card card-primary">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="card-title">Response Data</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-3 col-form-label">응답 Status Code</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="text" class="form-control" id="responseStatusCode" name="responseStatusCode">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-3 col-form-label">응답 Headers</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="text" class="form-control" id="responseHeaders" name="responseHeaders">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row" style="margin-top: 2em;">
|
||||||
|
<label class="col-sm-3 col-form-label"> </label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<button type="button" class="btn btn-default btn-sm" id="btn_json" style="float: right;">Format JSON</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label class="col-sm-3 col-form-label">응답 Body</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<div id="responseBody" class="shadow-sm" style="height: 200px; border: 1px solid #ced4da; border-radius: .25rem;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="hidden" th:field="*{id}">
|
||||||
|
<button type="submit" class="btn btn-primary mr-2">Submit</button>
|
||||||
|
<button type="button" class="btn btn-secondary"
|
||||||
|
onclick="history.go(-1);">Cancel</button>
|
||||||
|
|
||||||
|
<button type="button" class="btn btn-primary mr-2" id="execBtn" style="float: right;">Execute</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<th:block layout:fragment="script">
|
||||||
|
<link rel="stylesheet" data-name="vs/editor/editor.main"
|
||||||
|
th:href="@{/plugins/vs/editor/editor.main.css}">
|
||||||
|
|
||||||
|
<link rel="stylesheet" th:href="@{/plugins/select2/css/select2.min.css}">
|
||||||
|
<link rel="stylesheet" th:href="@{/plugins/select2-bootstrap4-theme/select2-bootstrap4.min.css}">
|
||||||
|
|
||||||
|
<script th:src="@{/plugins/select2/js/select2.full.js}"></script>
|
||||||
|
|
||||||
|
<script>var require = { paths: { 'vs': '../../plugins/vs' } };</script>
|
||||||
|
|
||||||
|
<script th:src="@{/plugins/vs/loader.js}"></script>
|
||||||
|
<script th:src="@{/plugins/vs/editor/editor.main.nls.js}"></script>
|
||||||
|
<script th:src="@{/plugins/vs/editor/editor.main.js}"></script>
|
||||||
|
|
||||||
|
<script th:inline="javascript">
|
||||||
|
var urlForSidebar = "/manage/findAllHttpRequestInfos";
|
||||||
|
|
||||||
|
//Initialize Select2 Elements
|
||||||
|
$('.select2bs4').select2({
|
||||||
|
theme: 'bootstrap4'
|
||||||
|
})
|
||||||
|
|
||||||
|
$("#execBtn").click(function() {
|
||||||
|
$("#requestBody").val(window.editor.getValue());
|
||||||
|
var postData = $('#form').serializeArray();
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url : "/manage/executeHttpRequest",
|
||||||
|
data : postData,
|
||||||
|
dataType : "json",
|
||||||
|
type : "POST",
|
||||||
|
success : function(raw) {
|
||||||
|
$("#responseStatusCode").val(raw.statusCode);
|
||||||
|
$("#responseHeaders").val(raw.headers);
|
||||||
|
window.editor2.setValue(raw.body);
|
||||||
|
},
|
||||||
|
error : function(e) {
|
||||||
|
alert("전송에 실패했습니다.\n" + e.responseText);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#btn_json").click(function() {
|
||||||
|
try {
|
||||||
|
var jsonObj = JSON.parse(window.editor2.getValue());
|
||||||
|
window.editor2.setValue(JSON.stringify(jsonObj, null, 4));
|
||||||
|
} catch (e) {}
|
||||||
|
});
|
||||||
|
|
||||||
|
function setMonaco(elementId, selectId, initValue){
|
||||||
|
var targetDivElement = document.getElementById(elementId);
|
||||||
|
var lang = $("#"+selectId+" option:selected").val();
|
||||||
|
|
||||||
|
window.editor = monaco.editor.create(targetDivElement, {
|
||||||
|
value: initValue,
|
||||||
|
language: lang,
|
||||||
|
minimap: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
wordWrap: 'on',
|
||||||
|
wrappingStrategy: 'simple',
|
||||||
|
wordWrapBreakAfterCharacters: '',
|
||||||
|
wordWrapBreakBeforeCharacters: '',
|
||||||
|
wrappingIndent: 'none',
|
||||||
|
automaticLayout: true
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#"+selectId).change(function(){
|
||||||
|
var selectLang = $("#"+selectId+" option:selected").val();
|
||||||
|
if (selectLang == "application/x-www-form-urlencoded") {
|
||||||
|
alert("요청 Body에 'userId=aaa&userName=이링크' 형식으로 입력해야 합니다.");
|
||||||
|
}
|
||||||
|
monaco.editor.setModelLanguage(editor.getModel(), selectLang);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#form').submit(function(eventObj) {
|
||||||
|
$("#requestBody").val(window.editor.getValue());
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setMonaco2(elementId, selectId, initValue){
|
||||||
|
var targetDivElement = document.getElementById(elementId);
|
||||||
|
var lang = $("#"+selectId+" option:selected").val();
|
||||||
|
|
||||||
|
window.editor2 = monaco.editor.create(targetDivElement, {
|
||||||
|
value: initValue,
|
||||||
|
language: lang,
|
||||||
|
minimap: {
|
||||||
|
enabled: false
|
||||||
|
},
|
||||||
|
wordWrap: 'on',
|
||||||
|
wrappingStrategy: 'simple',
|
||||||
|
wordWrapBreakAfterCharacters: '',
|
||||||
|
wordWrapBreakBeforeCharacters: '',
|
||||||
|
wrappingIndent: 'none',
|
||||||
|
automaticLayout: true
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#"+selectId).change(function(){
|
||||||
|
var selectLang = $("#"+selectId+" option:selected").val();
|
||||||
|
monaco.editor.setModelLanguage(window.editor2.getModel(), selectLang);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setMonaco('requestBodyDiv', 'requestContentType', /*[[${httpRequestInfo.requestBody}]]*/);
|
||||||
|
setMonaco2('responseBody', 'requestContentType', "");
|
||||||
|
</script>
|
||||||
|
</th:block>
|
||||||
|
</html>
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<form id="form" class="inputForm" action="#" th:action="@{/manage/saveScriptInfo}"
|
<form id="form" class="inputForm" action="#" th:action="@{/manage/saveScriptInfo}"
|
||||||
th:object="${scriptInfo}" method="post">
|
th:object="${scriptInfo}" method="post">
|
||||||
<div class="card card-default">
|
<div class="card card-primary">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h3 class="card-title">Basic Info</h3>
|
<h3 class="card-title">Basic Info</h3>
|
||||||
</div>
|
</div>
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card card-default">
|
<div class="card card-primary">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<h3 class="card-title">Script Code</h3>
|
<h3 class="card-title">Script Code</h3>
|
||||||
</div>
|
</div>
|
||||||
@@ -103,7 +103,7 @@
|
|||||||
let editor;
|
let editor;
|
||||||
let constrainedInstance;
|
let constrainedInstance;
|
||||||
|
|
||||||
const isNew = [[${scriptInfo.id == null}]];
|
const isNew = /*[[${scriptInfo.id == null}]]*/ false;
|
||||||
|
|
||||||
function findLineNumberByText(text){
|
function findLineNumberByText(text){
|
||||||
const linesContent = editor.getModel().getLinesContent();
|
const linesContent = editor.getModel().getLinesContent();
|
||||||
@@ -172,7 +172,7 @@
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
setMonaco('scriptCode', [[${scriptInfo.scriptCode}]]);
|
setMonaco('scriptCode', /*[[${scriptInfo.scriptCode}]]*/);
|
||||||
if(isNew == false){
|
if(isNew == false){
|
||||||
$('#scriptName').prop( "disabled", true );
|
$('#scriptName').prop( "disabled", true );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,6 @@
|
|||||||
<th>API명</th>
|
<th>API명</th>
|
||||||
<th>URL</th>
|
<th>URL</th>
|
||||||
<th>서비스코드</th>
|
<th>서비스코드</th>
|
||||||
<th>스크립트</th>
|
|
||||||
<th>Method</th>
|
<th>Method</th>
|
||||||
<th>수정</th>
|
<th>수정</th>
|
||||||
<th>삭제</th>
|
<th>삭제</th>
|
||||||
@@ -118,7 +117,6 @@
|
|||||||
{"data": "apiName"},
|
{"data": "apiName"},
|
||||||
{"data": "url"},
|
{"data": "url"},
|
||||||
{"data": "serviceValue"},
|
{"data": "serviceValue"},
|
||||||
{"data": "scriptName"},
|
|
||||||
{"data": "method", "searchable": false, "orderable": false},
|
{"data": "method", "searchable": false, "orderable": false},
|
||||||
{"data": "id", "searchable": false, "orderable": false},
|
{"data": "id", "searchable": false, "orderable": false},
|
||||||
{"data": "id", "searchable": false, "orderable": false}
|
{"data": "id", "searchable": false, "orderable": false}
|
||||||
|
|||||||
@@ -0,0 +1,165 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:th="http://www.thymeleaf.org"
|
||||||
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
layout:decorator="layout/default_layout">
|
||||||
|
|
||||||
|
<th:block layout:fragment="css">
|
||||||
|
<link rel="stylesheet"
|
||||||
|
th:href="@{/plugins/datatables-bs4/css/dataTables.bootstrap4.min.css}">
|
||||||
|
<link rel="stylesheet"
|
||||||
|
th:href="@{/plugins/datatables-responsive/css/responsive.bootstrap4.min.css}">
|
||||||
|
<link rel="stylesheet"
|
||||||
|
th:href="@{/plugins/datatables-buttons/css/buttons.bootstrap4.min.css}">
|
||||||
|
</th:block>
|
||||||
|
|
||||||
|
<div class="content-wrapper" layout:fragment="content">
|
||||||
|
<!-- Content Header (Page header) -->
|
||||||
|
<section class="content-header">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row mb-2">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<h1>HTTP 요청 관리</h1>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<ol class="breadcrumb float-sm-right">
|
||||||
|
<li class="breadcrumb-item"><a href="/">Home</a></li>
|
||||||
|
<li class="breadcrumb-item active">부가 기능</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /.container-fluid -->
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Main content -->
|
||||||
|
<section class="content">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<h3 class="card-title">HTTP API 호출 테스트를 수행할 수 있다.</h3>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<table id="listHttpRequestInfoTable"
|
||||||
|
class="table table-bordered table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>요청그룹</th>
|
||||||
|
<th>요청명</th>
|
||||||
|
<th>URL</th>
|
||||||
|
<th>Method</th>
|
||||||
|
<th>수정</th>
|
||||||
|
<th>삭제</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<!-- /.card-body -->
|
||||||
|
</div>
|
||||||
|
<!-- /.card -->
|
||||||
|
</div>
|
||||||
|
<!-- /.col -->
|
||||||
|
</div>
|
||||||
|
<!-- /.row -->
|
||||||
|
</div>
|
||||||
|
<!-- /.container-fluid -->
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<th:block layout:fragment="script">
|
||||||
|
<script th:src="@{/plugins/datatables/jquery.dataTables.min.js}"></script>
|
||||||
|
<script
|
||||||
|
th:src="@{/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js}"></script>
|
||||||
|
<script
|
||||||
|
th:src="@{/plugins/datatables-responsive/js/dataTables.responsive.min.js}"></script>
|
||||||
|
<script
|
||||||
|
th:src="@{/plugins/datatables-responsive/js/responsive.bootstrap4.min.js}"></script>
|
||||||
|
<script
|
||||||
|
th:src="@{/plugins/datatables-buttons/js/dataTables.buttons.min.js}"></script>
|
||||||
|
<script
|
||||||
|
th:src="@{/plugins/datatables-buttons/js/buttons.bootstrap4.min.js}"></script>
|
||||||
|
<script th:src="@{/plugins/jszip/jszip.min.js}"></script>
|
||||||
|
<script th:src="@{/plugins/pdfmake/pdfmake.min.js}"></script>
|
||||||
|
<script th:src="@{/plugins/pdfmake/vfs_fonts.js}"></script>
|
||||||
|
<script th:src="@{/plugins/datatables-buttons/js/buttons.html5.min.js}"></script>
|
||||||
|
<script th:src="@{/plugins/datatables-buttons/js/buttons.print.min.js}"></script>
|
||||||
|
<script
|
||||||
|
th:src="@{/plugins/datatables-buttons/js/buttons.colVis.min.js}"></script>
|
||||||
|
|
||||||
|
<script th:inline="javascript">
|
||||||
|
$.fn.dataTable.ext.buttons.new = {
|
||||||
|
text: 'New',
|
||||||
|
action: function ( e, dt, node, config ) {
|
||||||
|
location.href = "/manage/getHttpRequestInfoForm";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var listHttpRequestInfoTable = $("#listHttpRequestInfoTable").DataTable({
|
||||||
|
"responsive": true, "lengthChange": false, "autoWidth": false,
|
||||||
|
"processing": true,
|
||||||
|
"serverSide": true,
|
||||||
|
"pageLength": 50,
|
||||||
|
"searchDelay": 1200,
|
||||||
|
"ajax": {
|
||||||
|
"url": "/manage/rest/httpRequestInfos",
|
||||||
|
"type": "POST",
|
||||||
|
"dataType": "json",
|
||||||
|
"contentType": "application/json",
|
||||||
|
"data": function (d) {
|
||||||
|
return JSON.stringify(d);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"columns": [
|
||||||
|
{"data": "requestGroupName"},
|
||||||
|
{"data": "requestName"},
|
||||||
|
{"data": "url"},
|
||||||
|
{"data": "method", "searchable": false, "orderable": false},
|
||||||
|
{"data": "id", "searchable": false, "orderable": false},
|
||||||
|
{"data": "id", "searchable": false, "orderable": false}
|
||||||
|
],
|
||||||
|
"columnDefs": [
|
||||||
|
{
|
||||||
|
"render": function (data, type, row) {
|
||||||
|
return '<a href="/manage/getHttpRequestInfoForm/' + row.id + '">' + data + '</a>';
|
||||||
|
},
|
||||||
|
"targets": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"render": function (data, type, row) {
|
||||||
|
return '<a href="/manage/getHttpRequestInfoForm/' + data + '" class="btn btn-primary"><i class="fas fa-edit"></i></a>';
|
||||||
|
},
|
||||||
|
"targets": -2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"render": function (data, type, row) {
|
||||||
|
var msg = "'정말로 데이터를 삭제 하시겠습니까?'";
|
||||||
|
return '<a href="/manage/deleteHttpRequestInfo/' + data + '" onclick="return confirm(' + msg +');" class="btn btn-primary"><i class="fas fa-trash"></i></a>';
|
||||||
|
},
|
||||||
|
"targets": -1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buttons": ["new", "excel", "colvis"],
|
||||||
|
"initComplete": function() {
|
||||||
|
listHttpRequestInfoTable.buttons().container().appendTo('#listHttpRequestInfoTable_wrapper .col-md-6:eq(0)');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
$(".dataTables_filter input").unbind().bind("input", function(e) { // Bind our desired behavior
|
||||||
|
// If the length is 3 or more characters, or the user pressed ENTER, search
|
||||||
|
if(this.value.length >= 3 || e.keyCode == 13) {
|
||||||
|
// Call the API search function
|
||||||
|
listHttpRequestInfoTable.search(this.value).draw();
|
||||||
|
}
|
||||||
|
// Ensure we clear the search if they backspace far enough
|
||||||
|
if(this.value == "") {
|
||||||
|
listHttpRequestInfoTable.search("").draw();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
</script>
|
||||||
|
</th:block>
|
||||||
|
</html>
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<ol class="breadcrumb float-sm-right">
|
<ol class="breadcrumb float-sm-right">
|
||||||
<li class="breadcrumb-item"><a href="/">Home</a></li>
|
<li class="breadcrumb-item"><a href="/">Home</a></li>
|
||||||
<li class="breadcrumb-item active">스크립트 관리</li>
|
<li class="breadcrumb-item active">부가 기능</li>
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user