Getting Null in request.getAttribute(..) in Struts 2 - java

Setting Attribute
public class VoucherApproverListAction extends ActionSupport implements
SessionAware, ServletRequestAware, Preparable {
private HttpServletRequest servletRequest;
public HttpServletRequest getServletRequest() {
return servletRequest;
}
#Override
public void setServletRequest(HttpServletRequest servletRequest) {
this.servletRequest=servletRequest;
}
public void prepare() throws Exception {
servletRequest.setAttribute("id",tCaseVouchrDto.getId());
}
}
Getting Attribute
public class VoucherAction extends ActionSupport implements
SessionAware, ServletRequestAware, Preparable {
private HttpServletRequest servletRequest;
public HttpServletRequest getServletRequest() {
return servletRequest;
}
#Override
public void setServletRequest(HttpServletRequest servletRequest) {
this.servletRequest=servletRequest;
}
public void prepare() throws Exception {
String paramValue = (String)servletRequest.getAttribute("id");
logger.info("#-----Id===-----#" + paramValue);
}
}
From VoucherApproverListAction action class after success ,it is redirected to VoucherAction action class Getting null in paramValue

From VoucherApproverListAction action class after success ,it is
redirected to VoucherAction action class
This is the problem, request attributes are lost if you send redirect. You need to pass a parameter or save it in the session before the next request.

Related

Java: How to replace doPost, doGet in deprecated WebSocketServlet class

In older Java versions you could extend a class with WebSocketServlet, and because WebSocketServlet itself extended HttpServlet it was possible to add CRUD method, such as doGet(...), doPost(...) etc in the class.
However, now WebSocketServlet is deprecated and and using #ServerEndpoint with #OnOpen, #OnMessage, etc does not provide any "listen to doGet, doPost" messages. How can I migrate something like this?
public class Test extends WebSocketServlet
{
String something = "";
#Override
protected StreamInBound createWebSocketInbound(String string, HttpServletRequest hsr)
{
// DO STUFF
}
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException
{
this.something = "get";
}
}
Where do put doGet(...) and doPost(...)?
#ServerEndpoint(value = "/test")
public class Test {
#OnOpen
public void onOpen(Session session) {
// DO STUFF
}
#OnMessage
public String onMessage(String message, Session session) {
// DO STUFF
}
#OnClose
public void onClose(Session session, CloseReason closeReason) {
// DO STUFF
}
}
Also notice that I need to change a variable from the doGet(...) method that exist in the Test class.
Thanks!

cdi observe session scoped bean changed

i'm trying to observes a #SessionScoped component after change any property. HttpSessionAttributeListener not fire changes in cdi managed components.
#SuppressWarnings("serial")
#SessionScoped
public class TestSession implements Serializable {
private User user;
public TestSession() {
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
An example Servlet:
#SuppressWarnings("serial")
#WebServlet(name = "demo", urlPatterns = "/demo")
public class DemoServlet extends HttpServlet {
private static final Logger logger = LoggerFactory.getLogger(DemoServlet.class);
#Inject
private TestSession testSession;
#Override
protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
throws ServletException, IOException {
User user = new User(1L,new Role(1L));
user.setId(RandomUtils.nextLong());
testSession.setUser(user); //listen that component change something
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/WEB-INF/jsp/demo.jsp");
dispatcher.forward(httpServletRequest, httpServletResponse);
}
}
Is the a way to listen when component change any attribute ? Anyone has some approach to do that ?
Important : I dont have access to rewrite or add code on TestSession java class or servlet .
You can place an interceptor in the setUser() method that creates an event then catch it.

spring mvc: how to add custom annotion on parameters to controllers

This is my controller class:
#Component
#RequestMapping("/test")
public class MyController
{
#RequestMapping(value = {"test"}, method = RequestMethod.GET)
#ResponseBody
public String test(#MyAnnotation String myValue)
{
return "myValue:"+myValue;
}
}
Moreover, below is my interceptor class:
public class MyInterceptor implements HandlerInterceptor
{
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
{
MyAnnotation annotation = ((HandlerMethod)handler).getMethod().getAnnotation(MyAnnotation.class);
// TODO
}
#Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception
{
}
#Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) throws Exception
{
}
}
if I want myValue to be "test", then how to implement the custom annotation #MyAnnotation? what to do in class MyInterceptor

Accessing Resource class fields in PostProcessInterceptor?

I have a resource class as
#Path("secure")
#RequestScoped
// #SecurityChecked
public class SecureResource {
#Context
private HttpServletRequest request;
#GET
#SecurityChecked
public Response getUser() {
return Response.ok("authenticated successfully!").build();
}
#POST
public Response login(#FormParam("user") #Nonnull final String user,
#FormParam("password") #Nonnull final String password) {
final String authToken = TokenUtils.createToken(user);
return Response.ok().header(AUTH_TOKEN, authToken).build();
}
#PUT
public Response updateUser() {
return Response.ok("updating user").build();
}
}
and I have a PostProcessInterceptor where I would like to access the request of header class
#Interceptor
#Provider
#ServerInterceptor
#SecurityChecked
public class SecurityCheckInterceptor implements PostProcessInterceptor {
private static final Pattern PATTERN = Pattern.compile(":");
private static final Logger LOGGER = LoggerFactory.getLogger(SecurityCheckInterceptor.class);
#Override
public void postProcess(final ServerResponse response) {
// access the Resource class request object
}
}
I am not sure how can I access the request object here
Please help
Thank you
Why do you want to access request in PostProcessInterceptor? Are you sure you cant use
public static class MyInterceptor implements PreProcessInterceptor{
...
#Override
public ServerResponse preProcess(HttpRequest request, ResourceMethod method){...}
}
here?

RESTeasy InMemoryClient does not inject #Context UriInfo field into Spring #Transactional Bean

We have a problem with our tests that the field UriInfo is not correctly injected when the resource is wrapped in a TransactionalProxy.
We tried using the SpringResourceFactory but that did not help either.
I tried to extract the relevant classes for this usecase:
public class InMemoryClientFactory implements FactoryBean<InMemoryClientExecutor>{
#Inject
private SessionResource sessionResource;
#Override
public InMemoryClientExecutor getObject() throws Exception {
Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
Registry registry = dispatcher.getRegistry();
registry.addSingletonResource(sessionResource);
final InMemoryClientExecutor inMemoryClientExecutor = new InMemoryClientExecutor(dispatcher);
}
#Override
public Class getObjectType() {
return InMemoryClientExecutor.class;
}
#Override
public boolean isSingleton() {
return true;
}
}
#Path("session")
public interface SessionResource {
#GET
#Path("{sessionId}")
#Produces({MediaType.APPLICATION_XML})
Response get(#PathParam("sessionId") String sessionId);
#DELETE
#Path("{sessionId}")
Response delete(#PathParam("sessionId") String sessionId);
}
#Service
#Transactional
public class SessionResourceImpl implements SessionResource {
#Context
private UriInfo uriInfo;
#Override
public Response get(String sessionId) {
// uriInfo will be null here
String url = uriInfo.getBaseUriBuilder().path(SessionResource.class).path(SessionResource.class, "delete").build(sessionId)
.toString());
return Response.ok(session).build();
#Override
public Response delete(String sessionId) {
System.out.println("Deleted Session "+1);
}
}
#ContextConfiguration(locations = ["classpath:/META-INF/testContext.xml"])
#Transactional
#RunWith(SpringJUnit4ClassRunner.class)
public class SessionResourceIT {
#Inject
InMemoryRestClientFactory inMemoryClientFactory;
#Inject
SessionResource resource;
#Test
public void test() {
SessionResource resource = inMemoryClientFactory.createProxy(SessionResource.class);
ClientResponse cr = client.get(sessionId);
assertNotNull(cr.getEntity(String.class));
}
}
A possible workaround is to unwrap the transactional proxy for the tests, this works as long as the test itself is annotated with #Transactional. I hope someone has a better solution than this.
public class InMemoryClientFactory implements FactoryBean<InMemoryClientExecutor>{
#Inject
private SessionResource sessionResource;
#Override
public InMemoryClientExecutor getObject() throws Exception {
Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
Registry registry = dispatcher.getRegistry();
registry.addSingletonResource(unwrapProxy(sessionResource));
final InMemoryClientExecutor inMemoryClientExecutor = new InMemoryClientExecutor(dispatcher);
}
#Override
public Class getObjectType() {
return InMemoryClientExecutor.class;
}
#Override
public boolean isSingleton() {
return true;
}
private static Object unwrapProxy(Object bean) throws Exception {
Object result = bean;
/*
* If the given object is a proxy, set the return value as the object
* being proxied, otherwise return the given object.
*/
if (AopUtils.isAopProxy(bean) && bean instanceof Advised) {
Advised advised = (Advised) bean;
result = advised.getTargetSource().getTarget();
}
return result;
}
}

Categories