From 9d10e6b4aad99d250faec406c17fb19d15cc9bbb Mon Sep 17 00:00:00 2001 From: hsoh Date: Mon, 31 Oct 2022 18:05:00 +0900 Subject: [PATCH] =?UTF-8?q?Http=20=EC=9A=94=EC=B2=AD=20=EA=B8=B0=EB=8A=A5?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 + .../eactive/httpmockserver/ApiController.java | 19 +- .../httpmockserver/HttpRequestInfo.java | 142 ++++++++ .../HttpRequestInfoController.java | 303 +++++++++++++++++ .../httpmockserver/HttpRequestInfoDao.java | 8 + .../HttpRequestInfoService.java | 23 ++ .../HttpRequestInfoServiceImpl.java | 76 +++++ .../httpmockserver/HttpResponseInfo.java | 36 ++ .../resources/templates/fragment/sidebar.html | 6 + .../templates/page/add-edit-api.html | 12 +- .../page/add-edit-bytes-message-spec.html | 6 +- .../page/add-edit-http-request-info.html | 321 ++++++++++++++++++ .../templates/page/add-edit-script-info.html | 8 +- .../resources/templates/page/list-api.html | 2 - .../page/list-http-request-info.html | 165 +++++++++ .../templates/page/list-script-info.html | 2 +- 16 files changed, 1106 insertions(+), 25 deletions(-) create mode 100644 src/main/java/com/eactive/httpmockserver/HttpRequestInfo.java create mode 100644 src/main/java/com/eactive/httpmockserver/HttpRequestInfoController.java create mode 100644 src/main/java/com/eactive/httpmockserver/HttpRequestInfoDao.java create mode 100644 src/main/java/com/eactive/httpmockserver/HttpRequestInfoService.java create mode 100644 src/main/java/com/eactive/httpmockserver/HttpRequestInfoServiceImpl.java create mode 100644 src/main/java/com/eactive/httpmockserver/HttpResponseInfo.java create mode 100644 src/main/resources/templates/page/add-edit-http-request-info.html create mode 100644 src/main/resources/templates/page/list-http-request-info.html diff --git a/build.gradle b/build.gradle index 2629020..0bf6f88 100644 --- a/build.gradle +++ b/build.gradle @@ -33,6 +33,8 @@ dependencies { // implementation 'com.google.jimfs:jimfs:1.2' 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 'commons-io:commons-io:2.11.0' diff --git a/src/main/java/com/eactive/httpmockserver/ApiController.java b/src/main/java/com/eactive/httpmockserver/ApiController.java index 7fc1cc2..8507233 100644 --- a/src/main/java/com/eactive/httpmockserver/ApiController.java +++ b/src/main/java/com/eactive/httpmockserver/ApiController.java @@ -1,6 +1,5 @@ package com.eactive.httpmockserver; -import java.lang.reflect.InvocationTargetException; import java.util.Map; import java.util.Map.Entry; import java.util.Random; @@ -8,11 +7,6 @@ import java.util.Random; import javax.servlet.http.HttpServletRequest; 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.math.NumberUtils; import org.slf4j.Logger; @@ -24,10 +18,14 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; 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 public class ApiController { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @@ -48,7 +46,10 @@ public class ApiController { HttpServletResponse response) throws Exception { logger.info("=================================================="); logger.info("=================================================="); - logger.info(request.getServletPath()); + logger.info("request.getProtocol()= {}", request.getProtocol()); + logger.info("request.getMethod()= {}", request.getMethod()); + logger.info("request.getServletPath()= {}", request.getServletPath()); + logger.info("request.getQueryString()= {}", request.getQueryString()); logger.info("--------------------------------------------------"); logger.info("httpEntity.getHeaders().toString()= {}", httpEntity.getHeaders()); logger.info("--------------------------------------------------"); @@ -58,7 +59,7 @@ public class ApiController { Map paramMap = request.getParameterMap(); for (Entry entry : paramMap.entrySet()) { for (String value : entry.getValue()) { - logger.info("{}={}", entry.getKey(), value); + logger.info("request.getParameter({})={}", entry.getKey(), value); } } diff --git a/src/main/java/com/eactive/httpmockserver/HttpRequestInfo.java b/src/main/java/com/eactive/httpmockserver/HttpRequestInfo.java new file mode 100644 index 0000000..1308551 --- /dev/null +++ b/src/main/java/com/eactive/httpmockserver/HttpRequestInfo.java @@ -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 + "]"; + } +} diff --git a/src/main/java/com/eactive/httpmockserver/HttpRequestInfoController.java b/src/main/java/com/eactive/httpmockserver/HttpRequestInfoController.java new file mode 100644 index 0000000..f23d68e --- /dev/null +++ b/src/main/java/com/eactive/httpmockserver/HttpRequestInfoController.java @@ -0,0 +1,303 @@ +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 urlParameters = assignQueryParams(httpRequestInfo.getQueryParams()); + if (urlParameters != null && urlParameters.size() > 0) { + URI uri = new URIBuilder(base.getURI()).addParameters(urlParameters).build(); + base.setURI(uri); + } + + // heaser 셋팅 + base.setHeader("Connection", "close"); + 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 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 assignQueryParams(String queryParams) { + if (StringUtils.isBlank(queryParams)) { + return null; + } + + List 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 getAllHttpRequestInfosForDatatables(@RequestBody DataTablesRequest req) { + Pageable pageable = ApiManageRestController.assignJpaPageable(req); + + // search option + Example 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 res = new DataTablesResponse( + 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 id) { + if (id.isPresent()) { + Optional 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"; + } +} diff --git a/src/main/java/com/eactive/httpmockserver/HttpRequestInfoDao.java b/src/main/java/com/eactive/httpmockserver/HttpRequestInfoDao.java new file mode 100644 index 0000000..c7af1fc --- /dev/null +++ b/src/main/java/com/eactive/httpmockserver/HttpRequestInfoDao.java @@ -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 { +} diff --git a/src/main/java/com/eactive/httpmockserver/HttpRequestInfoService.java b/src/main/java/com/eactive/httpmockserver/HttpRequestInfoService.java new file mode 100644 index 0000000..bccd5bd --- /dev/null +++ b/src/main/java/com/eactive/httpmockserver/HttpRequestInfoService.java @@ -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 findById(Long id); + + public HttpRequestInfo save(HttpRequestInfo httpRequestInfo); + + public List findAllHttpRequestInfos(Pageable pageable); + + public List findHttpRequestInfos(Example example, Pageable pageable); + + public HttpRequestInfo update(HttpRequestInfo httpRequestInfo); + + public void delete(Long id); + + public long getRecordsCount(Example example); +} diff --git a/src/main/java/com/eactive/httpmockserver/HttpRequestInfoServiceImpl.java b/src/main/java/com/eactive/httpmockserver/HttpRequestInfoServiceImpl.java new file mode 100644 index 0000000..f5b637f --- /dev/null +++ b/src/main/java/com/eactive/httpmockserver/HttpRequestInfoServiceImpl.java @@ -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 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 findAllHttpRequestInfos(Pageable pageable) { + Page pagedResult = httpRequestInfoDao.findAll(pageable); + if (pagedResult.hasContent()) { + return pagedResult.getContent(); + } else { + return new ArrayList(); + } + } + + @Override + public List findHttpRequestInfos(Example example, Pageable pageable) { + if (example == null) { + return findAllHttpRequestInfos(pageable); + } + + Page pagedResult = httpRequestInfoDao.findAll(example, pageable); + if (pagedResult.hasContent()) { + return pagedResult.getContent(); + } else { + return new ArrayList(); + } + } + + @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 example) { + if (example == null) { + return httpRequestInfoDao.count(); + } else { + return httpRequestInfoDao.count(example); + } + } +} diff --git a/src/main/java/com/eactive/httpmockserver/HttpResponseInfo.java b/src/main/java/com/eactive/httpmockserver/HttpResponseInfo.java new file mode 100644 index 0000000..eb7e604 --- /dev/null +++ b/src/main/java/com/eactive/httpmockserver/HttpResponseInfo.java @@ -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 + "]"; + } +} diff --git a/src/main/resources/templates/fragment/sidebar.html b/src/main/resources/templates/fragment/sidebar.html index a5eaab1..facbf0b 100644 --- a/src/main/resources/templates/fragment/sidebar.html +++ b/src/main/resources/templates/fragment/sidebar.html @@ -89,6 +89,12 @@