I have added this line
environment.jersey().register(new LoggingFeature(Logger
.getLogger(LoggingFeature.class.getName()), Level.OFF,
LoggingFeature.Verbosity.PAYLOAD_TEXT, null));
in my run(Configuration configuration, Environment environment) method looking at this and this
I am only getting stuff in the logs if the Level is set to OFF and all my requests/response messages are logged as ERROR, but why ERROR?
Here is an example of the log:
ERROR [11:17:41.603] [dw-31 - GET /helloworld] o.g.j.l.LoggingFeature - 1
* Server has received a request on thread dw-31 - GET /helloworld
1 > GET http://localhost:8080/helloworld
1 > Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
1 > Accept-Encoding: gzip, deflate, sdch, br
1 > Accept-Language: en-US,en;q=0.8
1 > Cache-Control: max-age=0
1 > Connection: keep-alive
1 > Cookie: openid_provider=openid; _ga=GA1.1.1009619719.1483436711
1 > Host: localhost:8080
1 > Upgrade-Insecure-Requests: 1
1 > User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36
ERROR [11:17:41.615] [dw-31 - GET /helloworld] o.g.j.l.LoggingFeature - 1 * Server responded with a response on thread dw-31 - GET /helloworld
1 < 200
My Resource class:
#Path("/helloworld")
#Produces(MediaType.APPLICATION_JSON)
public class HelloWorldResource {
public HelloWorldResource() { }
#GET
public Response helloWorld(){
System.out.println("Hello World");
return Response.ok().build();
}
}
My main application class:
public class ApiApplication extends Application<ApiConfiguration>{
public static void main(String[] args) throws Exception{
new ApiApplication().run(args);
}
#Override
public void initialize(Bootstrap<ApiConfiguration> bootstrap) {
// nothing to do yet
}
#Override
public void run(ApiConfiguration apiConfiguration, Environment environment) throws Exception {
final TemplateHealthCheck healthCheck =
new TemplateHealthCheck(apiConfiguration.getTemplate());
environment.healthChecks().register("template", healthCheck);
final HelloWorldResource helloWorldResource = new HelloWorldResource();
final JerseyEnvironment jerseyEnvironment = environment.jersey();
jerseyEnvironment.register(helloWorldResource);
jerseyEnvironment.register(new LoggingFeature(Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME), Level.OFF, LoggingFeature.Verbosity.PAYLOAD_ANY, Integer.MAX_VALUE));
}
}
You shall try changing the LoggingFeature to -
environment.jersey().register(new LoggingFeature(
Logger.getLogger(LoggingFeature.class.getName()), Level.FINE,
LoggingFeature.Verbosity.PAYLOAD_TEXT, null));
Since the current logging is set to Level.OFF. The application does not try to log anything and returns from the filter implementation of ContainerRequestFilter and filter implementation of ContainerResponseFilter interfaces with the java.util.Logger within which the log(LogRecord) method is overriden by some subclass of Logger which is modifying the level to ERROR.
I would second the thought of this implementation to be considered as poor. Expecting at the same time that changing to Level.OFF shouldn't log anything at all. (at least not under ERROR)
At the same time the verbosity specified is LoggingFeature.Verbosity.PAYLOAD_TEXT so the entire
Content of HTTP headers as well as entity content of textual media
types is logged.
which is the details after your [ERROR] message in the logs.
Related
I currently try to set up a Xtext web editor with "Context Mapper" as DSL.
The backend is a basic Spring Boot backend with the Context Mapper DSL and Context Mapper LSP (Language Server).
The frontend is a VueJS frontend made with the help of this guide. It utilizes everything Eclipse Xtext generates and ports it to a VueJS website.
My only issue now is that the "/xtext-service/*" API return CORS errors with HTTP code 404 while the console of the backend prints absolutely nothing.
The Servlet looks like every other XtextServlet:
#WebServlet(name = "XtextServices", urlPatterns = "/xtext-service/*")
#SuppressWarnings("all")
public class ContextMappingDSLServlet extends XtextServlet {
private DisposableRegistry disposableRegistry;
#Override
public void init() {
try {
super.init();
final Injector injector = new ContextMappingDSLWebSetup().createInjectorAndDoEMFRegistration();
this.disposableRegistry = injector.<DisposableRegistry>getInstance(DisposableRegistry.class);
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
#Override
public void destroy() {
if ((this.disposableRegistry != null)) {
this.disposableRegistry.dispose();
this.disposableRegistry = null;
}
super.destroy();
}
}
The requests are also the standard requests the Xtext generated web editor invokes and the occurrences request goes through it seems:
Response:
HTTP/1.1 404
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: http://localhost:8081
Access-Control-Allow-Credentials: true
Content-Type: application/json
Transfer-Encoding: chunked
Date: Fri, 21 Oct 2022 16:03:19 GMT
Keep-Alive: timeout=60
Connection: keep-alive
Request:
GET /xtext-service/occurrences?resource=1e26589b.cml&caretOffset=1 HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,de;q=0.8
Cache-Control: no-cache
Connection: keep-alive
Cookie: JSESSIONID=CDE6CC29EE123451F3DF3FF174337EE3
Host: localhost:8080
Origin: http://localhost:8081
Pragma: no-cache
Referer: http://localhost:8081/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36
sec-ch-ua: "Chromium";v="106", "Google Chrome";v="106", "Not;A=Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
The requests to http://localhost:8080/xtext-service/occurrences?resource=1e26589b.cml&caretOffset=1 returns 404 while update throws
Access to XMLHttpRequest at 'http://localhost:8080/xtext-service/update?resource=1e26589b.cml' from origin 'http://localhost:8081' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
CORS however is enabled:
#Configuration
#EnableWebMvc
public class WebConfiguration implements WebMvcConfigurer {
#Override
public void addCorsMappings(CorsRegistry registry) {
registry
.addMapping("/**")
.allowedMethods(CorsConfiguration.ALL)
.allowedHeaders(CorsConfiguration.ALL)
.allowedOriginPatterns(CorsConfiguration.ALL)
.allowCredentials(true);
}
}
The non-servlet APIs do work without any issues, but the Xtext-service servlet doesn't, and I don't know why.
#ServletComponentScan is enabled.
I have to add an information in the cookie of a request that my application sends to another application,
but it doesn't seem to be added correctly.
When I check the request with WireShark, I see two Cookie headers in the headers :
POST /service HTTP/1.1
Accept-Encoding: gzip
Cookie: iam=**************************
Accept: text/xml, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
SOAPAction: ""
Content-Type: text/xml; charset=utf-8
Content-Length: 128393
Host: host-dev:9999
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.10 (Java/1.8.0_271)
Cookie: JSESSIONID=***********************
Authorization: Basic **************************
(I've changed some of the info)
In my code I have this :
#Service
public class ESignatureSoapConnector extends WebServiceGatewaySupport {
private ObjectFactory objectFactory;
#Autowired
public ESignatureSoapConnector(ESignatureMarshaller marshaller, ConfigurationProperties configurationProperties) throws Exception {
this.setMarshaller(marshaller);
this.setUnmarshaller(marshaller);
this.setDefaultUri(configurationProperties.getBaseUrl());
this.setMessageSender(buildMessageSender(configurationProperties.getUsername(), configurationProperties.getPassword()));
this.objectFactory = new ObjectFactory();
}
public ESignatureResponse signDocument(MTOMFile file, String iamCookieValue) {
ESignature request = new ESignature();
request.setInputDocument(file);
JAXBElement<ESignatureResponse> response = (JAXBElement<ESignatureResponse>) getWebServiceTemplate()
.marshalSendAndReceive(objectFactory.createESignature(request), new WebServiceMessageCallback() {
#Override
public void doWithMessage(WebServiceMessage webServiceMessage) throws IOException, TransformerException {
TransportContext context = TransportContextHolder.getTransportContext();
HttpComponentsConnection connection = (HttpComponentsConnection) context.getConnection();
HttpPost post = connection.getHttpPost();
post.addHeader("Cookie", "iam=" + iamCookieValue);
}
});
return response.getValue();
}
private WebServiceMessageSender buildMessageSender(String username, String password) throws Exception {
...
}
}
I'm assuming the way I set the cookie isn't correct but I can't find the proper way to do it.
The value for the cookie is different for each request, it's a soap request and I work in Spring
The solution we've found :
JAXBElement<ESignatureResponse> response = (JAXBElement<ESignatureResponse>) getWebServiceTemplate()
.marshalSendAndReceive(objectFactory.createESignature(request), new WebServiceMessageCallback() {
#Override
public void doWithMessage(WebServiceMessage webServiceMessage) throws IOException, TransformerException {
HttpClient httpClient = ((HttpComponentsMessageSender) getWebServiceTemplate().getMessageSenders()[0]).getHttpClient();
BasicClientCookie iamCookie = new BasicClientCookie(iamConfigurationProperties.getCookieName(), iamCookieValue);
iamCookie.setDomain(iamConfigurationProperties.getCookieDomain());
iamCookie.setPath(iamConfigurationProperties.getCookiePath());
((DefaultHttpClient) httpClient).getCookieStore().addCookie(iamCookie);
}
});
I am new to CORS headers and implementing with Spring boot. I am enabling CORS header on POST service which accept request body.
First time preflight request is made which runs fine and return 200 but when actual post request is invoked, it always return 403 forbidden with response body "Invalid CORS request". I have read almost all spring docs and all google/stackoverflow discussions but could not find out what am I missing..huh..
In Below snippet I have tested by adding crossOrigin at top of class and top of method but no luck.
#CrossOrigin(origins = "https://domain/", allowCredentials = "false")
#RequestMapping(value = ApplicationConstants.URI_PATH)
class MainController {
#RequestMapping(value = '/postMethod', method = RequestMethod.POST)
Map<String, Object> postMethod(HttpServletResponse servletResponse,
#RequestBody(required = false) AccessToken requestedConsumerInfo) {...}
For POST method - Preflight request is invoked and result is 200 but main POST call returns 403.
Call with OPTIONS: Status code 200
Response headers (616 B)
Access-Control-Allow-Credentials true
Access-Control-Allow-Headers content-type
Access-Control-Allow-Methods POST
Access-Control-Allow-Origin https://domain
Allow GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH
Cache-Control max-age=0, private, no-cache, …roxy-revalidate, no-transform
Connection close
Content-Length 0
Date Wed, 20 Dec 2017 17:57:14 GMT
Pragma no-cache
Server nginx/1.9.1
Strict-Transport-Security max-age=63072000; includeSubdomains;
Vary Origin,User-Agent
X-Frame-Options SAMEORIGIN
X-XSS-Protection 1; mode=block
Request headers (512 B)
Accept text/html,application/xhtml+xm…plication/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate, br
Accept-Language en-US,en;q=0.5
Access-Control-Request-Headers content-type
Access-Control-Request-Method POST
Connection keep-alive
Host domain
Origin https://domain
User-Agent Mozilla/5.0 (Windows NT 6.1; W…) Gecko/20100101 Firefox/57.0
Call with POST: Status code 403
Response headers (364 B)
Cache-Control max-age=0, private, no-cache, …roxy-revalidate, no-transform
Connection close
Content-Length 20
Date Wed, 20 Dec 2017 17:57:14 GMT
Pragma no-cache
Server nginx/1.9.1
Strict-Transport-Security max-age=63072000; includeSubdomains;
Vary User-Agent
X-Frame-Options SAMEORIGIN
X-XSS-Protection 1; mode=block
Request headers (2.507 KB)
Accept application/json, text/plain, */*
Accept-Encoding gzip, deflate, br
Accept-Language en-US,en;q=0.5
Connection keep-alive
Content-Length 102
Content-Type application/json
Cookie rxVisitor=1513720811976ARCUHEC…B4SL3K63V8|6952d9a33183e7bc|1
Host domain
Origin https://domain
Referer https://domain/home/account/register
User-Agent Mozilla/5.0 (Windows NT 6.1; W…) Gecko/20100101 Firefox/57.0
Since this was not working, I have also tested by adding global configurations alone and also along with above snippet but no luck.
#Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
#Override
void addCorsMappings(CorsRegistry registry) {
super.addCorsMappings(registry);
registry.addMapping(ApplicationConstants.MEMBER_URL_PATH)
.allowedOrigins("https://domain/")
.allowedMethods(HttpMethod.GET.toString(),
HttpMethod.POST.toString(), HttpMethod.PUT.toString());
}
}
}
On the preflight OPTIONS request, the server should respond with all the following (looks like you're doing this already):
Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers, Access-Control-Allow-Credentials (if cookies are passed)
On the actual POST request, you'll need to return at least Access-Control-Allow-Origin and Access-Control-Allow-Credentials. You're not currently returning them for the POST response.
I had the same issue, then used the annotation #CrossOrigin and it works fine, but just for GET, when I tried to make a POST I still got Cross Origin error, then this fixed for me:
Create an interceptor and added the Access Controll headers to the response.
(You might not need all of them)
public class AuthInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse httpResponse, Object handler, ModelAndView modelAndView)
throws Exception {
httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
httpResponse.setHeader("Access-Control-Allow-Headers", "*");
httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpResponse.setHeader("Access-Control-Max-Age", "4800");
}
}
Then add the interceptor:
#Configuration
#EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addInterceptors(InterceptorRegistry registry) {
System.out.println("++++++ WebConfig addInterceptors() ");
registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/**");
}
}
I hope this save you some time, it took me a while to get this working .
How to disable HTTP delete in Spring MVC. I tried Interceptor but it doesnt work for Delete requests.
In my AppInitializer
#Override
protected void customizeRegistration(Dynamic registration) {
registration.setInitParameter("dispatchDeleteRequest", "true");
}
tried this.
I am making a call of the form
OPTIONS /<Website>/ HTTP/1.0
Content-Length: 0
Accept: */*
Accept-Language: en-US
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Win64; x64; Trident/4.0; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; Tablet PC 2.0)
Host: XYZ.com
And the response I am getting is
HTTP/1.1 200 OK
Content-Length: 0
Server: Apache-Coyote/1.1
Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Date: Mon, 10 Nov 2014 10:51:02 GMT
Connection: close
UPDATE :-One way I can think of doing it
#Controller
public class HandleDeleteRequest{
static final Logger logger = Logger.getRootLogger();
#RequestMapping(value = "/*", method = RequestMethod.DELETE)
public boolean handleDeleteRequest(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
logger.info(request.getMethod());
if (request.getMethod().equalsIgnoreCase("DELETE")) {
// Not a POST/GET - send error and return false
logger.error("Not Get or Put request");
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Unauthorized Request");
return false;
}
return true;
}
}
But this one doesnt seem to be appropriate
I'm sending the following request:
GET http://127.0.0.1:8080/ajax/rest/teamService/list HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31
Referer: http://127.0.0.1:8080/do/controlpanel
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: JSESSIONID=MMezuISPiL9aOEvxmoOKbUWI.undefined
My spring service xml maps /ajax to a controller. This mapping should respond:
#RequestMapping(value = "/rest/*")
public #ResponseBody JSONResponse team(#ModelAttribute("cpSession") ControlPanelSession sess, Model model, HttpServletRequest request) {
...
}
Other mappings in the same controller answer /ajax calls just fine. For instance:
#RequestMapping(value = "/isFNameOK", method = RequestMethod.GET)
#ResponseBody
public String isFNameOK(#ModelAttribute("cpSession") ControlPanelSession sess, Model model, HttpServletRequest request, #RequestParam("fName") String fName) {
...
}
But apparently it's not, because I'm getting:
No mapping found for HTTP request with URI [/ajax/rest/teamService/list]
Any ideas?
/rest/* will match /rest/teamService, but not /rest/teamService/list.
You could use /rest/** to match everything under the /rest path. However, you might prefer to use:
#RequestMapping(value = "/rest/{service}/{action}")
public #ResponseBody JSONResponse team(#PathVariable String service, #PathVariable String action, ...) {
Which will match your URL, and provide the wild-carded parts in your method body for further inspection.