Spring MVC #AutoWired response not working - java

I have :
#Controller
#RequestMapping(value="admin/*", method=RequestMethod.GET)
public class AdminController {
#Autowired
private HttpServletRequest request;
#Autowired
private HttpServletResponse response;
#RequestMapping
public ResponseEntity<String> test0() {
System.out.println("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");
return null;
}
}
and the tag:
<mvc:annotation-driven />
in my config.xml
It should be enough I feel, but there is a problem with #Autowired:
No matching bean of type [javax.servlet.http.HttpServletResponse] found for dependency: expected at least 1 bean which qualifies ...
I have seen a couple of solutions mention setting up beans and such, but I am sure there has to be some better way. The annotation-scan should take care of this. It would suck if I have to set up beans in xml for several different annotations at different times. I just want the annotations to work when I use them!
I have seen:
Spring MVC - Response
Thanks!

As a workaround try:
#RequestMapping
public ResponseEntity<String> test0(
HttpServletRequest request,
HttpServletResponse response) {
System.out.println("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");
return null;
}
Also try adding RequestContextListener but this should't be required in Spring MVC environment.

Autowiring doesn't work for the response, only the request. There are workarounds, but they're kind of hacky and lame. I ran into the same issue, here's my original question with a link to the workaround: #Autowired HttpServletResponse

It does not work as you want it, as fields, because a request and respose changes after each request (in lack of better explanation). You cannot reinject every time the new request/response in the fields. That is why you have to add them in the method where they will be injected every time new.

Related

Get header from request in service layer of Spring Boot application

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);
}

Understanding REST APIs - What are Context and #Context?

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)

CDI and HttpRequest

I am using a helper class in a servlet to remove some code from the servlet itself. I am injecting this helper class in the servlet with the CDI #Inject and this is also marked as #RequestScoped bean. Since this helper class is used to remove some code from the servlet I need access to the httprequest, response and session in this class. Is there a way to make these available via injection? I tried to use #inject on a field of type
HttpServletRequest but I get an error from WELD.
There are a couple of alternative solutions to this.
You could pass the HttpServletRequest to the helper. I mean instead of the helper being:
#Inject HttpServletRequest request;
public Xxx doSomeHelperWork() {
// use request
}
Make it:
public Xxx doSomeHelperWork(HttpServletRequest request) {
// use request
}
Use the DeltaSpike servlet module which can handle the injection of HttpServletRequest.

handleNoSuchRequestHandlingMethod override not working

#Controller
public class CentralizedExceptionController extends DefaultHandlerExceptionResolver {
#Override
protected ModelAndView handleNoSuchRequestHandlingMethod(NoSuchRequestHandlingMethodException ex, HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("working?!");
return new ModelAndView();
}
I have this in my code, but in case of a 404 its never called.
(I dont have an error-page defined in my web.xml, and i dont want to)
Take a look at this jira issue: https://jira.springsource.org/browse/SPR-8837?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=72648#comment-72648
If your Spring dispatcher servlet is configured to process all/most URLs, then you are probably getting the 404 error along with this DispatcherServlet log message from console:
No mapping found for HTTP request with URI [xxx]
This indicates that Spring's DispatcherServlet is processing the request but do not have an appropriate #RequestMapping to dispatch to.
A simple solution would be to limit requests processed by dispatcher servlet by reconfiguring web.xml's servlet-mapping > url-pattern to only URLs specified by your application's #RequestMappings. However, this is NOT very practical (so don't do this).
One way to overcome this would be to create a #RequestMapping that handles all "unhandled" request mappings - some kind of fallback request mapping.
#RequestMapping("**")
#ResponseBody
public String fallbackRequestMapping() {
return "do something useful...";
}
Note that this answer is similar in approach to Dani's answer but written with annotation based development in mind. Therefore, it is useful to understand the associated Spring issue.
plz check. Your controller class name should not be Controller.java.
You need to use #ExceptionHandler annotation to your method:
#ExceptionHandler(NoSuchRequestHandlingMethodException.class)
public ModelAndView handleNoSuchRequestHandlingMethod(NoSuchRequestHandlingMethodException ex, HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
...
}

cache controller response

I'd like to use memcached to cache the response produced by my controllers. The controllers themselves are Grails controllers, but there's nothing really Grails-specific about the problem. If I could figure out how to solve this problem in a Spring MVC, Struts (or similar) application, I should easily be able to migrate the solution to Grails.
Ideally, I'd like to identify the controller methods that are eligible for caching using Java annotations. Is anyone aware of an existing solution for this problem? I should emphasise that I'm not interested in using any caching technology other than memcached.
Thanks,
Don
The Simple Spring Memcached library the previous poster linked to would actually accomplish what you need to do. It doesn't limit itself to just DAO methods. You could annotate a controller method to cache it's response just as easily as annotating a DAO method.
So, if you have a Controller named SimpleController and you wanted to cache the response of that controller, you could do the following
public class SimpleController implements Controller {
#ReadThroughSingleCache(namespace = "SimpleController", keyIndex = 0, expiration = 3600)
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
return new ModelAndView("index")
}
This will cache the response of the controller in Memcached for an hour and any request that comes in that matches the same request will return the cached response.
Aaron, braveterry,
Thanks for suggesting my project: http://code.google.com/p/simple-spring-memcached/
Don, Aaron is correct that SSM is not limited to DAO methods, however there are a few caveats for his example:
I don't think HttpServletRequest's toString() method would produce a good key
You would need to make sure that ModelAndView is Serializable
That being said, there's no reason you can't delegate to another bean that has an appropriate signature
Here's some code as an example:
public class SimpleController implements Controller {
private BeanWithAnnotatedMethod bean; // Injected resource
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {
Object keyObject = Helper.generateAppropriateKey(request);
String result = bean.annotatedMethod(keyObject);
return new ModelAndView(result)
}
Would something like this do the trick? http://code.google.com/p/simple-spring-memcached/

Categories

Resources