Using CookieParam annotation with Spring MVC Controller - java

I'm trying to use the javax.ws.rs.CookieParam annotation to grab a cookie from the HTTP request to a method on my controller.
#Override
public void cookieTest( #CookieParam("testToken") String testCookie, HttpServletRequest request ) {
Cookie[] cookies = request.getCookies();
for( Cookie cookie : cookies ) {
if( cookie.getName().equals( "testToken" ) ) {
System.out.println( "found testToken" );
}
}
}
However I get the following error:
Caused by: java.lang.IllegalStateException: No parameter name specified for argument of type [java.lang.String], and no parameter name information found in class file either.
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.getRequiredParameterName(HandlerMethodInvoker.java:729)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveRequestParam(HandlerMethodInvoker.java:488)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.java:348)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:171)
... 67 more
The controller does have an interface, but I added the CookieParam annotation in both places with the correct name. If I remove the testCookie parameter, I can iterate through the request.getCookies() and see that the cookie does exist. Is there a step I'm missing?
I'm using Spring 3 and Java 6.

You are using wrong annotation. Use #CookieValue instead https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/CookieValue.html

This is the declaration of one of my controller methods that makes use of a cookie :
#RequestMapping(value = {"/"}, method = RequestMethod.GET)
public String home(ModelMap model, HttpServletRequest request,
#CookieValue(value = "aCookie", defaultValue = "someRandomValue") String aValue)

Related

How can i access request headers in graphql query using java datafetcher environment?

I want to fetch a header value I am passing during a GraphQl Query call. Something like we can do prior in case of rest api
HttpServletRequest.getheader()
I wanted to fetch it from the dataFetchingEnvironment but the context fetched from this value did not get me any means to fetch the header values from request.
try {
GraphQLContext context = env.getGraphQlContext();
String Id= context.getHeader("headerkeyIpass");
// I know this method does not exist i am trying to paint a picture as to what i am asking
I do not intend to change the resolver method calls but any inputs to improve my code would be great.
Like you said getHttpServletRequest does not exist on DataFetchingEnvironment.getGraphQlContext() when using the new official Spring 2.7 spring-boot-starter-graphql (not the legacy GraphQL Java Kickstart ones).
Instead you can add an autowired HttpServletRequest request variable at the top of your controller and inside each query resolver it will be filled with the request context.
#Controller
public class SomeGraphQLController {
...
#Autowired
private HttpServletRequest request; // will be filled inside each #QueryResolver and #MutationResolver method.
...
#QueryResolver
public XXX yyyy() {
...
try {
String someHeader = request.getHeader("someHeader");
...
}
}
The GraphQLContext has method getHttpServletRequest() which returns
java.util.Optional<javax.servlet.http.HttpServletRequest>
So from there u can get the headers
GraphQLContext context = env.getGraphQlContext();
HttpServletRequest request = context.getHttpServletRequest().get();
String Id= request.getHeader("headerkeyIpass");
If you are using the latest graphql libraries there are some breaking changed and you can get the headers from GraphQLServletContext as shown here
GraphQLServletContext graphQLServletContext = (GraphQLServletContext) env.getContext();
String user = graphQLServletContext.getHttpServletRequest().getHeader("user");

Spring MVC #SessionAttribute Missing session attribute of type String[] error

I was having some problem when trying to use #SessionAttribute in Spring MVC Controller. Basically what I am trying to do is, in my API, I want to retrieve from the session, if it contains data, fetch it out, then remove the session itself. Here is my controller class:
#SessionAttributes({WebKeys.SEARCH_RESULT_LIST_THREE})
public class ALController {
#RequestMapping(value = "/search.do", method = { RequestMethod.POST })
public String doSearchList(Model model, #ModelAttribute("attendanceTO") AttendanceTO attendanceSearchForm, #SessionAttribute(WebKeys.SEARCH_RESULT_LIST_THREE) String[] selectedRecords) {
// removed code
attendanceSearchForm.setSelectedRecords(null);
// checking from session
if(selectedRecords != null && selectedRecords.length > 0){
attendanceSearchForm.setSelectedRecords(selectedRecords);
}
model.addAttribute("selectedRecords", selectedRecords);
// remove session
model.addAttribute(WebKeys.SEARCH_RESULT_LIST_THREE, null);
}
}
At this point of time, the session is not existed yet. I only set up the session when user submit form. I am getting this error messages:
Missing session attribute 'key.searchResultList.three' of type String[]
Any ideas on how to resolve this? Thanks!
U should add a required parameter to the #SessionAttribute annotation and set its value to false,meaning it's not necessary,like
#SessionAttribute(name=WebKeys.SEARCH_RESULT_LIST_THREE,required=false)

Spring REST get url path for multiple mapped endpoint

I have REST endpoint with multiple paths as following:
#RequestMapping(method = RequestMethod.POST, path = {"/xxx/yyy", "/zzz"})
#ResponseBody
public Mono<EpcPain> paymentOrder(#RequestHeader(name = "Timeout", defaultValue = "10000") int timeout,
#RequestHeader(name = "X-Request-Id", required = false) String xRequestId) {
...
}
How can I resolve if request path was xxx/yyy or zzz? I do not want to duplicate this endpoint nor pass some params. I am looking for some spring code magic.
org.springframework.web.context.request.RequestContextHolder may be used to get the path
import static org.springframework.web.servlet.HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE;
import static org.springframework.web.servlet.HandlerMapping.LOOKUP_PATH;
import static org.springframework.web.servlet.HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE;
and
#RequestMapping(value = {"/getDetails","/getDetailsMore"}, method = RequestMethod.GET)
public String getCustomerDetails(TestFormBean bean) {
RequestAttributes reqAttributes = RequestContextHolder.currentRequestAttributes();
System.out.println(reqAttributes.getAttribute(BEST_MATCHING_PATTERN_ATTRIBUTE, 0));
System.out.println(reqAttributes.getAttribute(LOOKUP_PATH, 0));
System.out.println(reqAttributes.getAttribute(PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, 0));
return "test";
}}
All three prints the path.
Here 0 - is request scope and 1 - is session scope.
Hope this helps.
You could add ServerHttpRequest as a method argument and then get the URI for the current request using getURI(). It should work for both Spring MVC and Spring WebFlux.
Have a look at the handler methods documentation for details.

How to extract a variable value in Spring AOP advise

The authentication method has been integrated with every REST calls in the API. I have been trying to implement an authentication method via Spring AOP so that I can remove all the duplicate code from end-points and have one single advise to look for all public methods in Controllers.
Please check the below my code,
#Aspect
public class EndpointAccessAspect {
/**
* All the request mappings in controllers need to authenticate and validate end-point access
*/
#Before("execution(public * com.xxxx.webapi.controllers.MenuController.getCategory(HttpServletRequest)) && args(request)")
public void checkTokenAccess(HttpServletRequest request){
String re =(String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
System.out.println(" %%%%%%%%%%%%%%%%%%% checkTokenAccess %%%%%%%%%%%%%%%" + re);
}
public void checkEndPointPermission(){
System.out.println(" $$$$$$$$$$$$$$$$$$ checkEndPointPermission &&&&&&&&&&&&&");
}
}
However, I saw Intelij gives error near getCategory(HttpServletRequest)) && args(request) saying can not resolve symbol HttpServletRequest. I need the request to distingues each REST end-points. There are more variables than HttpServletRequest variable in the method but only that variable is needed.
The code is compiling when I test the functionality I noticed it doesn't reach to the advise. Can anybody help me to fix this?
I found this from Spring documentation
Spring doc
any join point (method execution only in Spring AOP) which takes a
single parameter, and where the argument passed at runtime is
Serializable
Does this mean I can not use methods that have multiple parameters?
Controller end-point
#RequestMapping(value = "{menuId}/categories/{categoryId}", method = RequestMethod.GET)
#ApiResponses(value = {
#ApiResponse(code = 200, message = "Successful retrieval of a category requested", response = ProductGroupModel.class),
#ApiResponse(code = 500, message = "Internal server error") })
public ProductGroupModel getCategory(
#ApiParam(name = "menuId", value = "Numeric value for menuId", required = true) #PathVariable(value = "menuId") final String menuId,
#ApiParam(name = "categoryId", value = "Numeric value for categoryId", required = true) #PathVariable(value = "categoryId") final String categoryId,
final HttpServletRequest request) {
The following syntax, resolved the above issue. Basically, I had to modify the code to deal with multiple parameters in the advise.
#Before("execution(public * com.xxxx.webapi.controllers.MenuController.getCategory( HttpServletRequest,..)) && args(request, ..)")
public void checkTokenAccess(HttpServletRequest request){
String re =(String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
System.out.println(" %%%%%%%%%%%%%%%%%%% checkTokenAccess %%%%%%%%%%%%%%%" + re);
}

java - get cookie value by name in spring mvc

I'm working on a java spring mvc application. I have set a cookie in one of my controller's methods in this way:
#RequestMapping(value = {"/news"}, method = RequestMethod.GET)
public ModelAndView news(Locale locale, Model model, HttpServletResponse response, HttpServletRequest request) throws Exception {
...
response.setHeader("Set-Cookie", "test=value; Path=/");
...
modelAndView.setViewName("path/to/my/view");
return modelAndView;
}
This is working fine and I can see a cookie with name test and value "value" in my browser console. Now I want to get the cookie value by name in other method. How can I get value of test cookie?
The simplest way is using it in a controller with the #CookieValue annotation:
#RequestMapping("/hello")
public String hello(#CookieValue("foo") String fooCookie) {
// ...
}
Otherwise, you can get it from the servlet request using Spring org.springframework.web.util.WebUtils
WebUtils.getCookie(HttpServletRequest request, String cookieName)
By the way, the code pasted into the question could be refined a bit. Instead of using #setHeader(), this is much more elegant:
response.addCookie(new Cookie("test", "value"));
You can also use org.springframework.web.util.WebUtils.getCookie(HttpServletRequest, String).
private String getCookieValue(HttpServletRequest req, String cookieName) {
return Arrays.stream(req.getCookies())
.filter(c -> c.getName().equals(cookieName))
.findFirst()
.map(Cookie::getValue)
.orElse(null);
}
Spring MVC already gives you the HttpServletRequest object, it has a getCookies() method that returns Cookie[] so you can iterate on that.
private String extractCookie(HttpServletRequest req) {
for (Cookie c : req.getCookies()) {
if (c.getName().equals("myCookie"))
return c.getValue();
}
return null;
}
Cookie doesnt have method to get by value try this
Cookie cookie[]=request.getCookies();
Cookie cook;
String uname="",pass="";
if (cookie != null) {
for (int i = 0; i < cookie.length; i++) {
cook = cookie[i];
if(cook.getName().equalsIgnoreCase("loginPayrollUserName"))
uname=cook.getValue();
if(cook.getName().equalsIgnoreCase("loginPayrollPassword"))
pass=cook.getValue();
}
}

Categories

Resources