I have a JAX-RS service that I want to know what is the application context path. Before, I was using a HttpServletRequest to get the application url, using these methods:
public static String getApplicationBaseUrl(HttpServletRequest request) {
return String.format("%s://%s:%s%s",
request.getScheme(),
request.getServerName(),
request.getServerPort(),
request.getContextPath());
}
I saw the #Context in JAX-RS, but it returns only the paths beginning from JAX resource. What can I do for retrieve the application path?
I found the answer. I was using the #Context for javax.ws.rs.core.UriInfo class, but, I can inject the HttpServletRequest too. So, now I can use the getApplicationBaseUrl method that I wrote.
Related
I am using Spring MVC. I am not using Spring boot dependencies.
I created the AuthenticationSuccessEventListener class, this class implements the ApplicationListener interface.
How do I get the HttpServletRequest in the AuthenticationSuccessEventListener class? I tried many options, but I still could not find the answer to my question.
When trying to get the HttpServletRequest, I get an exception.
Message: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
Who can, tell me please, what am I doing wrong?
#Component
public class AuthenticationFailureListener implements ApplicationListener<AuthenticationSuccessEvent> {
// This option doesn't work.
// #Autowired
// HttpServletRequest httpServletRequest;
// This option doesn't work.
// HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
#Override
public void onApplicationEvent(AuthenticationSuccessEvent a) {
}
}
Is there any way in spring boot to grab header from request in any point of application?
Some static stuff will be great.
Please, be aware that #RequestHeader does not work for me since I need this value on service layer.
You can inject HttpServletRequest object in your service layer like this :
#Autowired
HttpServletRequest request;
private void method() {
request.getHeader("headerName");
}
but remember, that bean HttpServletRequest has HTTP request scope. So, you can't inject that into asynchronous methods etc, because it will throw Runtime Exception.
hope it helps.
I was searching the same question before, i found out that you can use header parameters in the RestController methods with #RequestHeader as you said. So why not direct them into your service layer methods:
#Autowired
ServiceLayerObj serviceLayerObj;
...
#RequestMapping
public YourReturnObj someRestServiceMethod(
#RequestBody SomeObj body,
#RequestHeader(value = "username") String username
){
return serviceLayerObj.yourServiceLayerMethod(body,username);
}
I recently went through restful web services tutorial, but couldn't understand what a context is. Can someone explain what it it and also what #Context does?
JAX-RS provides the #Context annotation to inject 12 object instances related to the context of the HTTP request and they are:
SecurityContext - Security context instance for the current HTTP request
Request - Used for setting precondition request processing
Application, Configuration, and Providers -> Provide access to the JAX-RS application, configuration, and providers instances
ResourceContext - Resource contect aclass instances
ServletConfig - The ServletConfig instance instance
ServletContext - The ServletContext instance
HttpServletRequest - The HttpServletRequest instance for the current request
HttpServletResponse - The HttpServletResponse instance for the current request
HttpHeaders - Maintains the HTTP header keys and values
UriInfo - Query parameters and path variables from the URI called
It is a little confusing to have both an #Inject (or #Autowired in Spring) and #Context that does the same job, but it is hoped to bring more alignment to Java EE in the next edition. In the meantime, you will have to make do.
An interesting feature is that all of these instances can be injected as a field value or directly into the resource method.
An example of injection into the resource method parameter list:
#Path("/")
public class EndpointResource {
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response getAllHttpHeaders(final #Context HttpHeaders httpHeaders){
// Code here that uses httpHeaders
}
}
An example of injection into a field:
#Path("/")
public class EndpointResource {
private final #Context HttpHeaders httpHeaders;
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response getAllHttpHeaders(){
// Code here that uses httpHeaders
}
}
If you want to know more, take a look at this series of articles answering the question What is #Conext in JAX-RS used for?
For an explanation about context in programming terms, have a look at this answer.
The JAX-RS API provides a #Context annotation. In general, such annotation can be used to obtain contextual Java types related to the request or response. Those types can be injected into classes managed by the JAX-RS runtime.
For example, to inject the HttpServletRequest in your resource method, you can do the following:
#GET
public Resonse foo(#Context HttpServletRequest request) {
...
}
Additional resources:
Types that can be injected with #Context
Jersey documentation about resources
context is a react Hook feature that helps to pass the data from one component to another without calling the props at each level ... it avoids prop drilling. by defining the provider in one context component and then you can call everywhere and every time when you need.
REST is an architectural style and one of the way to implement web-services. (Other is SOAP). There are many implementations of REST architecture and one of them in java is Jersey (https://jersey.java.net/)
#context is annotation in Jersey framework. It's a class from jax rs jar. (https://jersey.java.net/apidocs-javax.jax-rs/2.0.1/javax/ws/rs/core/Context.html)
Environment: JBoss AS 7, RestEasy 3.0.5.
I would like to use a preprocess filter in my application to authenticate a particular user and add this authenticated user to the request scope. I tried the following:
#Provider
public class SecurityFilter implements ContainerRequestFilter {
#Override
public void filter(ContainerRequestContext requestContext) {
// authenticate, lookup user code etc...
requestContext.setProperty("User", new User("test"));
}
}
And then access it at the bean level using:
#Stateless
public class TestBean {
#Context HttpServletRequest servletRequest;
#GET
#Path("/hello")
public String hello() {
return "Hello " + servletRequest.getAttribute("User");
}
}
However the Context elements are not injected when the bean is annotated as stateless (stateless is required for EJB logic) due to a 2 year old RestEasy bug.
Can anyone think of a solution to this issue?
Alternatively, is there a more typical solution that prepopulating these objects using a filter?
Kind thanks for reading.
What I have done before is that I have a web application, "facade" if you want, to the EJBs. The JAX-RS layer is implemented in this application. A servlet filter intercepts the request to the JAX-RS resources and calls a CDI service that implements the "authenticate, lookup user code etc" logic. On success, the CDI service exports the current user object to CDI. This user object is #Inject'ed in the EJBs.
If CDI is an option for you (and I don't see why not in this setup), you could do the same (i.e. export the User to CDI) from your SecurityFilter, without having to create a web-app.
Additionally the dependency of the service layer (EJBs) to web-specific APIs (HttpServletRequest) is a bit creepy; I really think dependency injection of the actual User object is the way to go.
Im new to java based web service development.
I need to create a web service which accepts multipart data(ex: zip file).
Please help me out how to mention that in the function.
below is my current web service code which is accepting data in the form of json.
#RequestMapping(value="/workitems/updateData", method=RequestMethod.POST)
#ResponseBody
public Object updateData(#RequestHeader String deviceToken, #RequestBody FormFields[]
formFields,HttpServletResponse response) throws Exception {
//some code
}
please guide me to how to accept the multipart data in the web service method.
thanks in advance.
#RequestMapping(
value ="/workitems/updateData",method=RequestMethod.POST ,headers="Accept=application/xml, application/json")
public #ResponseBody
Object updateData(HttpServletResponse response,#RequestHeader String deviceToken,
#RequestParam ("file") MultipartFile file) throws Exception {
}
You can support it as above.
You can use normal Upload technique which you use in Servlet - commons-fileupload.jar way.
The same code placed in a method inside your controller will work fine. Make sure you pass HttpServletRequest object to your method.