How to remove HttpServletRequest parameters (in JSP)? - java

How can an HttpServletRequest parameter (especially in JSP) be unset or removed (like in PHP using the unset($_POST['index']) function)? I have tried the following.
Map requestMap=request.getParameterMap();
requestMap.remove("index");
but it says
No modifications are allowed to a locked ParameterMap
Is there a way to unset request parameters?

Is there a way to unset request parameters?
AFAIK, not within the JSP itself (or any Servlet for that matter).
But you could write a Filter that wrapped the current Request in a way that replaces the parameter map.

What you have to do is write a HttpFilter, write a HttpRequestWrapper of yours(MyRequestWrapper). Override the getParameter method of HttpRequestWrapper in your MyRequestWrapper such that you don't return parameters(may be always return null).
Within filter code, you should override the doFilter method and create a new MyRequestWrapper from ServletRequest Object, then do chanin.doFilter(myRequestWrapper, response)

Related

How to get parameters from the URL in Liferay

I have a portlet developed in Liferay, in which I want to get query parameter value from URL.
I tried this way but get "null" value from Query parameter:
HttpServletRequest httpReq = PortalUtil.getHttpServletRequest(request);
HttpServletRequest httpOrigReq = PortalUtil.getOriginalServletRequest(httpReq);
String myValue = httpOrigReq.getParameter("idProcessOrigin");
Any advice would be greatly appreciated!
The code you mention in your question should work, however, it's ignoring the peculiarities of a portlet environment. Typically, in a portlet, you'd rather "decorate" the names of parameters with <portlet:namespace/> (or whatever the equivalent in your UI library of choice is to this JSP tag). Instead of submitting a parameter "idProcessOrigin", you'd submit "<portlet:namespace/>idProcessOrigin" (of course, with properly replaced namespace, e.g. rather SOME_RANDOM_STUFF_idProcessOrigin)
If you don't want this, you can also declare the property com.liferay.portlet.requires-namespaced-parameters=<boolean> in your portlet-#Component's property list (as carried over from liferay-portlet.xml)
For the standard way of obtaining the parameters from a portlet request, you don't need to go through the HttpServletRequest at all - just use the PortletRequest's getParameter method. The result of this method depends, however, on properly decorated parameter names (or the deactivated option mentioned above). Note: When you call request.getParameter("idProcessOrigin"), you don't need the decoration any more, provided that request is a PortletRequest, not an HttpServletRequest.

Weird Behavior When Dealing With POST Request Parameters

I'm working on a RESTful API, using Apache CXF as my JAX-RS implementation. I have a POST endpoint that's supposed to receive a request with three parameters. Here's a snippet of my code (modified and shortened):
#Path("endpoint_path")
public class MyResource {
#Context
private HttpServletRequest request;
#POST
#Produces(MediaType.TEXT_HTML)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response postEndpoint(#QueryParam("param1") String param1,
#FormParam("param2") String param2,
#FormParam("param3") String param3) {
(use request as input for some library)
}
}
Inside that method, param2 and param3 both have the expected values, but if I check the request object's parameters (by using request.getParameterNames()), I only get one parameter -param1- instead of all three. I know for sure that I'm receiving all 3 parameters, param1 as a query parameter, and param2 and param3 as form parameters, because as I just said, I get their values passed as method parameters. They just don't seem to exists inside the request object.
This puzzled me so much, that I created a Filter that only does one thing, it peeks inside the request for the parameter names and does nothing else:
public class TestCXFPostParamsFilter implements Filter {
#Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
servletRequest.getParameterNames();
filterChain.doFilter(servletRequest, servletResponse);
}
(init() and destroy() empty methods)
}
and in my web.xml file, I set the filter to apply to every request to my endpoint. Now here's where things get weird - for some reason, that makes everything work, by which I mean, if I check the request object back in the endpoint method, it'll contain all three expected parameters. What sorcery is this?
As a side note, some of you may be wondering why would I bother to check the request object, when I just said I have access to the parameter values that are passed to the method by CXF's servlet? The answer is that I'm using a library that expects you to pass the request object to it, instead of just the necessary values. So I really need the request to keep its parameters inside (like I always assumed it would).
Finally, I'm using Java 6, and CXF 2.7.10 (which comes with Apache Camel CXF 2.13.0). And yes, those are more or less set in stone for all intents and purposes, so if the reason all of this is happening is because of a bug in one of these pieces, I'm stuck with an useless filter as a "solution".

How to implement state in command pattern

I am porting my Java servlet front controller from a large if-else if block to the command pattern and have created a command interface with an execute method. Currently, I am instantiating an instance of each command in the init() method of my servlet and storing them in a HashMap. I am wondering how I can run the necessary command.execute() within the context of a given request?
Do I add a setContext(HttpServletRequest request, HttpServletResponse response); method to the interface and call command.setContext(request, response) from my doGet()/doPost() methods before I execute or should I not be instantiating the commands in init() to begin with? instead, having a constructor that takes request and response as args?
Obviously, the aim of the command is to set various attributes for a given user/session and determine the correct JSP to forward to, which it can't really do without the context.
You should use:
command.execute(HttpServletRequest request, HttpServletResponse response);
All state can (and should) be recorded in the request. This is easy to do by storing attributes.
Sometimes you may need to use:
command.execute(this, HttpServletRequest request, HttpServletResponse response);
but probably only if your commands are enum rather than real objects.

Different "request" implicit objects in Liferay

What is the difference between fetching attributes from these implicit objects:
renderRequest.getAttribute("myVar")
actionRequest.getAttribute("myVar")
request.getAttribute("myVar")
Why are they all allowed?
I mean you usually store attribute in actionRequest or renderRequest object but you can get it in request implicit object, why?
What is the correct approach?
How is it possible to get an action object in view time?
Does not it violate the action-render renderParams passing mechanism?
Why are actionRequest/response available as implicit object if they throw NullPointerException when trying to use them in JSP?
Finally when is it useful to store an attribute in the request (PortalUtil.getOriginalServletRequest)?
What is the correct approach for accessing request attributes?
In portlets, the correct approach is to only interact with the renderRequest for retrieving parameter values and for getting or setting request attributes (in JSPs or the portlet class). renderResponse can be used to create new Portlet URLs.
Why can you get request attributes from the request object as well?
request is an HttpServletRequest and renderRequest is a PortletRequest. However, Liferay implemented request as a wrapper of HttpServletRequest in such way that, e.g. for accessing request attributes, it will fallback to the PortletRequest if it doesn't find the attribute in the actual HttpServletRequest.
What's the use of actionRequest and actionResponse at view time?
Like you say, if you follow the principles of MVC, you will only use the JSP for view logic. If you check the DefineObjectsTag from Liferay, you can see that all these xxxRequest and xxxResponse objects are only set if the portlet is in the right lifecycle. Because, normally, you're in the RENDER_PHASE when executing the JSP logic, only renderRequest and renderResponse will be not-null.
When is it useful to store an attribute in the request?
It doesn't really make sense to store attributes in the HttpServletRequest if you're working with portlets. On the other hand, inside a servlet (filter) you could add attributes that can then be retrieved from portlets by using request.getAttribute("xxx").

Adding parameters in jsp file

Is there any way to add parameters in a servlet or jsp? Because as far as I have searched, parameters can only be set in forms.
Why is there no command in java to add parameters manually?
Another doubt I have is that, when forwarding from one jsp page to other, is the input request(with the parameters, attributes etc) forwarded to the next jsp page?
What if I don't want certain parameters or attributes to be forwarded?
Is there any way to add parameters in a servlet or jsp?
-- Append it to the URL. If you are thinking of some hypothetical function such asrequest.setParameter, then there is no such method provided. Don't you think it would be a security breach then?
Request parameters can be passed by using <jsp: param>
This tag contains two attributes:
name
value.
eg:
<jsp: param name="myParam" value="Amar Patel"/>
This tag is used as a nested tag within <jsp:forward> or <jsp:include> blocks.
For example:
<jsp: forward page="ssParameters.jsp">
<jsp: param name="myParam" value="Amar Patel"/>
<jsp: param name="Age" value="15"/>
</jsp: forward>
Is there any way to add parameters in a servlet or jsp?
Yes. If it's possible to use the RequestDispatcher.forward(ServletRequest, ServletResponse) or RequestDispatcher.include(ServletRequest, ServletResponse) you can use the the HttpServletRequestWrapper to add or filter Request Parameters
// assuming this code is part of a Servlet or JSP
HttpServletRequest request = ...;
final Map<String,String> additionalParameters = ...;
RequestDispatcher dispatcher = this.getServletConfig().getServletContext().getRequestDispatcher("/");
dispatcher.forward(new HttpServletRequestWrapper(request){
public String getRequestParameter(String parameterName) {
if (additionalParameters.contains(parameterName)) {
return additionalParameters.get(parameterName);
} else {
if (!"filteredParameter".equals(parameterName)) {
return super.getParameterMap().get(parameterName());
} else {
return null;
}
}
}
}
, response);
If you only want to pass additional "parameters" to the forwarded/included page / servlet
it's recomended to use the ServletRequest.setAttribute(String, Object). ServletRequest Attributes may be added / removed during processing the request and allow to add complete java Objects rather than Strings when using Request Parameters.
Why is there no command in java to add parameters manually?
The ServletRequest Request Parameters should usually be treated as unmodifiable as it is Warpper of the Request sent from the Client to server. If you want to add Parameters use the Request Attributes.
Another doubt I have is that, when forwarding from one jsp page to
other, is the input request(with the parameters, attributes etc)
forwarded along to the next jsp page?
Most of the time the original HttpServletRequest is passed to the forwarded page / servlet. But as shown in my snipplet it's also possible to pass a different ServletRequest to the forwarded / included servlet / jsp.
What if I don't want certain parameters or attributes to be forwarded?
See code snippet above. You can filter the forwarded parameters or attributes using your own HttpServletRequestWrapper
You can pass your parameters by using it in your url. Regarding your questions about request. If you do forward to another jsp/servlet, all your parameters and attributes will be in the request. If you don't want to see it there, then you should use redirect instead (response.sendRedirect(url))

Categories